void Process::async_read() { if(data.id==0) return; if(stdout_fd) { stdout_thread=std::thread([this](){ DWORD n; std::unique_ptr<char[]> buffer(new char[buffer_size]); for (;;) { BOOL bSuccess = ReadFile(*stdout_fd, static_cast<CHAR*>(buffer.get()), static_cast<DWORD>(buffer_size), &n, nullptr); if(!bSuccess || n == 0) break; read_stdout(buffer.get(), static_cast<size_t>(n)); } }); } if(stderr_fd) { stderr_thread=std::thread([this](){ DWORD n; std::unique_ptr<char[]> buffer(new char[buffer_size]); for (;;) { BOOL bSuccess = ReadFile(*stderr_fd, static_cast<CHAR*>(buffer.get()), static_cast<DWORD>(buffer_size), &n, nullptr); if(!bSuccess || n == 0) break; read_stderr(buffer.get(), static_cast<size_t>(n)); } }); } }
void Process::async_read() { if(data.id<=0) return; if(stdout_fd) { stdout_thread=std::thread([this](){ auto buffer = std::unique_ptr<char[]>( new char[buffer_size] ); ssize_t n; while ((n=read(*stdout_fd, buffer.get(), buffer_size)) > 0) read_stdout(buffer.get(), static_cast<size_t>(n)); }); } if(stderr_fd) { stderr_thread=std::thread([this](){ auto buffer = std::unique_ptr<char[]>( new char[buffer_size] ); ssize_t n; while ((n=read(*stderr_fd, buffer.get(), buffer_size)) > 0) read_stderr(buffer.get(), static_cast<size_t>(n)); }); } }
void Process::async_read() { if(data.id<=0) return; if(stdout_fd) { stdout_thread=std::thread([this](){ char buffer[buffer_size]; ssize_t n; while ((n=read(*stdout_fd, buffer, buffer_size)) > 0) read_stdout(buffer, static_cast<size_t>(n)); }); } if(stderr_fd) { stderr_thread=std::thread([this](){ char buffer[buffer_size]; ssize_t n; while ((n=read(*stderr_fd, buffer, buffer_size)) > 0) read_stderr(buffer, static_cast<size_t>(n)); }); } }
/** * @brief thread routine that handle a forked process * @param arg the ::child_node for the forked child * @return 0 on success, -1 on error. */ void *handle_child(void *arg) { child_node *c; int status; pid_t wait_res; void *ret; int stdout_error; #ifndef NDEBUG char *name; #endif c = (child_node *)arg; ret = (void *) -1; stdout_error = 0; wait_res = 0; #ifndef NDEBUG print( DEBUG, "new child started. (name=%s, pid=%d)", c->handler->name, c->pid ); #endif if(c->handler->have_stdout) { if((stdout_error = read_stdout(c))) { print(ERROR, "cannot read process stdout"); } } stdout_error &= read_stderr(c); if((wait_res = waitpid(c->pid, &status, 0)) != c->pid) { print(ERROR, "waitpid: %s", strerror(errno)); } else if(on_child_done(c, status)) { print(ERROR, "cannot notify child termination."); } else if(!stdout_error) ret = 0; #ifdef NDEBUG send_to_graveyard(c->tid); #else if(asprintf(&name, "%s(name=%s, pid=%d)", __func__, c->handler->name, c->pid)<0) { print( ERROR, "asprintf: %s", strerror(errno) ); name=NULL; } _send_to_graveyard(c->tid, name); #endif pthread_mutex_lock(&(c->conn->children.control.mutex)); list_del(&(c->conn->children.list), (node *)c); pthread_mutex_unlock(&(c->conn->children.control.mutex)); pthread_cond_broadcast(&(c->conn->children.control.cond)); if(wait_res!=c->pid) kill(c->pid, 9); // SIGKILL, process didn't returned as expected if(c->handler->have_stdout) close(c->stdout_fd); if(c->handler->have_stdin) close(c->stdin_fd); close(c->stderr_fd); free(c); return ret; }