Escribir en stdin y leer desde stdout (Progtwigción UNIX / LINUX / C)

Estaba trabajando en una tarea en la que un progtwig tomaba un descriptor de archivo como argumento (generalmente del padre en una llamada ejecutiva) y leía desde un archivo y escribía en un descriptor de archivo, y en mis pruebas, me di cuenta de que el progtwig funcionaría desde la línea de comandos y no dar un error si utilicé 0, 1 o 2 como el descriptor del archivo. Eso tenía sentido para mí, excepto que podía escribir en stdin y hacer que se mostrara en la pantalla.

¿Hay alguna explicación para esto? Siempre pensé que había algo de protección en stdin / stdout y ciertamente no se puede imprimir para stdin o fgets desde stdout.

#include  #include  #include  int main() { char message[20]; read(STDOUT_FILENO, message, 20); write(STDIN_FILENO, message, 20); return 0; } 

Intentar escribir en un archivo marcado como readonly o viceversa haría que write y read devolvieran -1, y fallara. En este caso específico , stdin y stdout son en realidad el mismo archivo. Básicamente, antes de que se ejecute el progtwig (si no se realiza ninguna redirección) el shell va:

  if(!fork()){  int fd = open("/dev/tty1", O_RDWR); dup(fd); dup(fd); execvp("name", argv); } 

Entonces, stdin, out y err son todos duplicados del mismo descriptor de archivo, abierto para leer y escribir.

 read(STDIN_FILENO, message, 20); write(STDOUT_FILENO, message, 20); 

Deberia trabajar. Nota: stdout ser un lugar diferente de stdin (incluso en la línea de comandos). Puede alimentar la salida de otro proceso como stdin en su proceso, o disponer que stdin / stdout sean archivos.

fprintf / fgets tiene un búfer, lo que reduce el número de llamadas al sistema.

Mejor suposición: stdin señala de dónde viene la entrada, su terminal y stdout apuntan a dónde debería ir la salida, su terminal. Como ambos apuntan al mismo lugar, ¿son intercambiables (en este caso)?

Si ejecuta un progtwig en UNIX

 myapp < input > output 

Puede abrir / proc / {pid} / fd / 1 y leer desde allí, abrir / proc / {pid} / fd / 0 y escribir en él y, por ejemplo, copiar la output en la input . (Posiblemente haya una manera más simple de hacer esto, pero sé que funciona)

Puedes hacer cualquier cosa que sea completamente confusa si te lo propones. 😉

Es muy posible que los descriptores de archivo 0, 1 y 2 estén abiertos tanto para lectura como para escritura (y de hecho, todos se refieren a la misma “descripción de archivo abierto” subyacente), en cuyo caso lo que está haciendo funcionará. Pero hasta donde yo sé, no hay garantía, por lo que también podría no funcionar. Creo que POSIX en algún lugar especifica que si stderr está conectado a la terminal cuando el shell invoca un progtwig, se supone que debe ser legible y escribible, pero no puedo encontrar la referencia correcta.

En general, recomendaría no leer nunca desde stdout o stderr a menos que esté buscando un terminal para leer una contraseña, y stdin ha sido redirigido (no es tty). Y recomendaría no escribir nunca en stdin: ¡es peligroso y podrías terminar peleando con un archivo en el que el usuario no esperaba que se lo escribiera!

Si desea escribir un mensaje en stdin, puede abrir el tty actual y llamar al sistema de escritura para escribir un mensaje en este archivo fd:

 string console_cmd = "hello"; string tty = ttyname(STDIN_FILENO); int fd = open(tty.c_str(), O_WRONLY); write(fd, console_cmd.c_str(), console_cmd.size()); 

Del mismo modo, lea de stdout.