web-dev-qa-db-fra.com

dup2 / dup - pourquoi aurais-je besoin de dupliquer un descripteur de fichier?

J'essaie de comprendre l'utilisation de dup2 et dup.

Depuis la page de manuel:

DESCRIPTION

dup and dup2 create a copy of the file descriptor oldfd.
After successful return of dup or dup2, the old and new descriptors may
be used interchangeably. They share locks, file position pointers and
flags; for example, if the file position is modified by using lseek on
one of the descriptors, the position is also changed for the other.

The two descriptors do not share the close-on-exec flag, however.

dup uses the lowest-numbered unused descriptor for the new descriptor.

dup2 makes newfd be the copy of oldfd, closing newfd first if necessary.  

RETURN VALUE

dup and dup2 return the new descriptor, or -1 if an error occurred 
(in which case, errno is set appropriately).  

Pourquoi aurais-je besoin de cet appel système? à quoi sert de dupliquer le descripteur de fichier?

Si j'ai le descripteur de fichier, pourquoi voudrais-je en faire une copie?

J'apprécierais si vous pouviez m'expliquer et me donner un exemple où dup2/dup est nécessaire.

Merci

74
JAN

L'appel système dup duplique un descripteur de fichier existant, renvoyant un nouveau qui fait référence au même objet d'E/S sous-jacent.

Dup permet aux shells d'implémenter des commandes comme celle-ci:

ls existing-file non-existing-file > tmp1  2>&1

Le 2> & 1 indique au Shell de donner à la commande un descripteur de fichier 2 qui est un doublon du descripteur 1. (c'est-à-dire que stderr et stdout pointent vers le même fd).
Maintenant, le message d'erreur pour appeler ls on fichier non existant et la sortie correcte de ls on existante fichier apparaître dans tmp1 fichier.

L'exemple de code suivant exécute le programme wc avec une entrée standard connectée à l'extrémité de lecture d'un tuyau.

int p[2];
char *argv[2];
argv[0] = "wc";
argv[1] = 0;
pipe(p);
if(fork() == 0) {
    close(STDIN); //CHILD CLOSING stdin
    dup(p[STDIN]); // copies the fd of read end of pipe into its fd i.e 0 (STDIN)
    close(p[STDIN]);
    close(p[STDOUT]);
    exec("/bin/wc", argv);
} else {
    write(p[STDOUT], "hello world\n", 12);
    close(p[STDIN]);
    close(p[STDOUT]);
}

L'enfant copie la fin de lecture sur le descripteur de fichier 0, ferme le fichier de scripteurs en p et exécute wc. Lorsque wc lit à partir de son entrée standard, il lit à partir du tuyau.
. Les outils ont été construits à tour de rôle en utilisant quelque chose d'autre, ainsi de suite.

À votre santé :)

39
Deepthought

Une autre raison de dupliquer un descripteur de fichier est de l'utiliser avec fdopen. fclose ferme le descripteur de fichier qui a été passé à fdopen, donc si vous ne voulez pas que le descripteur de fichier d'origine soit fermé, vous devez d'abord le dupliquer avec dup.

16
R..

Certains points liés à dup/dup2 peuvent être notés s'il vous plaît

dup/dup2 - Techniquement, le but est de partager une entrée de table de fichiers à l'intérieur d'un processus unique par différentes poignées. (Si nous bifurquons, le descripteur est dupliqué par défaut dans le processus enfant et l'entrée de la table de fichiers est également partagée).

Cela signifie que nous pouvons avoir plus d'un descripteur de fichier ayant peut-être des attributs différents pour une seule entrée de table de fichier ouverte en utilisant la fonction dup/dup2.

(Bien qu'il semble actuellement que seul l'indicateur FD_CLOEXEC soit le seul attribut pour un descripteur de fichier).

http://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html

dup(fd) is equivalent to fcntl(fd, F_DUPFD, 0);

dup2(fildes, fildes2); is equivalent to 

   close(fildes2);
   fcntl(fildes, F_DUPFD, fildes2);

Les différences sont (pour le dernier) - À part une valeur errno entre dup2 et fcntl close suivi de fcntl peut augmenter les conditions de concurrence car deux appels de fonction sont impliqués.

Les détails peuvent être vérifiés à partir de http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html

Un exemple d'utilisation -

Un exemple intéressant lors de l'implémentation du contrôle des tâches dans un shell, où l'utilisation de dup/dup2 peut être vue .. dans le lien ci-dessous

http://www.gnu.org/software/libc/manual/html_node/Launching-Jobs.html#Launching-Jobs

5

dup est utilisé pour pouvoir rediriger la sortie d'un processus.

Par exemple, si vous souhaitez enregistrer la sortie d'un processus, vous dupliquez la sortie (fd = 1), vous redirigez le fd dupliqué vers un fichier, puis forkez et exécutez le processus, et lorsque le processus se termine, vous redirigez à nouveau le fd enregistré à la sortie.

4
alinsoar