/* * open the file by sending the "name" and "oflag" to the * connection server and reading a file descriptor back. */ int csopen(char *name, int oflag) { pid_t pid; int len; char buf[10]; struct iovec iov[3]; static int fd[2] = { -1, -1 }; if (fd[0] < 0) { /* fork/exec our open server first time */ /* * fd_pipe() is defined in figure 17-2.c */ if (fd_pipe(fd) < 0) { err_ret("fd_pipe error"); return -1; } if ((pid = fork()) < 0) { err_ret("fork error"); return -1; } else if (pid == 0) { /* child */ close(fd[0]); if (fd[1] != STDIN_FILENO && dup2(fd[1], STDIN_FILENO) != STDIN_FILENO) err_sys("dup2 error to stdin"); if (fd[1] != STDOUT_FILENO && dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) err_sys("dup2 error to stdout"); /* * exec family returns only if error */ if (execl("./opend", "opend", (char *)0) < 0) err_sys("execl error"); } /* parent */ close(fd[1]); } sprintf(buf, " %d", oflag); /* oflag to ascii */ iov[0].iov_base = CL_OPEN " "; /* string concatenation */ iov[0].iov_len = strlen(CL_OPEN) + 1; iov[1].iov_base = name; iov[1].iov_len = strlen(name); iov[2].iov_base = buf; iov[2].iov_len = strlen(buf) + 1; /* +1 for null at end of buf */ len = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len; if (writev(fd[0], &iov[0], 3) != len) { err_ret("writev error"); return -1; } /* * read descriptor, returned errors handled by write() * recv_fd() is defined in 17-14.c */ return (recv_fd(fd[0], write)); }
void do_driver(char *driver) { pid_t child; int pipe[2]; /* * Create a full-duplex pipe to communicate with the driver. */ if (fd_pipe(pipe) < 0) err_sys("can't create stream pipe"); if ((child = fork()) < 0) { err_sys("fork error"); } else if (child == 0) { /* child */ close(pipe[1]); /* stdin for driver */ if (dup2(pipe[0], STDIN_FILENO) != STDIN_FILENO) err_sys("dup2 error to stdin"); /* stdout for driver */ if (dup2(pipe[0], STDOUT_FILENO) != STDOUT_FILENO) err_sys("dup2 error to stdout"); if (pipe[0] != STDIN_FILENO && pipe[0] != STDOUT_FILENO) close(pipe[0]); /* leave stderr for driver alone */ execlp(driver, driver, (char *)0); err_sys("execlp error for: %s", driver); } close(pipe[0]); /* parent */ if (dup2(pipe[1], STDIN_FILENO) != STDIN_FILENO) err_sys("dup2 error to stdin"); if (dup2(pipe[1], STDOUT_FILENO) != STDOUT_FILENO) err_sys("dup2 error to stdout"); if (pipe[1] != STDIN_FILENO && pipe[1] != STDOUT_FILENO) close(pipe[1]); /* * Parent returns, but with stdin and stdout connected * to the driver. */ }
int /* returns 0 if all OK, -1 if error (with errno set) */ ns_pipe(const char *name, int fd[2]) { int len; struct sockaddr_un unix_addr; if (fd_pipe(fd) < 0) /* create unnamed stream pipe */ return (-1); unlink(name); /* remove the name, if it already exists */ memset(&unix_addr, 0, sizeof(unix_addr)); unix_addr.sun_family = AF_UNIX; strcpy(unix_addr.sun_path, name); len = strlen(unix_addr.sun_path) + sizeof(unix_addr.sun_family); return (bind(fd[0], (struct sockaddr *)&unix_addr, len)); /* fd[0] has the name bound to it */ }
/* evaluate a pipeline (3.9.2) * ----------------------------------------------------------------------- */ int eval_pipeline(struct eval *e, struct npipe *npipe) { struct job *job; union node *node; struct fdstack st; unsigned int n; int pid = 0; int prevfd = -1; int status = -1; /* job = (e->flags & E_JCTL) ? job_new(npipe->ncmd) : NULL;*/ job = job_new(npipe->ncmd); if(job == NULL) { buffer_puts(fd_err->w, "no job control"); buffer_putnlflush(fd_err->w); } for(node = npipe->cmds; node; node = node->list.next) { fdstack_push(&st); /* if there was a previous command we read input from pipe */ if(prevfd >= 0) { struct fd *in; fd_alloca(in); fd_push(in, STDIN_FILENO, FD_READ|FD_PIPE); fd_setfd(in, prevfd); } /* if it isn't the last command we have to create a pipe to pass output to the next command */ if(node->list.next) { struct fd *out; fd_alloca(out); fd_push(out, STDOUT_FILENO, FD_WRITE|FD_PIPE); prevfd = fd_pipe(out); if(prevfd == -1) { close(prevfd); sh_error("pipe creation failed"); } } if((n = fdstack_npipes(FD_HERE|FD_SUBST))) fdstack_pipe(n, fdstack_alloc(n)); pid = job_fork(job, node, npipe->bgnd); if(!pid) { /* no job control for commands inside pipe */ /* e->mode &= E_JCTL;*/ /* exit after evaluating this subtree */ exit(eval_tree(e, node, E_EXIT)); } fdstack_pop(&st); fdstack_data(); } if(!npipe->bgnd) { job_wait(job, 0, &status, 0); } /* if(job) shell_free(job);*/ return WEXITSTATUS(status); }