/* * We cook [[readline]] to print out the line read if it * begins with the string [[;#]]. This string is a * special comment that helps us test the chunks marked * [[]]. * <read.c>= */ char* readline(Reader r, const char *prompt) { if (prompt) print("%s", prompt); r->line++; if (r->fin) /* * Returning the next line from a file requires us to * continually call [[fgets]] until we get a newline * character at the end of the returned string. * <set [[r->buf]] to next line from file, or return [[NULL]] if lines are exhausted>= */ { int n; for (n = 0; n == 0 || r->buf[n-1] != '\n'; n = strlen(r->buf)) { growbuf(r, n+512); if (fgets(r->buf+n, 512, r->fin) == NULL) break; } if (n == 0) return NULL; if (r->buf[n-1] == '\n') r->buf[n-1] = '\0'; } else if (r->s) /* * To return the next line in a string, we need to find * it and update the pointer. * <set [[r->buf]] to next line from string, or return [[NULL]] if lines are exhausted>= */ { const char *p; int len; if ((p = strchr(r->s, '\n')) == NULL) return NULL; p++; len = p - r->s; growbuf(r, len); strncpy(r->buf, r->s, len); r->buf[len-1] = '\0'; /* no newline */ r->s = p; } else assert(0); if (r->buf[0] == ';' && r->buf[1] == '#') print("%s\n", r->buf); return r->buf; }
void insert(Bufblock *buf, int c) { if (buf->current >= buf->end) growbuf(buf); *buf->current++ = c; }
void rinsert(Bufblock *buf, Rune r) { int n; n = runelen(r); if (buf->current+n > buf->end) growbuf(buf); runetochar(buf->current, &r); buf->current += n; }
int execsh(char *args, char *cmd, Bufblock *buf, Envy *e) { int tot, n, tid, pid; HANDLE outin, outout, inout, inin; struct { char *cmd; HANDLE handle; } *arg; if(buf == 0) outout = GetStdHandle(STD_OUTPUT_HANDLE); else if(CreatePipe(&outin, &outout, 0, 0) == FALSE) { perror("pipe"); Exit(); } if(CreatePipe(&inin, &inout, 0, 0) == FALSE) { perror("pipe"); Exit(); } arg = malloc(sizeof(*arg)); arg->cmd = strdup9(cmd); arg->handle = inout; if(CreateThread(0, 0, writecmd, arg, 0, &tid) == FALSE) { perror("spawn writecmd"); Exit(); } pid = spinoff(inin, outout, args, 0, e); CloseHandle(inin); if(DEBUG(D_EXEC)) printf("starting: %s\n", cmd); if(buf) { CloseHandle(outout); tot = 0; for(;;) { if (buf->current >= buf->end) growbuf(buf); if(ReadFile(outin, buf->current, buf->end-buf->current, &n, 0) == FALSE) break; buf->current += n; tot += n; } if (tot && buf->current[-1] == '\n') buf->current--; CloseHandle(outin); } return pid; }
int execsh(char *args, char *cmd, Bufblock *buf, Envy *e) { char *p; int tot, n, pid, in[2], out[2]; if(buf && pipe(out) < 0){ perror("pipe"); Exit(); } pid = rfork(RFPROC|RFFDG|RFENVG); if(pid < 0){ perror("mk rfork"); Exit(); } if(pid == 0){ if(buf) close(out[0]); if(pipe(in) < 0){ perror("pipe"); Exit(); } pid = fork(); if(pid < 0){ perror("mk fork"); Exit(); } if(pid != 0){ dup(in[0], 0); if(buf){ dup(out[1], 1); close(out[1]); } close(in[0]); close(in[1]); if (e) exportenv(e); if(shflags) execl(shell, shellname, shflags, args, nil); else execl(shell, shellname, args, nil); perror(shell); _exits("exec"); } close(out[1]); close(in[0]); p = cmd+strlen(cmd); while(cmd < p){ n = write(in[1], cmd, p-cmd); if(n < 0) break; cmd += n; } close(in[1]); _exits(0); } if(buf){ close(out[1]); tot = 0; for(;;){ if (buf->current >= buf->end) growbuf(buf); n = read(out[0], buf->current, buf->end-buf->current); if(n <= 0) break; buf->current += n; tot += n; } if (tot && buf->current[-1] == '\n') buf->current--; close(out[0]); } return pid; }
int execsh(char *args, char *cmd, Bufblock *buf, Envy *e, Shell *sh, Word *shellcmd) { char *p, **argv; int tot, n, pid, in[2], out[2]; if(buf && pipe(out) < 0){ mkperror("pipe"); Exit(); } pid = fork(); mypid = getpid(); if(pid < 0){ mkperror("mk fork"); Exit(); } if(pid == 0){ if(buf) close(out[0]); if(pipe(in) < 0){ mkperror("pipe"); Exit(); } pid = fork(); if(pid < 0){ mkperror("mk fork"); Exit(); } if(pid != 0){ dup2(in[0], 0); if(buf){ dup2(out[1], 1); close(out[1]); } close(in[0]); close(in[1]); if (e) exportenv(e, sh); n = shargv(shellcmd, 1, &argv); argv[n++] = args; argv[n] = 0; execvp(argv[0], argv); mkperror(shell); _exit(1); } close(out[1]); close(in[0]); if(DEBUG(D_EXEC)) fprint(1, "starting: %s\n", cmd); p = cmd+strlen(cmd); while(cmd < p){ n = write(in[1], cmd, p-cmd); if(n < 0) break; cmd += n; } close(in[1]); _exit(0); } if(buf){ close(out[1]); tot = 0; for(;;){ if (buf->current >= buf->end) growbuf(buf); n = read(out[0], buf->current, buf->end-buf->current); if(n <= 0) break; buf->current += n; tot += n; } if (tot && buf->current[-1] == '\n') buf->current--; close(out[0]); } return pid; }