Admin/bash_process/bash_process.c
author wenzelm
Sat Feb 13 22:52:41 2016 +0100 (2016-02-13)
changeset 62300 f41884b9c4f1
parent 62293 72f6d6fd5853
child 62567 cb4e6ca06505
permissions -rw-r--r--
actually wait for forked process and return its status -- this is not meant to be a daemon;
wenzelm@47764
     1
/*  Author:     Makarius
wenzelm@47764
     2
wenzelm@62292
     3
Bash process with separate process group id.
wenzelm@47764
     4
*/
wenzelm@47764
     5
wenzelm@47764
     6
#include <stdlib.h>
wenzelm@47764
     7
#include <stdio.h>
wenzelm@62292
     8
#include <string.h>
wenzelm@47764
     9
#include <sys/types.h>
wenzelm@62300
    10
#include <sys/wait.h>
wenzelm@47764
    11
#include <unistd.h>
wenzelm@47764
    12
wenzelm@47764
    13
static void fail(const char *msg)
wenzelm@47764
    14
{
wenzelm@47798
    15
  fprintf(stderr, "%s\n", msg);
wenzelm@62292
    16
  fflush(stderr);
wenzelm@47764
    17
  exit(2);
wenzelm@47764
    18
}
wenzelm@47764
    19
wenzelm@47764
    20
wenzelm@47764
    21
int main(int argc, char *argv[])
wenzelm@47764
    22
{
wenzelm@47764
    23
  /* args */
wenzelm@47764
    24
wenzelm@62292
    25
  if (argc < 2) {
wenzelm@62292
    26
    fprintf(stderr, "Bad arguments: missing pid file\n");
wenzelm@62292
    27
    fflush(stderr);
wenzelm@47764
    28
    exit(1);
wenzelm@47764
    29
  }
wenzelm@47764
    30
  char *pid_name = argv[1];
wenzelm@47764
    31
wenzelm@47764
    32
wenzelm@47764
    33
  /* setsid */
wenzelm@47764
    34
wenzelm@50290
    35
  if (setsid() == -1) {
wenzelm@50290
    36
    pid_t pid = fork();
wenzelm@62300
    37
    int status;
wenzelm@62300
    38
wenzelm@50290
    39
    if (pid == -1) fail("Cannot set session id (failed to fork)");
wenzelm@62300
    40
    else if (pid != 0) {
wenzelm@62300
    41
      if (waitpid(pid, &status, 0) == -1) {
wenzelm@62300
    42
        fail("Cannot join forked process");
wenzelm@62300
    43
      }
wenzelm@62300
    44
wenzelm@62300
    45
      if (WIFEXITED(status)) {
wenzelm@62300
    46
        exit(WEXITSTATUS(status));
wenzelm@62300
    47
      }
wenzelm@62300
    48
      else if (WIFSIGNALED(status)) {
wenzelm@62300
    49
        exit(128 + WTERMSIG(status));
wenzelm@62300
    50
      }
wenzelm@62300
    51
      else {
wenzelm@62300
    52
        fail("Unknown status of forked process");
wenzelm@62300
    53
      }
wenzelm@62300
    54
    }
wenzelm@50290
    55
    else if (setsid() == -1) fail("Cannot set session id (after fork)");
wenzelm@50290
    56
  }
wenzelm@47764
    57
wenzelm@47764
    58
wenzelm@50292
    59
  /* report pid */
wenzelm@50292
    60
wenzelm@62292
    61
  if (strcmp(pid_name, "-") == 0) {
wenzelm@62292
    62
    fprintf(stdout, "%d\n", getpid());
wenzelm@62292
    63
    fflush(stdout);
wenzelm@62292
    64
  }
wenzelm@62292
    65
  else if (strlen(pid_name) > 0) {
wenzelm@62292
    66
    FILE *pid_file;
wenzelm@62292
    67
    pid_file = fopen(pid_name, "w");
wenzelm@62292
    68
    if (pid_file == NULL) fail("Cannot open pid file");
wenzelm@62292
    69
    fprintf(pid_file, "%d", getpid());
wenzelm@62292
    70
    fclose(pid_file);
wenzelm@62292
    71
  }
wenzelm@62292
    72
wenzelm@62292
    73
wenzelm@62292
    74
  /* shift command line */
wenzelm@62292
    75
wenzelm@62292
    76
  int i;
wenzelm@62292
    77
  for (i = 2; i < argc; i++) {
wenzelm@62292
    78
    argv[i - 2] = argv[i];
wenzelm@62292
    79
  }
wenzelm@62292
    80
  argv[argc - 2] = NULL;
wenzelm@62292
    81
  argv[argc - 1] = NULL;
wenzelm@50292
    82
wenzelm@50292
    83
wenzelm@47764
    84
  /* exec */
wenzelm@47764
    85
wenzelm@62292
    86
  execvp("bash", argv);
wenzelm@47796
    87
  fail("Cannot exec process");
wenzelm@47764
    88
}