2010-08-04 17 views
8

Sto cercando di fare qualcosa di strano qui. Ho bisogno di avviare un processo, logcat, da un demone che verrà eseguito in background e stampare sul terminale senza prendere il controllo di stdin. È per la registrazione che idealmente logcat stamperà i messaggi di registro pur consentendo all'utente di immettere comandi standard e inizializzare i programmi dalla shell. Ecco il codice per il demone che ho finora. Il programma, logcat, avvia e mostra i messaggi di log ma non posso inserire alcun comando in stdin poiché sembra che il programma abbia preso il controllo di stdin.Avvia un processo in background in 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; 
} 

Grazie

risposta

4

Il comando 'logcat' sembra essere per lo sviluppo Android - che potrebbero spiegare la posizione strana del comando.

il funzionamento dei tasti che è necessario correggere è quello di garantire che si chiude la corrente di ingresso standard (il terminale) e aperto /dev/null/ per il dispositivo di input:

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

Ciò significa che il processo figlio daemonized non leggere qualsiasi cosa dal terminale.


Quello che penso si vuole fare è:

  1. eseguire il programma launcher da una riga di comando, che avrà lo standard input, lo standard output e lo standard error collegato al 'terminale'.
  2. All'interno del programma, si desidera sostituire l'input standard in modo che provenga da /dev/null.
  3. Si desidera lasciare solo l'output standard: si desidera che lo logcat scriva sullo standard output corrente.
  4. Probabilmente vorrete anche lasciare un errore standard.

Ad un certo punto della procedura, fate il vostro daemonization correttamente (prendendo in prestito il link da @ di bstpierre risposta), facendo in modo che il terminale si è collegati non è il vostro terminale di controllo, in modo che gli interrupt e hangups inviato a il terminale non ha alcun effetto sul demone. L'impianto idraulico è più semplice di quello che hai impostato: dovresti occuparti dello standard input e lasciare invariato l'output standard e l'errore standard (invece di cambiare le uscite e lasciare l'input invariato).

Ora è possibile che l'output passi a /dev/console; se è così, allora è ragionevole rivedere il codice per aprire /dev/console. Tuttavia, non è ragionevole ripiegare su /dev/null se non è possibile aprire /dev/console; il tuo programma dovrebbe riportare un errore e fallire (perché non ha senso scrivere logcat su /dev/null!). Assicurati di aprire la console con il flag O_NOCTTY in modo che non diventi il ​​terminale di controllo per il demone.

Il commento finale che vorrei fare è:

  • Sei sicuro di volere testo casuale che appare sopra il vostro terminale o console quando è in uso per altre cose?

Non mi piace molto quando ciò accade.


Consulta anche: SO 958249

+0

Grazie mille per la tua profonda risposta. Il problema era lo stdin come lei aveva menzionato. Ho dovuto reindirizzare da logcat a stdin, insieme ad altre cose come il demonizzare il processo. Questo mi ha risparmiato tanto stress e preoccupazione. Grazie ancora, lo apprezzo davvero. – Mike

4
+0

Questo ha contribuito a una tonnellata. Grazie. – Mike

+0

@ Mike - c'è un sacco di cose che puoi sbagliare ... Ho lasciato fuori bit prima e quell'articolo è un buon punto di partenza per ricordare tutti i pezzi. – bstpierre

+2

Il collegamento sembra essere morto. – Bharat

0

C'è speciale funzione purposed per questo in glibc:

#include <unistd.h> 

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

Maggiori dettagli qui http://linux.die.net/man/3/daemon

Problemi correlati