util.c (2967B)
1 #include "util.h" 2 3 #include <errno.h> 4 #include <fcntl.h> 5 #include <limits.h> 6 #include <signal.h> 7 #include <stdarg.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <sys/stat.h> 12 #include <unistd.h> 13 14 15 ssize_t dgetline(int fd, char* line, size_t line_buffer) { 16 ssize_t line_size = 0; 17 ssize_t rc; 18 char c; 19 20 while (line_size < (ssize_t) line_buffer - 1 && (rc = read(fd, &c, 1)) == 1) { 21 if (c == '\r') 22 continue; 23 if (c == '\n') 24 break; 25 line[line_size++] = c; 26 } 27 line[line_size] = '\0'; 28 if (rc == -1 && line_size == 0) 29 return -1; 30 return line_size; 31 } 32 33 ssize_t readstr(int fd, char* str) { 34 ssize_t len = 0; 35 int rc; 36 37 while ((rc = read(fd, &str[len], 1)) == 1 && str[len] != '\0') 38 len++; 39 40 str[len] = '\0'; 41 return rc == -1 ? -1 : len; 42 } 43 44 ssize_t writestr(int fd, const char* str) { 45 if (str == NULL) 46 return write(fd, "", 1); 47 return write(fd, str, strlen(str) + 1); 48 } 49 50 unsigned int stat_mode(const char* format, ...) { 51 char path[PATH_MAX]; 52 struct stat st; 53 va_list args; 54 55 va_start(args, format); 56 vsnprintf(path, PATH_MAX, format, args); 57 va_end(args); 58 59 if (stat(path, &st) == 0) 60 return st.st_mode; 61 62 return -1; 63 } 64 65 int fork_dup_cd_exec(int dir, const char* path, int fd0, int fd1, int fd2) { 66 pid_t pid; 67 68 if ((pid = fork()) == -1) { 69 fprint(1, "error: cannot fork process: %r\n"); 70 return -1; 71 } else if (pid == 0) { 72 dup2(fd0, STDIN_FILENO); 73 dup2(fd1, STDOUT_FILENO); 74 dup2(fd2, STDERR_FILENO); 75 76 fchdir(dir); 77 78 execl(path, path, NULL); 79 fprint(1, "error: cannot execute stop process: %r\n"); 80 _exit(1); 81 } 82 return pid; 83 } 84 85 int reclaim_console(void) { 86 int ttyfd; 87 88 if ((ttyfd = open("/dev/console", O_RDWR)) == -1) 89 return -1; 90 91 dup2(ttyfd, 0); 92 dup2(ttyfd, 1); 93 dup2(ttyfd, 2); 94 if (ttyfd > 2) 95 close(ttyfd); 96 97 return 0; 98 } 99 100 void sigblock_all(int unblock) { 101 sigset_t ss; 102 103 sigemptyset(&ss); 104 sigaddset(&ss, SIGALRM); 105 sigaddset(&ss, SIGCHLD); 106 sigaddset(&ss, SIGCONT); 107 sigaddset(&ss, SIGHUP); 108 sigaddset(&ss, SIGINT); 109 sigaddset(&ss, SIGPIPE); 110 sigaddset(&ss, SIGTERM); 111 112 sigprocmask(unblock, &ss, NULL); 113 } 114 115 116 long parse_long(const char* str, const char* name) { 117 char* end; 118 long l = strtol(str, &end, 10); 119 120 if (*end != '\0') { 121 fprint(1, "error: invalid %s '%s'\n", name, optarg); 122 exit(1); 123 } 124 return l; 125 } 126 127 char* progname(char* path) { 128 char* match; 129 130 for (;;) { 131 if ((match = strrchr(path, '/')) == NULL) 132 return path; 133 134 if (match[1] != '\0') 135 return match + 1; 136 137 *match = '\0'; 138 } 139 return path; 140 } 141 142 int fd_set_flag(int fd, int flags) { 143 int rc; 144 145 if ((rc = fcntl(fd, F_GETFL)) == -1) 146 return -1; 147 148 rc |= flags; 149 150 if (fcntl(fd, F_SETFL, rc) == -1) 151 return -1; 152 153 return rc; 154 } 155 156 void path_join(char* buffer, const char* component, ...) { 157 va_list va; 158 int index = 0; 159 160 va_start(va, component); 161 162 do { 163 if (!index) 164 buffer[index++] = '/'; 165 while (*component) 166 buffer[index++] = *(component++); 167 } while ((component = va_arg(va, const char*))); 168 buffer[index] = '\0'; 169 }