/*
 * 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;
}
Beispiel #2
0
void
insert(Bufblock *buf, int c)
{

	if (buf->current >= buf->end)
		growbuf(buf);
	*buf->current++ = c;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}