Question

Je sais ce que dup / dup2 fait, mais je aucune idée quand il serait utilisé.

Les exemples pratiques?

Merci.

Était-ce utile?

La solution

Un exemple utiliser serait redirection E / S. Pour cela, vous bifurquez un processus enfant et de fermer les descripteurs de fichiers stdin ou stdout (0 et 1), puis vous faites un dup () sur un autre FileDescriptor de votre choix qui va maintenant être mis en correspondance avec le plus bas descripteur de fichier disponible, ce qui est dans ce cas 0 ou 1.

En utilisant cela, vous pouvez maintenant exec tout processus enfant qui est peut-être pas au courant de votre demande et à chaque fois que l'enfant écrit sur le stdout (ou STDIN, tout ce que vous configuré) les données est écrite sur la condition FileDescriptor à la place.

Coquilles utiliser cette fonction pour mettre en oeuvre des commandes avec des tuyaux, par exemple /bin/ls | more en connectant la sortie standard d'un processus à l'entrée standard de l'autre.

Autres conseils

Le meilleur scénario pour comprendre dup et dup2 est redirection.
La première chose que nous devons savoir est que le système dispose de 3 ids de fichiers par défaut (ou variables indiquant les sources de sortie ou d'entrée) qui traite de l'entrée et de sortie. Ils sont stdin, stdout, stderr, en nombres entiers ils sont 0, 1, 2. La plupart des fonctions telles que fprintf ou cout sont directement sortie stdout.
Si nous voulons rediriger la sortie, d'une façon est de donner, par exemple, la fonction fprintf plus d'arguments indiquant in et out.
Cependant, il y a une façon plus élégante: on peut remplacer les ids de fichier par défaut pour les faire pointer vers le fichier que nous voulons recevoir la sortie. dup et dup2 fonctionne exactement dans cette situation.
Commençons par un exemple simple maintenant: supposons que nous voulons rediriger la sortie de fprintf vers un fichier txt nommé « chinaisbetter.txt ». Tout d'abord, nous devons ouvrir ce fichier

int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);

Ensuite, nous voulons stdout pour pointer sur "chinaisbetter.txt" en utilisant la fonction dup:

dup2(fw,1);

stdout (1) pointe vers le descripteur de « chinaisbetter.txt », même si elle est encore 1, mais la sortie est maintenant redirigé.
Ensuite, vous pouvez utiliser printf comme d'habitude, mais les résultats seront dans le fichier txt au lieu d'afficher directement sur l'écran:

printf("Are you kidding me? \n");

PS :

  1. Cela donne juste une explication intuitive, vous devrez peut-être vérifier la page de manuel ou des informations détaillées. En fait, nous disons "copie" ici, ils ne sont pas tout copier.

  2. L'identifiant de fichier se réfère ici au gestionnaire du fichier. Le descripteur de fichier mentionné ci-dessus est un struct de l'information du fichier des enregistrements.

Lorsque vous êtes curieux de connaître les fonctions POSIX, en particulier ceux qui semblent se reproduire, il est généralement bon de vérifier la norme elle-même . Au fond, vous habituellement voir des exemples, ainsi que le raisonnement derrière la mise en œuvre (et existence) des deux.

Dans ce cas:

Les sections suivantes sont informatives.

Exemples

Réorientation la sortie standard dans un fichier

L'exemple suivant ferme la sortie standard pour les processus actuels, réaffecte la sortie standard pour aller au fichier référencé par pfd et ferme le descripteur de fichier original à nettoyer.

#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...

Rediriger Messages d'erreur

L'exemple suivant redirige automatiquement les messages stderr à stdout.

#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...

Application Usage

Aucun.

Justification

Les fonctions de dup() et dup2() sont redondants. Leurs services sont également fournis par la fonction fcntl(). Ils ont été inclus dans ce volume de la norme IEEE Std 1003.1-2001 principalement pour des raisons historiques, car de nombreuses applications existantes les utiliser.

Alors que le bref segment de code affiché est très similaire dans le comportement à dup2(), une mise en œuvre conforme à base d'autres fonctions définies dans ce volume de la norme IEEE Std 1003.1-2001 est beaucoup plus complexe. Moins évident est l'effet possible d'une fonction de gestionnaire de signal qui pourrait être invoqué entre les étapes et allouer ou descripteurs de fichiers désaffecter. Cela pourrait être évité en bloquant les signaux.

La fonction dup2() n'est pas marqué obsolescent, car il présente une version de type sécurisé des fonctionnalités fournies dans une version de type dangereux par fcntl(). Il est utilisé dans l'Ada POSIX obligatoire.

La fonction dup2() n'a pas été conçu pour être utilisé dans des régions critiques comme un mécanisme de synchronisation.

Dans la description de [EBADF], le cas de Fildes étant hors de portée est couvert par le cas donné Fildes ne pas être valide. Les descriptions de fildes et fildes2 sont différents parce que le seul type d'invalidité qui est pertinente pour fildes2 est de savoir s'il est hors de portée; qui est, peu importe si fildes2 fait référence à un fichier ouvert lorsque l'appel est fait dup2().

Orientations futures

Aucun.

Voir aussi

close(), fcntl(), open(), le volume des définitions de base de la norme IEEE 1003,1 à 2001, <unistd.h>

Historique des modifications

D'abord publié dans le numéro 1. Dérivé du numéro 1 du SVID.

Un exemple pratique réoriente les messages de sortie à un autre flux comme un fichier journal. Voici un exemple de code pour la redirection d'E / S.
S'il vous plaît se référer à la publication dorigine

#include <stdio.h>

main()
{
    int    fd;
    fpos_t pos;

    printf("stdout, ");

    fflush(stdout);
    fgetpos(stdout, &pos);
    fd = dup(fileno(stdout));
    freopen("stdout.out", "w", stdout);

    f();

    fflush(stdout);
    dup2(fd, fileno(stdout));
    close(fd);
    clearerr(stdout);
    fsetpos(stdout, &pos);        /* for C9X */

    printf("stdout again\n");
}

f()
{
printf("stdout in f()");
}

redirection d'E / S dans la coquille serait très probablement mis en œuvre en utilisant les appels système dup2 / de fcnlt.

On peut facilement imiter le type de $program 2>&1 > logfile.log de redirection en utilisant la fonction dup2.

Le programme ci-dessous réoriente à la fois stdout et stderr .i.e émule le comportement de $program 2>&1 > output en utilisant le dup2.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int
main(void){
    int close_this_fd;
    dup2(close_this_fd = open("output", O_WRONLY), 1);
    dup2(1,2);
    close(close_this_fd);
    fprintf(stdout, "standard output\n");
    fprintf(stderr, "standard error\n");
    fflush(stdout);
    sleep(100); //sleep to examine the filedes in /proc/pid/fd level.
    return;
}

vagrant@precise64:/vagrant/advC$ ./a.out
^Z
[2]+  Stopped                 ./a.out
vagrant@precise64:/vagrant/advC$ cat output
standard error
standard output
vagrant@precise64:/vagrant/advC$ ll /proc/2761/fd
total 0
dr-x------ 2 vagrant vagrant  0 Jun 20 22:07 ./
dr-xr-xr-x 8 vagrant vagrant  0 Jun 20 22:07 ../
lrwx------ 1 vagrant vagrant 64 Jun 20 22:07 0 -> /dev/pts/0
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 1 -> /vagrant/advC/output
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 2 -> /vagrant/advC/output
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top