c pipe dup2 dup

¿Puede alguien explicar qué hace dup() en C?



pipe dup2 (8)

Ejemplo:

close(1); //closing stdout newfd=dup(1); //newfd takes value of least available fd number

Donde esto sucede con los descriptores de archivo:

0 stdin .--------------. 0 stdin .--------------. 0 stdin 1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd 2 stderr ''--------------'' ''--------------'' 2 stderr

Nuevamente surgió una pregunta: ¿Cómo puedo dup() un descriptor de archivo que ya cerré?

Dudo que haya llevado a cabo el experimento anterior con el resultado mostrado, porque eso no sería conforme con el estándar - cf. dup

La función dup () fallará si:

[EBADF]
El argumento fildes no es un descriptor de archivo abierto válido.

Entonces, después de la secuencia de códigos mostrada, newfd debe ser 1 , sino -1 , y errno EBADF .

Sé que dup, dup2, dup3 " crea una copia del descriptor de archivo oldfd " (de las páginas man). Sin embargo no puedo digerirlo.

Como sé, los descriptores de archivos son solo números para realizar un seguimiento de las ubicaciones de los archivos y su dirección (entrada / salida). ¿No sería más fácil simplemente

fd=fd2;

¿Cuándo queremos duplicar un descriptor de archivo?

Y algo más..

dup () utiliza el descriptor no utilizado con el número más bajo para el nuevo descriptor.

¿Significa eso que también puede tomar como valor stdin , stdout o stderr si asumimos que tenemos uno de esos cerca ?


Digamos que está escribiendo un programa shell y desea redireccionar la entrada estándar y la salida estándar en un programa que desea ejecutar. Podría verse algo como esto:

fdin = open(infile, O_RDONLY); fdout = open(outfile, O_WRONLY); // Check for errors, send messages to stdout. ... int pid = fork(0); if(pid == 0) { close(0); dup(fdin); close(fdin); close(1); dup(fdout); close(fdout); execvp(program, argv); } // Parent process cleans up, maybe waits for child. ...

dup2 () es una forma un poco más conveniente de hacerlo. El close () dup () se puede reemplazar por:

dup2(fdin, 0); dup2(fdout, 1);

La razón por la que desea hacer esto es que desea informar los errores a stdout (o stderr) para que no pueda simplemente cerrarlos y abrir un nuevo archivo en el proceso secundario. En segundo lugar, sería un desperdicio hacer la bifurcación si alguna de las llamadas open () devolviera un error.


Llamadas al sistema dup () y dup2 ().

• La llamada al sistema dup () duplica un descriptor de archivo abierto y devuelve el nuevo descriptor de archivo.

• El nuevo descriptor de archivo tiene las siguientes propiedades en común con el descriptor de archivo original: 1. se refiere al mismo archivo o canal abierto. 2. tiene el mismo puntero de archivo, es decir, ambos descriptores de archivo comparten un puntero de archivo. 3. tiene el mismo modo de acceso, ya sea leer, escribir o leer y escribir.

• se garantiza que dup () devuelve un descriptor de archivo con el valor entero más bajo disponible. Es debido a esta característica de devolver el descriptor de archivo no utilizado más bajo disponible que procesa la redirección de E / S.

int dup (file_descriptor)

int dup2 (file_descriptor1, file_descriptor2)


Lo más importante de dup () es que devuelve el entero más pequeño disponible para un nuevo descriptor de archivo. Esa es la base de la redirección:

int fd_redirect_to = open("file", O_CREAT); close(1); /* stdout */ int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */ close(fd_redirect_to); /* we don''t need this */

Después de esto, cualquier cosa escrita en el descriptor de archivo 1 (stdout), mágicamente entra en "archivo".


Sólo un consejo sobre " duplicar la salida estándar ".

En algunos sistemas Unix (pero no en GNU / Linux)

fd = open("/dev/fd/1", O_WRONLY);

es equivalente a:

fd = dup(1);


Solo quería responderme a mí mismo en la segunda pregunta después de experimentar un poco.

La respuesta es . Un descriptor de archivo que realice puede tomar un valor 0, 1, 2 si stdin, stdout o stderr están cerrados.

Ejemplo:

close(1); //closing stdout newfd=dup(1); //newfd takes value of least available fd number

Donde esto sucede con los descriptores de archivo:

0 stdin .--------------. 0 stdin .--------------. 0 stdin 1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd 2 stderr ''--------------'' ''--------------'' 2 stderr


Un descriptor de archivo es un poco más que un número. También lleva varios estados semi-ocultos con él (ya sea abierto o no, a qué descripción del archivo se refiere, y también algunas banderas). dup duplica esta información, por lo que, por ejemplo, puede cerrar los dos descriptores de forma independiente. fd=fd2 no lo hace.


ver esta página , stdout puede ser alias como dup(1) ...