X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=main.c;h=d8cb17f40658f8c7a6b777270a0eb08c4c239df9;hp=b7d660efa0703f2fb531ccf1b2dc77b51ec31e64;hb=9cd56141e80ea7d19350584d382d303f884d0aa5;hpb=17f3e46961723c1ae512dee4492d809c505260dc diff --git a/main.c b/main.c index b7d660e..d8cb17f 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,20 @@ +/* + * netifd - network interface daemon + * Copyright (C) 2012 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include #include #include #include -#include #include #include #include @@ -19,7 +31,6 @@ const char *resolv_conf = DEFAULT_RESOLV_CONF; static char **global_argv; static struct list_head process_list = LIST_HEAD_INIT(process_list); -static struct list_head fds = LIST_HEAD_INIT(fds); #define DEFAULT_LOG_LEVEL L_NOTICE @@ -42,14 +53,9 @@ static bool use_syslog = true; static void netifd_delete_process(struct netifd_process *proc) { - if (proc->uloop.pending) - uloop_process_delete(&proc->uloop); list_del(&proc->list); - netifd_fd_delete(&proc->log_fd); - if (proc->log_buf) { - free(proc->log_buf); - proc->log_buf = NULL; - } + ustream_free(&proc->log.stream); + close(proc->log.fd.fd); } void @@ -69,76 +75,46 @@ netifd_log_message(int priority, const char *format, ...) } static void -netifd_process_log_cb(struct uloop_fd *fd, unsigned int events) +netifd_process_log_read_cb(struct ustream *s, int bytes) { struct netifd_process *proc; const char *log_prefix; - char *buf, *start, *cur; - int maxlen, len, read_len; - - proc = container_of(fd, struct netifd_process, log_uloop); - - if (!proc->log_buf) - proc->log_buf = malloc(LOG_BUF_SIZE + 1); + char *data; + int len = 0; + proc = container_of(s, struct netifd_process, log.stream); log_prefix = proc->log_prefix; if (!log_prefix) log_prefix = "process"; -retry: - buf = proc->log_buf + proc->log_buf_ofs; - maxlen = LOG_BUF_SIZE - proc->log_buf_ofs; - read_len = len = read(fd->fd, buf, maxlen); - if (len < 0) { - if (errno == EINTR) - goto retry; - - goto out; - } else if (len == 0) - goto out; - - proc->log_buf_ofs += len; - - cur = buf; - start = proc->log_buf; - while (len > 0) { - cur = memchr(cur, '\n', len); - if (!cur) + do { + char *newline; + + data = ustream_get_read_buf(s, &len); + if (!len) break; - *cur = 0; + newline = strchr(data, '\n'); - if (!proc->log_overflow) + if (proc->log_overflow) { + if (newline) { + len = newline + 1 - data; + proc->log_overflow = false; + } + } else if (newline) { + *newline = 0; + len = newline + 1 - data; netifd_log_message(L_NOTICE, "%s (%d): %s\n", - log_prefix, proc->uloop.pid, start); - else - proc->log_overflow = false; - - cur++; - len -= cur - buf; - buf = start = cur; - } - - if (buf > proc->log_buf && len > 0) - memmove(proc->log_buf, buf, len); - - if (len == LOG_BUF_SIZE) { - if (!proc->log_overflow) { - proc->log_buf[LOG_BUF_SIZE] = 0; + log_prefix, proc->uloop.pid, data); + } else if (len == s->r.buffer_len) { netifd_log_message(L_NOTICE, "%s (%d): %s [...]\n", - log_prefix, proc->uloop.pid, proc->log_buf); + log_prefix, proc->uloop.pid, data); proc->log_overflow = true; - } - len = 0; - } - proc->log_buf_ofs = len; - - if (read_len > 0) - goto retry; + } else + break; -out: - if (fd->eof) - uloop_fd_delete(fd); + ustream_consume(s, len); + } while (1); } static void @@ -146,7 +122,8 @@ netifd_process_cb(struct uloop_process *proc, int ret) { struct netifd_process *np; np = container_of(proc, struct netifd_process, uloop); - netifd_process_log_cb(&np->log_uloop, 0); + + while (ustream_poll(&np->log.stream)); netifd_delete_process(np); return np->cb(np, ret); } @@ -154,7 +131,6 @@ netifd_process_cb(struct uloop_process *proc, int ret) int netifd_start_process(const char **argv, char **env, struct netifd_process *proc) { - struct netifd_fd *fd; int pfds[2]; int pid; @@ -167,6 +143,8 @@ netifd_start_process(const char **argv, char **env, struct netifd_process *proc) goto error; if (!pid) { + int i; + if (env) { while (*env) { putenv(*env); @@ -176,19 +154,17 @@ netifd_start_process(const char **argv, char **env, struct netifd_process *proc) if (proc->dir_fd >= 0) fchdir(proc->dir_fd); - /* close all non-essential fds */ - list_for_each_entry(fd, &fds, list) { - if (fd->proc == proc) + close(pfds[0]); + + for (i = 0; i <= 2; i++) { + if (pfds[1] == i) continue; - close(fd->fd); - } - dup2(pfds[1], 0); - dup2(pfds[1], 1); - dup2(pfds[1], 2); + dup2(pfds[1], i); + } - close(pfds[0]); - close(pfds[1]); + if (pfds[1] > 2) + close(pfds[1]); execvp(argv[0], (char **) argv); exit(127); @@ -203,11 +179,10 @@ netifd_start_process(const char **argv, char **env, struct netifd_process *proc) uloop_process_add(&proc->uloop); list_add_tail(&proc->list, &process_list); - proc->log_buf_ofs = 0; - proc->log_uloop.fd = proc->log_fd.fd = pfds[0]; - proc->log_uloop.cb = netifd_process_log_cb; - netifd_fd_add(&proc->log_fd); - uloop_fd_add(&proc->log_uloop, ULOOP_EDGE_TRIGGER | ULOOP_READ); + system_fd_set_cloexec(pfds[0]); + proc->log.stream.string_data = true; + proc->log.stream.notify_read = netifd_process_log_read_cb; + ustream_fd_init(&proc->log, pfds[0]); return 0; @@ -224,21 +199,10 @@ netifd_kill_process(struct netifd_process *proc) return; kill(proc->uloop.pid, SIGKILL); + uloop_process_delete(&proc->uloop); netifd_delete_process(proc); } -void -netifd_fd_add(struct netifd_fd *fd) -{ - list_add_tail(&fd->list, &fds); -} - -void -netifd_fd_delete(struct netifd_fd *fd) -{ - list_del(&fd->list); -} - static void netifd_do_restart(struct uloop_timeout *timeout) { execvp(global_argv[0], global_argv);