static int netifd_dir_push(int fd) { int prev_fd = open(".", O_RDONLY | O_DIRECTORY); system_fd_set_cloexec(prev_fd); if (fd >= 0) fchdir(fd); return prev_fd; }
int netifd_open_subdir(const char *name) { int prev_dir; int ret = -1; prev_dir = netifd_dir_push(-1); if (chdir(main_path)) { perror("chdir(main path)"); goto out; } ret = open(name, O_RDONLY | O_DIRECTORY); if (ret >= 0) system_fd_set_cloexec(ret); out: netifd_dir_pop(prev_dir); return ret; }
int jrpc_server_init(struct jrpc_server *server, char *host, char *port) { char *debug_level_env = getenv("JRPC_DEBUG"); if (debug_level_env == NULL) { server->debug_level = 0; } else { server->debug_level = strtol(debug_level_env, NULL, 10); dlog("JSONRPC-C Debug level %d\n", server->debug_level); } server->sock.cb = server_cb; server->sock.fd = usock(USOCK_TCP | USOCK_SERVER | USOCK_IPV4ONLY | USOCK_NUMERIC, host, port); if (server->sock.fd < 0) { perror("usock"); return 1; } system_fd_set_cloexec(server->sock.fd); uloop_fd_add(&server->sock, ULOOP_READ | ULOOP_EDGE_TRIGGER); return 0; }
static bool get_next_connection(int server_fd, struct jrpc_server *server) { struct jrpc_connection *conn; int fd; struct sockaddr_in a; socklen_t len; memset(&a, 0, sizeof(a)); len = sizeof(struct sockaddr); fd = accept(server_fd, (struct sockaddr *)&a, &len); if (fd < 0) { /* elog("accept[0x%08x] error[%d] error[%d] return false\n", server_fd, fd, errno); */ switch (errno) { case ECONNABORTED: case EINTR: return true; default: return false; } } conn = new_connection(fd, connection_cb); if (conn) { memcpy(&conn->addr, &a, sizeof(a)); system_fd_set_cloexec(conn->sock.fd); conn->server = server; conn->debug_level = server->debug_level; uloop_fd_add(&conn->sock, ULOOP_READ); } else { close(fd); } return true; }
int netifd_start_process(const char **argv, char **env, struct netifd_process *proc) { int pfds[2]; int pid; netifd_kill_process(proc); if (pipe(pfds) < 0) return -1; if ((pid = fork()) < 0) goto error; if (!pid) { int i; if (env) { while (*env) { putenv(*env); env++; } } if (proc->dir_fd >= 0) if (fchdir(proc->dir_fd)) {} close(pfds[0]); for (i = 0; i <= 2; i++) { if (pfds[1] == i) continue; dup2(pfds[1], i); } if (pfds[1] > 2) close(pfds[1]); execvp(argv[0], (char **) argv); exit(127); } if (pid < 0) goto error; close(pfds[1]); proc->uloop.cb = netifd_process_cb; proc->uloop.pid = pid; uloop_process_add(&proc->uloop); list_add_tail(&proc->list, &process_list); 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; error: close(pfds[0]); close(pfds[1]); return -1; }