Author Topic: pipelinejs - notes & stuff  (Read 1492 times)

0 Members and 1 Guest are viewing this topic.

adarqui

  • Administrator
  • Hero Member
  • *****
  • Posts: 30416
  • who run it.
  • Respect: +7440
    • View Profile
    • Email
pipelinejs - notes & stuff
« on: April 21, 2013, 09:47:47 am »
0
ok so writing a node.js native binding for pipelining a bunch of processes, shell style.. it can actually get pretty confusing, so, jotting down some notes etc here.. also im reading some other shells now to see how they are pipelining, because I think I designed my pipeline slightly incorrect.. every consecutive pipe is a child of the previous.

adarqui

  • Administrator
  • Hero Member
  • *****
  • Posts: 30416
  • who run it.
  • Respect: +7440
    • View Profile
    • Email
Re: pipelinejs - notes & stuff
« Reply #1 on: April 21, 2013, 09:58:31 am »
0
busybox's shell.c:

evalpipe()

Code: [Select]
/*
 * Evaluate a pipeline.  All the processes in the pipeline are children
 * of the process creating the pipeline.  (This differs from some versions
 * of the shell, which make the last process in a pipeline the parent
 * of all the rest.)
 */
static void
evalpipe(union node *n, int flags)
{
    struct job *jp;
    struct nodelist *lp;
    int pipelen;
    int prevfd;
    int pip[2];

    TRACE(("evalpipe(0x%lx) called\n", (long)n));
    pipelen = 0;
    for (lp = n->npipe.cmdlist; lp; lp = lp->next)
        pipelen++;
    flags |= EV_EXIT;
    INT_OFF;
    jp = makejob(/*n,*/ pipelen);
    prevfd = -1;
    for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
        prehash(lp->n);
        pip[1] = -1;
        if (lp->next) {
            if (pipe(pip) < 0) {
                close(prevfd);
                ash_msg_and_raise_error("pipe call failed");
            }
        if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) {
            INT_ON;
            if (pip[1] >= 0) {
                close(pip[0]);
            }
            if (prevfd > 0) {
                dup2(prevfd, 0);
                close(prevfd);
            }
            if (pip[1] > 1) {
                dup2(pip[1], 1);
                close(pip[1]);
            }
            evaltreenr(lp->n, flags);
            /* never returns */
        }
        if (prevfd >= 0)
            close(prevfd);
        prevfd = pip[0];
        /* Don't want to trigger debugging */
        if (pip[1] != -1)
            close(pip[1]);
    }
    if (n->npipe.pipe_backgnd == 0) {
        exitstatus = waitforjob(jp);
        TRACE(("evalpipe:  job done exit status %d\n", exitstatus));
    }
    INT_ON;
}



forkshell()

Code: [Select]
static int
forkshell(struct job *jp, union node *n, int mode)
{
    int pid;

    TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
    pid = fork();
    if (pid < 0) {
        TRACE(("Fork failed, errno=%d", errno));
        if (jp)
            freejob(jp);
        ash_msg_and_raise_error("can't fork");
    }
    if (pid == 0) {
        CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */
        forkchild(jp, n, mode);
    } else {
        forkparent(jp, n, mode, pid);
    }
    return pid;
}



adarqui

  • Administrator
  • Hero Member
  • *****
  • Posts: 30416
  • who run it.
  • Respect: +7440
    • View Profile
    • Email
Re: pipelinejs - notes & stuff
« Reply #2 on: April 21, 2013, 11:25:14 am »
0
Code: [Select]
    for(x=0;x<10;x++) {
        pipe(pfds);
        xfds[x] = pfds[0];
        xfds[x+1] = pfds[1];

        if(x == 0) {
            close(0);
            dup2(pfds[0], 0);
            close(1);
            dup2(pfds[1], 1);
        }

    }

    write(0, "fuck\n", 5);
    read(xfds[x], buf, sizeof(buf)-1);