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 }