
ENE
Estoy tratando de entender el uso de dup2
y dup
.
De la página del manual:
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).
¿Por qué necesitaría esa llamada al sistema? ¿De qué sirve duplicar el descriptor del archivo?
Si tengo el descriptor de archivo, ¿por qué querría hacer una copia de él?
Agradecería si pudieras explicarme y darme un ejemplo donde dup2
/ dup
se necesita
Gracias

Pensamiento profundo
La llamada al sistema dup duplica un descriptor de archivo existente y devuelve uno nuevo que hace referencia al mismo objeto de E/S subyacente.
Dup permite que los shells implementen comandos como este:
ls existing-file non-existing-file > tmp1 2>&1
El 2>&1 le dice al shell que le dé al comando un descriptor de archivo 2 que es un duplicado del descriptor 1. (es decir, stderr y stdout apuntan al mismo fd).
Ahora el mensaje de error para llamar ls en archivo inexistente y la salida correcta de ls en archivo existente aparecer en tmp1 expediente.
El siguiente código de ejemplo ejecuta el programa wc con una entrada estándar conectada al extremo de lectura de una tubería.
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]);
}
El niño duplica el final de lectura en el descriptor de archivo 0, cierra los descriptores de archivo en p y ejecuta wc. Cuando wc lee desde su entrada estándar, lee desde la tubería.
Así es como se implementan las tuberías usando dup, bueno, un uso de dup ahora usa tubería para construir otra cosa, esa es la belleza de las llamadas al sistema, construyes una cosa tras otra usando herramientas que ya están ahí, estas herramientas fueron construidas a su vez usando algo más, etc. Al final, las llamadas al sistema son las herramientas más básicas que obtienes en el kernel
Salud 🙂
Otra razón para duplicar un descriptor de archivo es usarlo con fdopen
. fclose
cierra el descriptor de archivo que se pasó a fdopen
por lo que si no desea que se cierre el descriptor de archivo original, debe duplicarlo con dup
primero.
dup se utiliza para poder redirigir la salida de un proceso.
Por ejemplo, si desea guardar el resultado de un proceso, duplica el resultado (fd=1), redirige el fd duplicado a un archivo, luego bifurca y ejecuta el proceso, y cuando finaliza, redirige nuevamente el fd guardado en la salida.
Se pueden observar algunos puntos relacionados con dup/dup2, por favor
dup/dup2: técnicamente, el propósito es compartir una entrada de la tabla de archivos dentro de un proceso único por diferentes mangos. (Si estamos bifurcando, el descriptor se duplica de forma predeterminada en el proceso secundario y la entrada de la tabla de archivos también se comparte).
Eso significa que podemos tener más de un descriptor de archivo que tenga atributos posiblemente diferentes para una sola entrada de tabla de archivos abiertos usando la función dup/dup2.
(Aunque parece que actualmente solo el indicador FD_CLOEXEC es el único atributo para un descriptor de archivo).
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);
Las diferencias son (por último)- Aparte de algún valor errno entre dup2 y fcntl close seguido de fcntl puede generar condiciones de carrera ya que están involucradas dos llamadas de función.
Los detalles se pueden consultar desde
http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
Un ejemplo de uso –
Un ejemplo interesante al implementar el control de trabajos en un shell, donde se puede ver el uso de dup/dup2… en el siguiente enlace
http://www.gnu.org/software/libc/manual/html_node/Launching-Jobs.html#Launching-Jobs
¿Cómo implementaría la funcionalidad de canalización de las conchas sin
dup
odup2
? tienes que llamarpipe(2)
y luego tener uno de los descriptores de archivodup
-ed a, por ejemploSTDIN_FILENO
– Basile Starynkevitch
24 de julio de 2012 a las 23:52
Posible duplicado de ejemplos prácticos use dup o dup2
– DraTyrsa
20 de enero de 2017 a las 10:27