2010-08-04 3 views
8

J'essaie de faire quelque chose d'un peu bizarre ici. Je dois lancer un processus, logcat, à partir d'un démon qui fonctionnera en arrière-plan et imprimer sur le terminal sans prendre le contrôle de stdin. C'est pour la journalisation idéalement alors logcat imprimera des messages de journal tout en permettant à l'utilisateur d'entrer des commandes standard et d'initialiser des programmes à partir du shell. Voici le code pour le démon que j'ai jusqu'ici. Le programme, logcat, démarre et affiche les messages du journal, mais je ne peux pas entrer de commandes dans stdin car il semble que le programme ait pris le contrôle de stdin.Démarrer un processus en arrière-plan sous Linux avec 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; 
} 

Merci

Répondre

4

La commande 'logcat' semble être pour le développement Android - qui pourraient expliquer l'emplacement étrange de la commande.

L'opération clé que vous devez fixer est d'assurer que vous fermez votre entrée standard actuel (le terminal) et ouvert /dev/null/ pour le dispositif d'entrée:

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

Cela signifie que votre processus enfant daemon ne lit pas rien du terminal.


Ce que je pense que vous voulez faire est:

  1. exécuter votre programme de lancement d'une ligne de commande, ce qui aura l'entrée standard, la sortie standard et l'erreur standard connecté à la borne.
  2. À l'intérieur de votre programme, vous voulez remplacer l'entrée standard de sorte qu'elle provienne de /dev/null.
  3. Vous voulez laisser la sortie standard seule - vous voulez que logcat écrive sur la sortie standard actuelle.
  4. Vous voulez probablement laisser l'erreur standard aussi.

À un certain moment dans la procédure, vous faites votre daemonization correctement (emprunter le lien de @ bstpierre de réponse), en vous assurant que le terminal que vous êtes connecté à n'est pas votre terminal de contrôle, de sorte que les interruptions et déconnexions envoyées à le terminal n'affecte pas votre démon. La plomberie est plus simple que ce que vous avez configuré - vous devez traiter l'entrée standard et laisser la sortie standard et l'erreur standard inchangées (au lieu de changer les sorties et de laisser l'entrée inchangée).

Maintenant, vous pourriez vouloir que la sortie passe à /dev/console; si c'est le cas, il est alors raisonnable de réviser le code pour ouvrir /dev/console. Cependant, il n'est pas raisonnable de se rabattre sur /dev/null si vous ne pouvez pas ouvrir /dev/console; votre programme doit signaler une erreur et échouer (car il est inutile d'écrire logcat à /dev/null!). Assurez-vous d'ouvrir la console avec l'indicateur O_NOCTTY afin qu'il ne devienne pas le terminal de contrôle du démon.

Le dernier commentaire que je ferais est:

  • Etes-vous sûr que vous voulez que le texte aléatoire apparaissant sur votre terminal ou la console quand il est utilisé pour d'autres choses?

Je n'aime pas beaucoup ça quand ça arrive.


Voir aussi: SO 958249

+0

Merci beaucoup pour votre excellente réponse en profondeur. Le problème était le stdin comme vous l'avez mentionné. J'ai dû rediriger de logcat à stdin, avec d'autres choses comme démoniser le processus. Cela m'a sauvé tellement de stress et d'inquiétude. Merci encore, je l'apprécie vraiment. – Mike

4
+0

une tonne Cela a aidé. Je vous remercie. – Mike

+0

@Mike - il y a beaucoup de choses que vous pouvez vous tromper ... J'ai laissé de côté des morceaux avant et cet article est un bon point de départ pour se souvenir de toutes les pièces. – bstpierre

+2

Le lien semble être mort. – Bharat

0

Il est fonction spéciale proposée pour ce glibc:

#include <unistd.h> 

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

Plus de détails ici http://linux.die.net/man/3/daemon

Questions connexes