int process_element( xmlNode *node) { char *str; int rc = PBSE_NONE; if (node == NULL) return(PBSE_NONE); if (!strcmp((const char *)node->name, response_data)) { str = (char *)xmlGetProp(node, (const xmlChar *)"status"); if (strcmp(str, success)) { free(str); return(ALPS_QUERY_FAILURE); } else rc = process_element(node->children); free(str); } else if (!strcmp((const char *)node->name, node_array)) { rc = process_nodes(node->children); rc = process_element(node->next); } else if (!strcmp((const char *)node->name, reservation_array)) { rc = process_reservations(node->children); } else if (!strcmp((const char *)node->name, text_name)) { rc = process_element(node->next); } else if (!strcmp((const char *)node->name, system_tag)) { rc = process_system(node); } else { /* move on to the next child */ rc = process_element(node->children); } return(rc); } /* END process_element() */
void gram_SYSTEM() { char *cmd; parser_push_fun("SYSTEM"); cmd = parser_parlist(&parser, COLLECT_SET); if (message_show(MSG_NOTICE)) message("SYSTEM %s", string_short(cmd)); if (!check_live_data(cmd)) free(cmd); else { Process process; process_construct(&process, "SYSTEM", cmd, NULL); process_system(&process); process_destroy(&process); } parser_pop_fun(); }
int main(int argc, char **argv) { String *cmd = string_new(0); String *input = NULL; if (argc == 1) { fprintf(stderr, "Usage: %s [-s] prog [arg(s)]\n" " -s: use system call, not std-input\n" " prog: program or system call to execute\n" " arg(s): optional arguments to prog\n" "Input to prog is read from stdin, unless -s was specified\n" " (don't make this too long, it's stored in a String first)\n" "\n", argv[0]); exit(1); } bool syscall = !strcmp(argv[1], "-s"); if (syscall) { argc--; argv++; } else { input = string_new(0); char buffer[100]; fprintf(stderr, "Reading input from stdin...\n"); while (fgets(buffer, 100, stdin)) string_addstr(input, buffer); fprintf(stderr, "Input will be:\n" "`%s'\n", string_str(input)); } while (*++argv) { string_addstr(cmd, *argv); string_addchar(cmd, ' '); } fprintf(stderr, "Command will be:\n" "`%s'\n", string_str(cmd)); message_setseverity(MSG_ALL); message(MSG_NOTICE, "Creating Process"); Process process; process_construct(&process, "process-demo", cmd, input); if (syscall) process_system(&process); else process_fork(&process); String const *out = process_output(&process); fprintf(stderr, "Output from process: '\n" "%s\n" "'\n", string_str(out)); process_destroy(&process); return 0; }
int main(int argc, char **argv) { liao_log("liao_server", LOG_PID|LOG_NDELAY, LOG_MAIL); if (argc != 3) { usage(argv[0]); exit(0); } if (chdir(LIAO_HOME) == -1) { log_alert("cannot start: unable to switch to home directory"); exit(0); } snprintf(msg_id, sizeof(msg_id), "00000000"); char cfg_file[MAX_LINE] = CFG_FILE; int c; const char *args = "c:h"; while ((c = getopt(argc, argv, args)) != -1) { switch (c) { case 'c': snprintf(cfg_file, sizeof(cfg_file), "%s", optarg); break; case 'h': default: usage(argv[0]); exit(0); } } // 处理配置文件 if (conf_init(cfg_file)) { fprintf(stderr, "Unable to read control files:%s\n", cfg_file); log_error("Unable to read control files:%s", cfg_file); exit(1); } /* // 检查队列目录 if (strlen(config_st.queue_path) <= 0) { fprintf(stderr, "Unable to read queue path.\n"); log_error("Unable to read queue path."); exit(1); } if ( access(config_st.queue_path, F_OK) ) { fprintf(stderr, "Queue path:%s not exists:%s, so create it.\n", config_st.queue_path, strerror(errno)); log_error("Queue path:%s not exists:%s, so create it.", config_st.queue_path, strerror(errno)); umask(0); mkdir(config_st.queue_path, 0777); }*/ online_d = dictionary_new(atoi(config_st.max_works) + 1); child_st = (struct childs *)malloc((atoi(config_st.max_works) + 1) * sizeof(struct childs)); if (!child_st) { log_error("malloc childs [%d] failed:[%d]%s", (atoi(config_st.max_works) + 1), errno, strerror(errno)); exit(1); } int i = 0; for (i=0; i<(atoi(config_st.max_works) + 1); i++) { child_st[i].used = 0; child_st[i].pid = -1; child_st[i].client_fd = -1; child_st[i].pipe_r_in = -1; child_st[i].pipe_r_out = -1; child_st[i].pipe_w_in = -1; child_st[i].pipe_w_out = -1; memset(child_st[i].mid, 0, sizeof(child_st[i].mid)); child_st[i].mfp_out = NULL; } // 开始服务 int connfd, epfd, sockfd, n, nread; struct sockaddr_in local, remote; socklen_t addrlen; // 初始化buffer char buf[BUF_SIZE]; size_t pbuf_len = 0; size_t pbuf_size = BUF_SIZE + 1; char *pbuf = (char *)calloc(1, pbuf_size); if (pbuf == NULL) { log_error("calloc fail: size[%d]", pbuf_size); exit(1); } // 创建listen socket int bind_port = atoi(config_st.bind_port); if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { log_error("socket failed:[%d]:%s", errno, strerror(errno)); exit(1); } if (setnonblocking(listenfd) > 0) { exit(1); } bzero(&local, sizeof(local)); local.sin_family = AF_INET; local.sin_addr.s_addr = htonl(INADDR_ANY); local.sin_port = htons(bind_port); if (bind(listenfd, (struct sockaddr *)&local, sizeof(local)) < 0) { log_error("bind local %d failed:[%d]%s", bind_port, errno, strerror(errno)); exit(1); } log_info("bind local %d succ", bind_port); if (listen(listenfd, atoi(config_st.max_works)) != 0) { log_error("listen fd[%d] max_number[%d] failed:[%d]%s", listenfd, atoi(config_st.max_works), errno, strerror(errno)); exit(1); } // 忽略pipe信号 sig_pipeignore(); // 捕抓子进程退出信号 sig_catch(SIGCHLD, sigchld); // epoll create fd epoll_event_num = atoi(config_st.max_works) + 1; epoll_evts = NULL; epoll_fd = -1; epoll_nfds = -1; int epoll_i = 0; epoll_evts = (struct epoll_event *)malloc(epoll_event_num * sizeof(struct epoll_event)); if (epoll_evts == NULL) { log_error("alloc epoll event failed"); _exit(111); } epoll_fd = epoll_create(epoll_event_num); if (epoll_fd == -1) { log_error("epoll_create max_number[%d] failed:[%d]%s", epoll_event_num, errno, strerror(errno)); exit(1); } struct epoll_event ev; ev.events = EPOLLIN; ev.data.fd = listenfd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) { log_error("epoll_ctl: listen_socket failed:[%d]%s", errno, strerror(errno)); exit(1); } epoll_num_running = 1; for (;;) { epoll_nfds = epoll_wait(epoll_fd, epoll_evts, epoll_event_num, -1); if (epoll_nfds == -1) { if (errno == EINTR) { // 收到中断信号 log_info("epoll_wait recive EINTR signal, continue"); continue; } _exit(111); } log_debug("epoll_num_running:%d nfds:%d", epoll_num_running, epoll_nfds); for (epoll_i = 0; epoll_i < epoll_nfds; epoll_i++) { sig_childblock(); int evt_fd = epoll_evts[epoll_i].data.fd; if (evt_fd == listenfd) { if ((connfd = accept(listenfd, (struct sockaddr *) &remote, &addrlen)) > 0) { char *ipaddr = inet_ntoa(remote.sin_addr); log_info("accept client:%s", ipaddr); char greetting[512] = {0}; char hostname[1024] = {0}; if (gethostname(hostname, sizeof(hostname)) != 0) { snprintf(hostname, sizeof(hostname), "unknown"); } // 取客户端IP,Port char client_ip[20] = {0}; char client_port[20] = {0}; struct sockaddr_in sa; int len = sizeof(sa); if (!getpeername(connfd, (struct sockaddr *)&sa, &len)) { snprintf(client_ip, sizeof(client_ip), "%s", inet_ntoa(sa.sin_addr)); snprintf(client_port, sizeof(client_port), "%d", ntohs(sa.sin_port)); } // 取一个新的client int i = new_idx_from_child_st(); if (i == -1) { log_error("new_idx_from_client_st fail: maybe client queue is full."); // send error snprintf(greetting, sizeof(greetting), "%s ERR %s%s", TAG_GREET, hostname, DATA_END); write(connfd, greetting, strlen(greetting)); log_debug("send fd[%d]:%s", connfd, greetting); continue; } child_st[i].used = 1; int pir[2]; int piw[2]; if (pipe(pir) == -1) { log_error("unable to create pipe:%s", strerror(errno)); // send error snprintf(greetting, sizeof(greetting), "%s ERR %s%s", TAG_GREET, hostname, DATA_END); write(connfd, greetting, strlen(greetting)); log_debug("send fd[%d]:%s", connfd, greetting); continue; } if (pipe(piw) == -1) { log_error("unable to create pipe:%s", strerror(errno)); close(pir[0]); close(pir[1]); pir[0] = -1; pir[1] = -1; // send error snprintf(greetting, sizeof(greetting), "%s ERR %s%s", TAG_GREET, hostname, DATA_END); write(connfd, greetting, strlen(greetting)); log_debug("send fd[%d]:%s", connfd, greetting); continue; } log_debug("create pir[0]:%d pir[1]:%d", pir[0], pir[1]); log_debug("create piw[0]:%d piw[1]:%d", piw[0], piw[1]); // 当程序执行exec函数时本fd将被系统自动关闭,表示不传递给exec创建的新进程 //fcntl(pir[0], F_SETFD, FD_CLOEXEC); //fcntl(piw[1], F_SETFD, FD_CLOEXEC); int f = fork(); if (f < 0) { log_error("fork fail:%s", strerror(errno)); close(pir[0]); close(pir[1]); pir[0] = -1; pir[1] = -1; close(piw[0]); close(piw[1]); piw[0] = -1; piw[1] = -1; child_st[i].used = 0; // send error snprintf(greetting, sizeof(greetting), "%s ERR %s%s", TAG_GREET, hostname, DATA_END); write(connfd, greetting, strlen(greetting)); log_debug("send fd[%d]:%s", connfd, greetting); continue; } struct timeval tm; gettimeofday(&tm, NULL); snprintf(child_st[i].mid, sizeof(child_st[i].mid), "%05u%u", (uint32_t)tm.tv_usec, (uint32_t)f); snprintf(msg_id, sizeof(msg_id), "%s", child_st[i].mid); if (f == 0) { // 子进程 close(pir[0]); close(piw[1]); close(listenfd); char _cmid[512] = {0}; char _cchild_st[512] = {0}; char _ccip[20] = {0}; char _ccport[20] = {0}; snprintf(_cmid, sizeof(_cmid), "-m%s", child_st[i].mid); snprintf(_cchild_st, sizeof(_cchild_st), "-c%s", config_st.child_cf); snprintf(_ccip, sizeof(_ccip), "-i%s", client_ip); snprintf(_ccport, sizeof(_ccport), "-p%s", client_port); char *args[6]; args[0] = "./liao_command"; args[1] = _cmid; args[2] = _cchild_st; args[3] = _ccip; args[4] = _ccport; args[5] = 0; if (fd_move(0, connfd) == -1) { log_info("%s fd_move(0, %d) failed:%d %s", child_st[i].mid, connfd, errno, strerror(errno)); _exit(111); } if (fd_move(1, pir[1]) == -1) { log_info("%s fd_move(pipe_w, %d) failed:%d %s", child_st[i].mid, pir[1], errno, strerror(errno)); _exit(111); } if (fd_move(2, piw[0]) == -1) { log_info("%s fd_move(pipe_r, %d) failed:%d %s", child_st[i].mid, piw[0], errno, strerror(errno)); _exit(111); } if (execvp(*args, args) == -1) { log_error("execp fail:%s", strerror(errno)); _exit(111); } //if (error_temp(errno)) // _exit(111); log_debug("execp succ"); _exit(100); } close(connfd); child_st[i].pipe_r_in = pir[0]; close(pir[1]); pir[1] = -1; child_st[i].pipe_r_out = -1; child_st[i].pipe_w_out = piw[1]; close(piw[0]); piw[0] = -1; child_st[i].pipe_w_in = -1; child_st[i].pid = f; if (setnonblocking(child_st[i].pipe_r_in) != 0) { log_error("setnonblocking fd[%d] failed", child_st[i].pipe_r_in); } struct epoll_event pipe_in_ev; pipe_in_ev.events = EPOLLIN | EPOLLET; pipe_in_ev.data.fd = child_st[i].pipe_r_in; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, pipe_in_ev.data.fd, &pipe_in_ev) == -1) { log_error("epoll_ctl client fd[%d] EPOLL_CTL_ADD failed:[%d]%s", pipe_in_ev.data.fd, errno, strerror(errno)); } log_debug("epoll_add fd[%d]", pipe_in_ev.data.fd); } else if (connfd == -1) { if (errno != EAGAIN && errno != ECONNABORTED && errno != EPROTO && errno != EINTR) { log_error("accept failed:[%d]%s", errno, strerror(errno)); } continue; } } else if (epoll_evts[epoll_i].events & EPOLLIN) { int ci = get_idx_with_sockfd(evt_fd); if (ci < 0) { log_error("socket fd[%d] get_idx_with_sockfd fail", evt_fd); continue; } log_debug("%s get event EPOLLIN: epoll_i[%d] fd[%d] get d_i[%d] fd[%d], used[%d]", child_st[ci].mid, epoll_i, epoll_evts[epoll_i].data.fd, child_st[ci].pipe_r_in, child_st[ci].used); // 读取内容 ---------------------- char inbuf[BUF_SIZE] = {0}; char *pinbuf = inbuf; int inbuf_size = BUF_SIZE; int inbuf_len = 0; char ch; do { i = 0; nread = read(child_st[ci].pipe_r_in, inbuf, inbuf_size); log_debug("%s read from liao_command:[%d]", child_st[ci].mid, nread); if (nread == -1) { // read error on a readable pipe? be serious //log_error("it is failed from fd[%d] read. error:%d %s", child_st[ci].fd_in, errno, strerror(errno)); //log_debug("it is failed from fd[%d] read. error:%d %s", child_st[ci].pipe_r_in, errno, strerror(errno)); break; } else if (nread > 0) { if (child_st[ci].mfp_out == NULL) { child_st[ci].mfp_out = mopen(MAX_BLOCK_SIZE, NULL, NULL); if (child_st[ci].mfp_out == NULL) { log_debug("%s mopen for body fail", child_st[ci].mid); break; } } while (i < nread) { ch = inbuf[i]; if ((inbuf_size - inbuf_len) < 2) { int r = fast_write(child_st[ci].mfp_out, inbuf, inbuf_len); if (r == 0) { log_error("%s fast_write fail", child_st[ci].mid); break; } memset(inbuf, 0, inbuf_size); inbuf_len = 0; } mybyte_copy(pinbuf + inbuf_len, 1, &ch); inbuf_len++; if (ch == '\n') { if (inbuf_len > 0) { int r = fast_write(child_st[ci].mfp_out, inbuf, inbuf_len); if (r == 0) { log_error("%s fast_write fail", child_st[ci].mid); break; } memset(inbuf, 0, inbuf_size); inbuf_len = 0; } // 处理当前指令 // ... process_system(&child_st[ci]); // ... // 处理完成后 if (child_st[ci].mfp_out != NULL) { mclose(child_st[ci].mfp_out); child_st[ci].mfp_out = NULL; child_st[ci].mfp_out = mopen(MAX_BLOCK_SIZE, NULL, NULL); if (child_st[ci].mfp_out == NULL) { log_error("mopen fail for mfp_out"); break; } } pinbuf = inbuf + 0; } i++; } } else { break; } } while (1); } else if ((epoll_evts[epoll_i].events & EPOLLHUP) && (epoll_evts[epoll_i].data.fd != listenfd)) { int ci = get_idx_with_sockfd(evt_fd); if ( ci < 0 ) { log_error("get_idx_with_sockfd(%d) fail, so not write", evt_fd); continue; } log_debug("%s get event EPOLLHUP: epoll_i[%d] fd[%d] get d_i[%d] fd[%d], used[%d]", child_st[ci].mid, epoll_i, epoll_evts[epoll_i].data.fd, child_st[ci].pipe_r_in, child_st[ci].used); epoll_delete_evt(epoll_fd, child_st[ci].pipe_r_in); continue; } } sig_childunblock(); } close(epoll_fd); close(listenfd); log_info("i'm finish"); return 0; }