2010-08-04 13 views
8

Estoy tratando de hacer algo un poco raro aquí. Necesito comenzar un proceso, logcat, desde un demonio que se ejecutará en segundo plano e imprimirá en la terminal sin tomar el control de stdin. Es para el registro, idealmente logcat imprimirá mensajes de registro mientras permite al usuario ingresar comandos estándar e inicializar programas desde el shell. Aquí está el código para el daemon que tengo hasta ahora. El programa, logcat, se inicia y muestra los mensajes de registro pero no puedo ingresar ningún comando en stdin ya que parece que el programa tomó el control de stdin.Inicie un proceso en segundo plano en Linux con C

int main (int argc, char** argv, char** env) 
{ 
    int fd; 
    if ((fd = open("/dev/console", O_RDWR)) < 0) { 
     fd = open("/dev/null", O_RDWR); 
    } 
    printf("THIS IS A TEST\n"); 
    dup2(1, fd); 
    dup2(2, fd); 

    pid_t childpid = fork(); 

    if(childpid == -1) { 
     perror("Failed to fork, logcat not starting"); 
     return 1; 
    } 

    if(childpid == 0) { 
     //this is the child, exec logcat 
     setsid(); 
     int execReturn = execl("/system/bin/logcat", "logcat", (char *) 0); 
    } else { 
     //this is the parent do nothing 
     close(fd); 
     return 0; 
    } 
    close(fd); 
    return 0; 
} 

Gracias

Respuesta

4

El comando 'logcat' parece ser para el desarrollo de Android - que podrían explicar la ubicación rara del comando.

La operación de tecla que debe corregir es asegurar que cierre su entrada de corriente estándar (el terminal) y abierto /dev/null/ para el dispositivo de entrada:

close(0); 
if ((fd = open("/dev/null", O_RDONLY)) != 0) 
    ...error - failed to open /dev/null! 

Esto significa que el proceso hijo endemoniada no va a leer cualquier cosa desde la terminal.


Lo que creo que quiere hacer es:

  1. ejecutar el programa de lanzamiento de una línea de comandos, que tendrá entrada estándar, salida estándar y el error estándar conectado a 'terminal'.
  2. Dentro de su programa, desea reemplazar la entrada estándar por lo que proviene de /dev/null.
  3. Desea dejar solo la salida estándar; desea logcat para escribir en la salida estándar actual.
  4. Probablemente también desee dejar solo el error estándar.

En algún momento del procedimiento, usted hace su daemonization correctamente (tomando prestado el enlace de la respuesta de @ bstpierre), asegurándose de que el terminal está conectado a no es su terminal de control, por lo que las interrupciones y desconexiones enviado a la terminal no afecta a tu daemon. La fontanería es más simple que la que ha configurado; debe tratar con la entrada estándar y dejar sin cambios la salida estándar y el error estándar (en lugar de cambiar las salidas y dejar la entrada sin cambios).

Ahora, es posible que desee que la salida vaya a /dev/console; si es así, entonces es razonable revisar el código para abrir /dev/console. Sin embargo, no es razonable recurrir al /dev/null si no puede abrir /dev/console; su programa debe informar un error y fallar (¡porque no tiene sentido tener logcat escribiendo en /dev/null!). Asegúrese de abrir la consola con el indicador O_NOCTTY para que no se convierta en la terminal de control del daemon.

El comentario final me gustaría hacer es:

  • ¿Seguro que deseas texto aleatorio que aparece sobre su terminal o consola cuando está en uso para otras cosas?

No me gusta mucho cuando eso sucede.


Consulte también: SO 958249

+0

Muchas gracias por su gran respuesta en profundidad. El problema fue el stdin como lo habías mencionado. Tuve que redireccionar de logcat a stdin, junto con algunas otras cosas como demonizar el proceso. Esto me ha ahorrado tanto estrés y preocupación. Gracias de nuevo, realmente lo aprecio. – Mike

4
+0

Esto ayudó un montón. Gracias. – Mike

+0

@Mike - hay muchas cosas que puedes cometer errores ... He omitido algunas partes antes y ese artículo es un buen punto de partida para recordar todas las piezas. – bstpierre

+2

El enlace parece estar muerto. – Bharat

0

Hay purposed función especial para esto en glibc:

#include <unistd.h> 

... 
/* We are in the parent, yet */ 
daemon(0,0); 
/* Now we are in the child */ 
... 

http://linux.die.net/man/3/daemon Más detalles aquí

Cuestiones relacionadas