static int undiverted(const char *path) { const char * const cmd[] = {"dpkg-divert", "--listpackage", path, NULL}; pid_t child; char packagename[sizeof("bash\n")]; size_t len; FILE *in = spawn_pipe(&child, cmd, -1); int diverted = 1; /* Is $path diverted by someone other than bash? */ len = fread(packagename, 1, sizeof(packagename), in); if (ferror(in)) die_errno("cannot read from dpkg-divert"); if (len == 0) diverted = 0; /* No diversion. */ if (len == strlen("bash\n") && !memcmp(packagename, "bash\n", len)) diverted = 0; /* Diverted by bash. */ if (fclose(in)) die_errno("cannot close read end of pipe"); wait_or_die(child, "dpkg-divert", ERROR_OK | SIGPIPE_OK); return !diverted; }
static int binsh_in_filelist(const char *package) { const char * const cmd[] = {"dpkg-query", "-L", package, NULL}; pid_t child; int sink; FILE *in; int found; /* * dpkg -L $package 2>/dev/null | ... * * Redirection of stderr is for quieter output * when $package is not installed. If opening /dev/null * fails, no problem; leave stderr alone in that case. */ sink = open("/dev/null", O_WRONLY); if (sink >= 0) set_cloexec(sink); in = spawn_pipe(&child, cmd, sink); /* ... | grep "^/bin/sh\$" */ found = has_binsh_line(in); if (fclose(in)) die_errno("cannot close read end of pipe"); /* * dpkg -L will error out if $package is not already installed. * * We stopped reading early if we found a match, so * tolerate SIGPIPE in that case. */ wait_or_die(child, "dpkg-query -L", ERROR_OK | (found ? SIGPIPE_OK : 0)); return found; }
int main(void) { char *echo_args[] = {"echo", "hello", "world", "!!", NULL}; char *cat_args[] = {"cat", NULL}; char *ls_args[] = {"ls", "-lha", NULL}; char *simple_echo_args[] = {"simple-echo", NULL}; const char *writestr = "TEST STRING\n"; char buf[1024*10]; char *buf_pointer; child_process_t process; int status; bool should_write = false; int i, j; // no pipe process = spawn_basic("echo", echo_args, true); if (process.pid < 0) goto onerror; waitpid(process.pid, &status, 0); // connect stdout to file //process = spawn("echo", echo_args, 0, true); // stdin only process = spawn_pipe("cat", cat_args, SPAWN_PIPE_STDIN, true); if (process.pid < 0) goto onerror; write(process.fd_stdin, writestr, strlen(writestr)); close(process.fd_stdin); waitpid(process.pid, &status, 0); // stdout only process = spawn_pipe("ls", ls_args, SPAWN_PIPE_STDOUT, true); if (process.pid < 0) goto onerror; buf_pointer = buf; bzero(buf, sizeof(buf)); while (1) { ssize_t bytes = read(process.fd_stdout, buf_pointer, sizeof(buf)); if (bytes > 0) { buf_pointer += bytes; } else { if (bytes < 0) { perror("Failed to read pipe"); } break; } } waitpid(process.pid, &status, 0); printf("RESULT START\n%s\nEND\n", buf); // redirect stdout { int fd = open("./test-redirect.txt", O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); process = spawn("ls", ls_args, SPAWN_REDIRECT_STDOUT, true, 0, fd, 0); waitpid(process.pid, &status, 0); close(fd); } // stdin/stdout process = spawn_pipe("./simple-echo/simple-echo", simple_echo_args, SPAWN_PIPE_STDOUT|SPAWN_PIPE_STDIN, true); if (process.pid < 0) goto onerror; buf_pointer = buf; bzero(buf, sizeof(buf)); should_write = true; i = 0; while (1) { if (should_write) { if (i >= 4) { close(process.fd_stdin); break; } else { write(process.fd_stdin, writestr, strlen(writestr)); i += 1; } } ssize_t bytes = read(process.fd_stdout, buf_pointer, sizeof(buf) - (buf_pointer - buf)); if (bytes > 0) { //fprintf(stderr, "READING[%s]\n", buf_pointer); for (j = 0; j < bytes; j++) { if (buf_pointer[j] == '\n') { printf("ONE LINE %zd: [%s]\n", bytes, buf); buf_pointer = buf; bzero(buf, sizeof(buf)); should_write = true; goto continue2; } } buf_pointer += bytes; } else { if (bytes < 0) { perror("Failed to read pipe"); } break; } continue2: continue; } waitpid(process.pid, &status, 0); return status; onerror: perror("Failed to start process"); return 2; }
void open_mysql(void) { spawn_pipe(do_mysql_comms, &to_mysql_fd, &from_mysql_fd); network_register_fd(from_mysql_fd, mysqlchild_readable, 0, &(tasks)); }