En este momento, tengo que iniciar un proceso externo en C. Actualmente estoy usando posix_spawn para crear el proceso. Es necesario que pueda monitorear si el proceso ha terminado o no. También necesito tener un enlace al estándar fuera del proceso. He analizado el uso de popen, sin embargo, no proporciona una forma "fácil" de obtener el pid. Me estoy volviendo loco lentamente, ya que no puede ser tan difícil obtener la salida estándar de un proceso en ejecución en Linux.
Además, en una nota adicional, necesito ayuda para descifrar lo que se supone que significa el parámetro file_actions. man(3) para posix_spawn sobre este tema dice:
Si file_actions no es NULL, entonces los descriptores de archivo abiertos en el proceso secundario serán los abiertos en el proceso de llamada modificados por el objeto de acciones de archivo de generación al que apunta file_actions y el indicador FD_CLOEXEC de cada descriptor de archivo abierto restante después de las acciones de archivo de generación han sido procesados.
Si esa no es la definición de una oración corrida, no tengo idea de qué es.
Como tiene el PID (devuelto por posix_spawn ) y está ejecutando Linux, encontrará la salida estándar del proceso en /proc/<pid>/fd/1 . Simplemente open (o fopen ) el archivo para leerlo.
Sin embargo, la forma estándar es usar un fork . Use pipe y dup2 para obtener un descriptor de archivo para leer la salida del niño, como en esta pregunta .
Puede usar posix_spawn para esto, sin tener que usar /proc/<pid>/fd/N , propenso a condiciones de carrera, específico de Linux. Puedes conservar todos los beneficios de posix_spawn.
Estabas en el camino correcto pensando en file_actions . A continuación, se muestra un ejemplo que imprime la salida estándar del niño en comillas triples al estilo de Python, así como el código de salida del niño, desde el proceso principal usando posix_spawn y file_actions.
Aquí hay un ejemplo de la salida de ejemplo.
child pid: 17468 child exit status: 0 child stdout: """Hello World! """Aquí está el ejemplo.
#define _DEFAULT_SOURCE #include <spawn.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> extern char **environ; static void dump_child_stdout(int filedes) { ssize_t num_read; char buf[1]; printf("child stdout:\n\"\"\""); for (;;) { num_read = read(filedes, buf, sizeof(buf)); if (num_read > 0) { printf("%c", buf[0]); } else { break; } } printf("\"\"\"\n"); } int main(int argc, char *argv[]) { int status; pid_t pid; int out[2]; posix_spawn_file_actions_t action; char *args[] = {"/bin/echo", "Hello World!", NULL }; posix_spawn_file_actions_init(&action); pipe(out); posix_spawn_file_actions_adddup2(&action, out[1], STDOUT_FILENO); posix_spawn_file_actions_addclose(&action, out[0]); status = posix_spawn(&pid, args[0], &action, NULL, args, environ); if (status == 0) { printf("child pid: %d\n", pid); if (waitpid(pid, &status, 0) < 0) { perror("waitpid"); } else { if (WIFEXITED(status)) { printf("child exit status: %d\n", WEXITSTATUS(status)); } else { printf("child died an unnatural death.\n"); } close(out[1]); dump_child_stdout(out[0]); } } else { fprintf(stderr, "posix_spawn: %s\n", strerror(status)); close(out[1]); } posix_spawn_file_actions_destroy(&action); return 0; }