X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=utils%2Futils.c;h=e239eda5110ec4e38b88880d7b7d24341389e85e;hp=e782e4428842684d725f361d769f101a9659ed3c;hb=8d720b2c2e569885c6e1e7eab68d36f31818ed84;hpb=f83a9e2f677df368ff3a6deea5aaeca7f28cd46e;ds=sidebyside diff --git a/utils/utils.c b/utils/utils.c index e782e44..e239eda 100644 --- a/utils/utils.c +++ b/utils/utils.c @@ -12,15 +12,23 @@ * GNU General Public License for more details. */ +#define _GNU_SOURCE #include #include #include "utils.h" -#include #include #include #include #include #include +#include +#include + +#include "../log.h" + +#ifndef O_PATH +#define O_PATH 010000000 +#endif void __blobmsg_list_init(struct blobmsg_list *list, int offset, int len, blobmsg_list_cmp cmp) @@ -129,36 +137,77 @@ blobmsg_list_equal(struct blobmsg_list *l1, struct blobmsg_list *l2) char* get_cmdline_val(const char* name, char* out, int len) { - char pattern[CMDLINE_SIZE + 1]; - char line[CMDLINE_SIZE + 1]; - char *res = NULL, *tty; - int r, fd; - regex_t pat_cmdline; - regmatch_t matches[2]; - - fd = open("/proc/cmdline", O_RDONLY); - if (fd < 0) - return NULL; + char line[CMDLINE_SIZE + 1], *c, *sptr; + int fd = open("/proc/cmdline", O_RDONLY); + ssize_t r = read(fd, line, sizeof(line) - 1); + close(fd); - r = read(fd, line, CMDLINE_SIZE); - if ( r <= 0 ) { - close(fd); + if (r <= 0) return NULL; + + line[r] = 0; + + for (c = strtok_r(line, " \t\n", &sptr); c; + c = strtok_r(NULL, " \t\n", &sptr)) { + char *sep = strchr(c, '='); + ssize_t klen = sep - c; + if (klen < 0 || strncmp(name, c, klen) || name[klen] != 0) + continue; + + strncpy(out, &sep[1], len); + out[len-1] = 0; + return out; } - line[r] = '\0'; - close(fd); - sprintf( pattern, "%s=([^ \n]*)", name); - regcomp(&pat_cmdline, pattern, REG_EXTENDED); - if (!regexec(&pat_cmdline, line, 2, matches, 0)) { - line[matches[1].rm_eo] = '\0'; - tty = (line + matches[1].rm_so); - strncpy(out, tty, len); - tty[len-1] = '\0'; - res = out; + return NULL; +} + +int patch_fd(const char *device, int fd, int flags) +{ + int dfd, nfd; + + if (device == NULL) + device = "/dev/null"; + + if (*device != '/') { + dfd = open("/dev", O_PATH|O_DIRECTORY); + + if (dfd < 0) + return -1; + + nfd = openat(dfd, device, flags); + + close(dfd); + } else { + nfd = open(device, flags); } - regfree(&pat_cmdline); + if (nfd < 0 && strcmp(device, "/dev/null")) + nfd = open("/dev/null", flags); + + if (nfd < 0) + return -1; + + fd = dup2(nfd, fd); + + if (nfd > STDERR_FILENO) + close(nfd); + + return (fd < 0) ? -1 : 0; +} + +int patch_stdio(const char *device) +{ + int fd, rv = 0; + const char *fdname[3] = { "stdin", "stdout", "stderr" }; + + for (fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) { + if (patch_fd(device, fd, fd ? O_WRONLY : O_RDONLY)) { + ERROR("Failed to redirect %s to %s: %d (%s)\n", + fdname[fd], device, errno, strerror(errno)); + rv = -1; + } + } - return res; + return rv; }