github.com/schwarzm/garden-linux@v0.0.0-20150507151835-33bca2147c47/old/linux_backend/src/wsh/util.c (about)

     1  #define _GNU_SOURCE
     2  
     3  #include <assert.h>
     4  #include <errno.h>
     5  #include <fcntl.h>
     6  #include <stdio.h>
     7  #include <stdlib.h>
     8  #include <string.h>
     9  #include <sys/param.h>
    10  #include <sys/socket.h>
    11  #include <sys/types.h>
    12  #include <sys/wait.h>
    13  #include <unistd.h>
    14  
    15  #include "util.h"
    16  
    17  void fcntl_set_cloexec(int fd, int on) {
    18    int rv;
    19    int fl;
    20  
    21    rv = fcntl(fd, F_GETFD);
    22    if (rv == -1) {
    23      perror("fcntl");
    24      abort();
    25    }
    26  
    27    fl = rv;
    28    if (on) {
    29      fl |= FD_CLOEXEC;
    30    } else {
    31      fl &= ~FD_CLOEXEC;
    32    }
    33  
    34    rv = fcntl(fd, F_SETFD, fl);
    35    if (rv == -1) {
    36      perror("fcntl");
    37      abort();
    38    }
    39  }
    40  
    41  void fcntl_set_nonblock(int fd, int on) {
    42    int rv;
    43    int fl;
    44  
    45    rv = fcntl(fd, F_GETFL);
    46    if (rv == -1) {
    47      perror("fcntl");
    48      abort();
    49    }
    50  
    51    fl = rv;
    52    if (on) {
    53      fl |= O_NONBLOCK;
    54    } else {
    55      fl &= ~O_NONBLOCK;
    56    }
    57  
    58    rv = fcntl(fd, F_SETFL, fl);
    59    if (rv == -1) {
    60      perror("fcntl");
    61      abort();
    62    }
    63  }
    64  
    65  int run_with_arg(const char *p1, const char *p2, const char *arg) {
    66    char path[MAXPATHLEN];
    67    int rv;
    68    char *argv[3];
    69    int status;
    70  
    71    rv = snprintf(path, sizeof(path), "%s/%s", p1, p2);
    72    assert(rv < sizeof(path));
    73  
    74    argv[0] = path;
    75    argv[1] = strdup(arg);
    76    argv[2] = NULL;
    77  
    78    rv = fork();
    79    if (rv == -1) {
    80      perror("fork");
    81      abort();
    82    }
    83  
    84    if (rv == 0) {
    85      execvp(argv[0], argv);
    86      perror("execvp");
    87      abort();
    88    } else {
    89      rv = waitpid(rv, &status, 0);
    90      if (rv == -1) {
    91        perror("waitpid");
    92        abort();
    93      }
    94  
    95      if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
    96        fprintf(stderr, "Process for \"%s\" exited with %d (%d)\n", path, WEXITSTATUS(status), status);
    97        return -1;
    98      }
    99    }
   100  
   101    return 0;
   102  }
   103  
   104  int run(const char *p1, const char *p2) {
   105    return run_with_arg(p1, p2, NULL);
   106  }
   107  
   108  int hook(const char *p1, const char *p2) {
   109    return run_with_arg(p1, "hook", p2);
   110  }
   111  
   112  void setproctitle(char **argv, const char *title) {
   113    char *last;
   114    int i;
   115    size_t len;
   116    char *p;
   117    size_t n;
   118  
   119    last = argv[0];
   120    i = 0;
   121  
   122    while (last == argv[i]) {
   123      last += strlen(argv[i++]) + 1;
   124    }
   125  
   126    len = last - argv[0];
   127    p = argv[0];
   128    n = strlen(title);
   129    assert(len > n);
   130  
   131    /* Assign argv termination sentinel */
   132    argv[1] = NULL;
   133  
   134    /* Copy title */
   135    strncpy(p, title, n);
   136    len -= n;
   137    p += n;
   138  
   139    /* Set remaining bytes to \0 */
   140    memset(p, '\0', len);
   141  }