usar seguidores pueden poner permite para mejores hashtags cuantos crear conseguir como c unix portability freebsd pty

pueden - hashtag instagram para conseguir seguidores



La salida final en esclavo pty se pierde si no se cerró en el padre. ¿Por qué? (5)

Creo que hay un comportamiento separado único para el Pty.

  1. El sistema finaliza si se escriben los últimos datos
  2. El sistema termina si el niño sale (¿tubo roto?)

El código se basa en el conducto existente el tiempo suficiente para enviar los datos, pero el niño que sale puede causar que el canal virtual se elimine antes de que se reciban los datos.

Esto sería exclusivo de Pty, y no existiría para terminal real.

Escribí y rlwrap un programa rlwrap que usa un pseudo-terminal para comunicarse con un proceso secundario. Pseudo-terminals (ptys) se encuentran en todos los sistemas Unix (-like), pero se comportan de forma ligeramente diferente en diferentes plataformas.

Caso en cuestión: en rlwrap , el proceso principal mantiene abierta la esclava del esclavo para controlar las configuraciones de terminal del niño (en Linux y FreeBSD se puede usar el maestro para eso, pero no en Solaris, por ejemplo)

En FreeBSD (8.2) (pero no en Linux) esto lleva a la pérdida del resultado final del niño. Por ejemplo:

#include <stdio.h> /* save as test.c and compile with gcc -o test test.c -lutil */ #define BUFSIZE 255 int main(void) { int master, slave; char buf[BUFSIZE]; int nread; openpty(&master, &slave, NULL, NULL, NULL); if (fork()) { /* parent: */ close(slave); /* leave this out and lose slave''s final words ... WHY? */ do { nread = read(master, buf, BUFSIZE); write(STDOUT_FILENO, buf, nread); /* echo child''s output to stdout */ } while (nread > 0); } else { /* child: */ login_tty(slave); /* this makes child a session leader and slave a controlling */ /* terminal for it, then dup()s std{in,out,err} to slave */ printf("Feeling OK :-)/n"); sleep(1); printf("Feeling unwell ... Arghhh!/n"); /* this line may get lost */ } return 0; }

El proceso principal hará eco de la salida del hijo, como se esperaba, pero cuando omito el close(slave) (manteniéndolo abierto como en rlwrap ):

  • en FreeBSD, el padre no ve la línea de salida final, sino que lee un EOF. (En todo caso, hubiera esperado lo contrario: que mantener el esclavo abierto evitaría que se perdiera la salida)
  • En Linux, por otro lado, nunca se ve un EOF, ni siquiera después de que el niño ha muerto (ya sea que cierremos el esclavo o no)

¿Este comportamiento está documentado en alguna parte? ¿Hay alguna razón para esto? ¿Puedo eludirlo sin cerrar el esclavo en el proceso principal?

Descubrí que no convertir el esclavo en un terminal de control - reemplazando la llamada login_tty con algunas simples llamadas dup() - resolverá el problema. rlwrap embargo, esta no es una solución para la rlwrap : bastantes comandos necesitan un terminal de control ( /dev/tty ) para comunicarse, por lo que rlwrap debe proporcionar uno para ellos.


En FreeBSD 10-STABLE obtengo ambas líneas de salida.

(Puede reemplazar openpty y fork con forkpty que básicamente también se encarga de login_tty ).

En FreeBSD 8.0, el antiguo controlador pty(4) fue reemplazado por pts(4) . La nueva pty(4) comporta de manera diferente a la anterior. Del manual;

A diferencia de las implementaciones anteriores, los nodos del dispositivo maestro y esclavo se destruyen cuando el PTY no se utiliza. Una llamada a stat (2) en un dispositivo maestro inexistente ya causará que se cree un nuevo nodo de dispositivo maestro. El dispositivo maestro solo se puede destruir abriendo y cerrando.

Podría haber habido cambios significativos entre 8.0-RELEASE y 10.0-RELEASE

También es posible que desee ver el patch que se aplica en el árbol de puertos de FreeBSD.


Esto es lo que encontré en Ubuntu Linux. Nota: siempre revise si hay errores.

#include <stdio.h> #include <stdlib.h> #include <pty.h> // openpty(), #include <utmp.h> // login_tty() #include <unistd.h> // read(), write() /* save as test.c and compile with gcc -o test test.c -lutil */ #define BUFSIZE (255) int main(void) { int master, slave; char buf[BUFSIZE]; int nread; pid_t pid; if( -1 == openpty(&master, &slave, NULL, NULL, NULL) ) { // then openpty failed perror( "openpty failed" ); exit( EXIT_FAILURE ); } // implied else, openpty successful pid = fork(); if( -1 == pid ) { // then fork failed perror( "fork failed" ); exit( EXIT_FAILURE ); } // implied else, fork successful if( pid ) { /* parent: */ close(slave); /* leave this out and lose slave''s final words ... WHY? */ do { if( -1 == (nread = read(master, buf, BUFSIZE) ) ) {// then, error occurred perror( "read failed" ); exit( EXIT_FAILURE ); } // implied else, read successful if ( nread ) { write(STDOUT_FILENO, buf, nread); /* echo child''s output to stdout */ } } while (nread); /* nread == 0 indicates EOF */ } else // pid == 0 { /* child: */ if( -1 == login_tty(slave) ) /* this makes child a session leader and slave a controlling */ /* terminal for it, then dup()s std{in,out,err} to slave */ { // then login_tty failed perror( "login_tty failed" ); exit( EXIT_FAILURE ); } // implied else, login_tty successful printf("Feeling OK :-)/n"); sleep(1); printf("Feeling unwell ... Arghhh!/n"); /* this line may get lost */ } // end if return 0; } // end function: main

cuando la instrucción close () está comentada, el padre nunca sale debido al bloqueo de la sentencia read ()

cuando la instrucción close () es parte de la fuente, el padre sale con un error de lectura al intentar leer desde una terminal que ''falta'' cuando el niño sale

aquí está la salida cuando close () comentó

Feeling OK :-) Feeling unwell ... Arghhh! then the parent hangs on the read() statement

aquí está la salida cuando close () no está comentada

Feeling OK :-) Feeling unwell ... Arghhh! read failed: Input/output error


No estoy seguro de si lo hago bien: independientemente de pty o no, siempre que un proceso tenga el canal abierto, el sistema operativo no debe pasar un EOF al lector (porque todavía hay un escritor). (después de la horquilla hay dos canales abiertos) solo si cierra el elemento primario, un cierre en el esclavo debe reenviar el EOF.

En un PTY, ¿está seguro de que las NL se manejan correctamente, ya que normalmente una CR debería activar la nueva línea?

(solo un pensamiento: si se trata de un tty de control, las cosas podrían cambiar ya que el sistema operativo maneja las entregas individuales de manera diferente y cerrar el canal normalmente terminaría todos los procesos secundarios del niño. ¿Podría ser un problema si el padre todavía tiene el mango abierto? )


printf realiza una salida en búfer según la clase de dispositivo de salida. Intenta poner fflush (stdout); después de la última impresión para ver si es un problema con la salida en búfer.