2013-11-03 14 views
5

Nel manuale per GNU libc su orphaned process groups, è menzionato:perché segnale SIGHUP non ricevuto quando diventando un gruppo processo orfano

“process groups that continue running even after the session leader 
has terminated are marked as orphaned process groups. 

When a process group becomes an orphan, its processes are sent a SIGHUP 
signal. Ordinarily, this causes the processes to terminate. However, 
if a program ignores this signal or establishes a handler for it 
(see Signal Handling), it can continue running as in the orphan process 
group even after its controlling process terminates; but it still 
cannot access the terminal any more. ” 

scrivo un programma di test, ma quando il gruppo processo diventa un orfano, il suo processo non ha ricevuto il segnale SIGHUP. Mi chiedo perché?

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 


static void 
sig_hup(int signo) //**never get called ???** 
{ 
    printf("SIGHUP received, pid = %ld\n", (long)getpid()); 
} 

static void 
pr_ids(char *name) 
{ 
    printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n", 
     name, (long)getpid(), (long)getppid(), (long)getpgrp(), 
     (long)tcgetpgrp(STDIN_FILENO)); 
    fflush(stdout); 
} 

int 
main(void) 
{ 
    char c; 
    pid_t pid; 

    pr_ids("parent"); 
    pid = fork(); 
    if (pid > 0) {  // parent 
     sleep(5); 
     exit(0);   // parent exit; 
    } else { 
     pr_ids("child"); 
     setsid();  //create new session, and "child" becomes the session leader 
     pid = fork(); 
     if(pid>0) { 
      sleep(20); 
      exit(0);  // "child" exit 
         // so the process group become an orphan process group 
     } 
     else{ 
      pr_ids("grandson"); 
      signal(SIGHUP, sig_hup); // establish signal handler 
      sleep(60);     // now becoming orphan process group 
      printf("end\n"); 
     } 
    } 
    exit(0); 
} 

risposta

0

Tale sezione documento sta parlando specificamente per la perdita di un terminale di controllo di un processo che aveva uno-solitamente da una disconnettere il modem, o l'equivalente virtuale (che termina una sessione ssh, ecc). (Penso che il fraseggio nel documento possa essere migliorato qui). Quando si utilizza setsid() qui, si rinuncia all'accesso al terminale di controllo entro il tempo setsid() restituito, quindi non vi è alcun terminale di controllo da perdere da lì in avanti.

Si potrebbe open() un dispositivo TTY (come uno schiavo PTY) per ottenere un terminale di controllo (si noti che potrebbe essere necessario fare qualche operazione aggiuntiva oltre-FreeBSD richiede un ioctl TIOCSCTTY), poi perderlo di nuovo, e quindi si dovrebbe ricevere il segnale SIGHUP.

1

I gruppi di processi orfani ricevono SIGHUP seguito da SIGCONT se vengono interrotti quando diventano orfani.

sonno non è sufficiente, è necessario:

kill(getpid(), SIGSTOP); 

In aggiunta a ciò, POSIX non richiede che SIGHUP e SIGCONT essere inviati se il bambini orfani è stato causato da setsid() o setprgrp() perché allora non era causato da un processo in corso innocentemente inconsapevole del controllo dei lavori (vedere http://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html).

Tuttavia, con kill(getpid(), SIGSTOP) invece di quello sleep(60) nel bambino, si otterrà un orfano arrestato con il programma anche se non si chiama setsid().

#define _GNU_SOURCE 
#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <signal.h> 

static void 
sig_hup(int signo) //**never get called ???** 
{ 
    printf("SIGHUP received, pid = %ld\n", (long)getpid()); 
} 

static void 
pr_ids(char *name) 
{ 
    printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n", 
     name, (long)getpid(), (long)getppid(), (long)getpgrp(), 
     (long)tcgetpgrp(STDIN_FILENO)); 
    fflush(stdout); 
} 

int 
main(void) 
{ 
    pid_t pid; 

    pr_ids("parent"); 
    pid = fork(); 
    if (pid > 0) {  // parent 
     sleep(5); 
     _exit(0);   // parent exit; 
    } else { 
     pr_ids("child"); 

     /*setsid();  //create new session, and "child" becomes the session leader*/ 

     pid = fork(); 
     if(pid>0) { 
      sleep(2); 
      exit(0);  // "child" exit 
         // so the process group become an orphan process group 
     } 
     else{ 
      pr_ids("grandson"); 
      signal(SIGHUP, sig_hup); // establish signal handler 
      kill(getpid(), SIGSTOP); 
      printf("end\n"); 
     } 
    } 
    exit(0); 
} 

dovrebbe ottenere un SIGHUP nel bambino dopo il genitore muore (5s).

Problemi correlati