Escribiendo en ambos stdout y un archivo

Tengo un proceso padre que obliga a un niño a realizar execv ().

Necesito que la salida dada por execv () a stdout se muestre en la pantalla y también se copie en un archivo de registro.

¿Cómo escribo la misma salida tanto en stdout como en un archivo, sin usar tuberías o tees ?

Si no desea utilizar una T, antes de escribir los datos, escríbalos en un archivo y luego envíelos a la salida estándar.

Debería escribir una función de registro que haga esto para que esté más limpio.

Conducirlo a través de la camiseta

Puedes usar dup2() – este enlace proporciona un ejemplo

Puede hacer esto completamente dentro de su progtwig, pero aún necesitará usar canalizaciones anónimas como lo creó la llamada al sistema pipe() .

Básicamente, necesitará un subproceso que realice el equivalente de tee , que es bastante fácil:

 int child_pipe[2]; pid_t pid_exec_child, pid_output_child; pipe(child_pipe); pid_exec_child = fork(); if (pid_exec_child == 0) { dup2(child_pipe[1], STDOUT_FILENO); close(child_pipe[0]); close(child_pipe[1]); execve(/* ... */); _exit(127); } close(child_pipe[1]); pid_output_child = fork(); if (pid_output_child == 0) { /* This child just loops around, reading from the other child and writing everything * to both stdout and the log file. */ int logfd = open("logfile", O_WRONLY); char buffer[4096]; ssize_t nread; while ((nread = read(child_pipe[0], buffer, sizeof buffer) != 0) { size_t nwritten_total; ssize_t nwritten; if (nread < 0) { if (errno == EINTR) continue; perror("read"); _exit(1); } /* Copy data to stdout */ nwritten_total = 0; while (nwritten_total < nread) { nwritten = write(STDOUT_FILENO, buffer + nwritten_total, nread - nwritten_total); if (nwritten < 0) { if (errno == EINTR) continue; perror("write(stdout)"); _exit(2); } nwritten_total += nwritten; } /* Copy data to logfile */ nwritten_total = 0; while (nwritten_total < nread) { nwritten = write(logfd, buffer + nwritten_total, nread - nwritten_total); if (nwritten < 0) { if (errno == EINTR) continue; perror("write(logfile)"); _exit(3); } nwritten_total += nwritten; } } _exit(0); } close(child_pipe[0]); /* Parent continues here */ 

Por supuesto, es probable que sea más fácil simplemente ejecutar la tee en ese segundo hijo ...

(Tenga en cuenta que los procesos secundarios utilizan _exit() , ya que han heredado el estado de E / S estándar del padre).

Además, puedes usar fifo’s. mkfifo my.fifo; en execv: progtwig> mi.fifo; y abre fifo como un archivo regular, leyendo de él. De esta manera, puede analizar su salida estándar, pero tiene inconvenientes menores con el acceso compartido.

¿Quieres que solo la salida del hijo vaya al registro?

El comando tee unix hace exactamente lo que usted describe: usted canaliza los datos y los escribe en un registro y en la salida estándar.

Usa una camiseta como esta:

 ./myprog | tee outputfile