bool Service::exec(std::string const & cmd) { std::string command = "/etc/init.d/" + name(); int pipe[3]; int pid; const char * const args[] = { command.c_str(), cmd.c_str(), NULL }; pid = popenRWE(pipe, args[0], args); int status = 0; waitpid(pid,&status,0); std::ostringstream out; char buf[1024]; ssize_t s = 0; while ((s = read(pipe[1], buf, 1024)) > 0) { out << std::string(buf, s); } lastOut = out.str(); std::ostringstream err; while ((s = read(pipe[2], buf, 1024)) > 0) { err << std::string(buf, s); } lastErr = err.str(); pcloseRWE(pid, pipe); return !status; }
virtual void run() { char buffer[1028]; while(fgets(buffer, 1028, outFile[STDOUT_FILENO]) != NULL) { if(outputHandle!=NULL) { outputHandle(data, buffer); } } errorThread->end(); while(!errorThread->isDone()) { sleep(1); } delete errorThread; errorThread = NULL; int result = pcloseRWE(pid, rwePipe)/256; if(resultHandle!=NULL) { resultHandle(data, result); } }
static char *shrink_urls(char *text) { int *ranges; int rcount; int i; int inofs = 0; int outofs = 0; const char *const shrink_args[] = { "bti-shrink-urls", NULL }; int shrink_pid; int shrink_pipe[3]; int inlen = strlen(text); dbg("before len=%u\n", inlen); shrink_pid = popenRWE(shrink_pipe, shrink_args[0], shrink_args); if (shrink_pid < 0) return text; rcount = find_urls(text, &ranges); if (!rcount) return text; for (i = 0; i < rcount; i += 2) { int url_start = ranges[i]; int url_end = ranges[i + 1]; int long_url_len = url_end - url_start; char *url = strndup(text + url_start, long_url_len); int short_url_len; int not_url_len = url_start - inofs; dbg("long url[%u]: %s\n", long_url_len, url); url = shrink_one_url(shrink_pipe, url); short_url_len = url ? strlen(url) : 0; dbg("short url[%u]: %s\n", short_url_len, url); if (!url || short_url_len >= long_url_len) { /* The short url ended up being too long * or unavailable */ if (inofs) { strncpy(text + outofs, text + inofs, not_url_len + long_url_len); } inofs += not_url_len + long_url_len; outofs += not_url_len + long_url_len; } else { /* copy the unmodified block */ strncpy(text + outofs, text + inofs, not_url_len); inofs += not_url_len; outofs += not_url_len; /* copy the new url */ strncpy(text + outofs, url, short_url_len); inofs += long_url_len; outofs += short_url_len; } free(url); } /* copy the last block after the last match */ if (inofs) { int tail = inlen - inofs; if (tail) { strncpy(text + outofs, text + inofs, tail); outofs += tail; } } free(ranges); (void)pcloseRWE(shrink_pid, shrink_pipe); text[outofs] = 0; dbg("after len=%u\n", outofs); return text; }
/* run a check */ int run_check(char *processed_command, char **ret, char **err) { char *argv[MAX_CMD_ARGS]; FILE *fp; pid_t pid; int pipe_stdout[2], pipe_stderr[2], pipe_rwe[3]; int retval; sigset_t mask; #ifdef EMBEDDEDPERL retval = run_epn_check(processed_command, ret, err); if(retval != GM_NO_EPN) { return retval; } #endif /* check for check execution method (shell or execvp) * command line does not have to contain shell meta characters * and cmd must begin with a /. Otherwise "BLAH=BLUB cmd" would lead * to file not found errors */ if((*processed_command == '/' || *processed_command == '.') && !strpbrk(processed_command,"!$^&*()~[]\\|{};<>?`\"'")) { /* use the fast execvp when there are no shell characters */ gm_log( GM_LOG_TRACE, "using execvp, no shell characters found\n" ); parse_command_line(processed_command,argv); if(!argv[0]) _exit(STATE_UNKNOWN); if(pipe(pipe_stdout)) { gm_log( GM_LOG_ERROR, "error creating pipe: %s\n", strerror(errno)); _exit(STATE_UNKNOWN); } if(pipe(pipe_stderr)) { gm_log( GM_LOG_ERROR, "error creating pipe: %s\n", strerror(errno)); _exit(STATE_UNKNOWN); } if((pid=fork())<0){ gm_log( GM_LOG_ERROR, "fork error\n"); _exit(STATE_UNKNOWN); } else if(!pid){ /* remove all customn signal handler */ sigfillset(&mask); sigprocmask(SIG_UNBLOCK, &mask, NULL); /* child process */ if((dup2(pipe_stdout[1],STDOUT_FILENO)<0)){ gm_log( GM_LOG_ERROR, "dup2 error\n"); _exit(STATE_UNKNOWN); } if((dup2(pipe_stderr[1],STDERR_FILENO)<0)){ gm_log( GM_LOG_ERROR, "dup2 error\n"); _exit(STATE_UNKNOWN); } close(pipe_stdout[1]); close(pipe_stderr[1]); current_child_pid = getpid(); execvp(argv[0], argv); if(errno == 2) _exit(127); if(errno == 13) _exit(126); _exit(STATE_UNKNOWN); } /* parent */ /* prepare stdout pipe reading */ close(pipe_stdout[1]); fp=fdopen(pipe_stdout[0],"r"); if(!fp){ gm_log( GM_LOG_ERROR, "fdopen error\n"); _exit(STATE_UNKNOWN); } *ret = extract_check_result(fp, GM_DISABLED); fclose(fp); /* prepare stderr pipe reading */ close(pipe_stderr[1]); fp=fdopen(pipe_stderr[0],"r"); if(!fp){ gm_log( GM_LOG_ERROR, "fdopen error\n"); _exit(STATE_UNKNOWN); } *err = extract_check_result(fp, GM_ENABLED); fclose(fp); close(pipe_stdout[0]); close(pipe_stderr[0]); if(waitpid(pid,&retval,0)!=pid) retval=-1; } else { /* use the slower popen when there were shell characters */ gm_log( GM_LOG_TRACE, "using popen, found shell characters\n" ); current_child_pid = getpid(); pid = popenRWE(pipe_rwe, processed_command); /* extract check result */ fp=fdopen(pipe_rwe[1],"r"); if(!fp){ gm_log( GM_LOG_ERROR, "fdopen error\n"); _exit(STATE_UNKNOWN); } *ret = extract_check_result(fp, GM_DISABLED); fclose(fp); /* extract check stderr */ fp=fdopen(pipe_rwe[2],"r"); if(!fp){ gm_log( GM_LOG_ERROR, "fdopen error\n"); _exit(STATE_UNKNOWN); } *err = extract_check_result(fp, GM_ENABLED); fclose(fp); /* close the process */ retval=pcloseRWE(pid, pipe_rwe); } return retval; }