0

I'm trying to write a program that executes a child command, and does not allow that child to be killed by Ctrl+C.

I've read that I can accomplish this with setpgid/setpgrp.

The following code works on OSX, but on Linux (2.6.32, Ubuntu 10.04) running something like,

./a.out ls

causes no output to occur and the program cannot be killed with SIGINT.

#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

int main(int argc, char **argv) {
    if (argc < 2) {
        printf("Please provide a command\n");
        exit(1);
    }

    int child_pid = vfork();

    if (child_pid == 0) {
        if (setpgrp() == -1) {
            perror("setpgrp error");
            exit(1);
        }

        printf("Now executing the command:\n");

        argv++;
        if (execvp(argv[0], argv) == -1) {
            perror("Could not execute the command");
            exit(1);
        }
    }

    int child_status;
    wait(&child_status);
}

If you comment out the call to setpgrp, you will see that the remaining code is functional.

OregonTrail
  • 8,594
  • 7
  • 43
  • 58

1 Answers1

1

I had to modify this section of the code for it to work on both platforms. I guess this is simply a difference between how the kernels treat sessions and process groups.

if (setsid() == -1) {
   #ifdef LINUX
   perror("setsid error");
   exit(1);
   #else
   if (setpgrp() == -1) {
       perror("setpgrp error");
       exit(1);
   }   
   #endif
}   
OregonTrail
  • 8,594
  • 7
  • 43
  • 58
  • **Just an FYI** `setsid()` succeeds on OS X without root in a child process after full `fork`. Basically `vfork` copies some stuff, but the process environment structure is shared between the two (almost like a hybrid between a process and a thread)... it's meant to be faster for fork/exec spawning where copying the environment is wasted effort. (Why yes, we did implement `vfork` in MINUX 2 in university, thanks for asking.;)) –  Apr 14 '16 at 01:00