Beispiel #1
0
/*
 *  This is the CGI process wrapper.  It will open and redirect stdin
 *  and stdout to stdIn and stdOut.  It converts argv to an argc, argv
 *  pair to pass to the user entry. It initializes the task environment
 *  with envp strings.  Then it will call the user entry.
 */
static void vxWebsCgiEntry(void *entryAddr(int argc, char_t **argv),
				char_t **argp, char_t **envp, char_t *stdIn, char_t *stdOut)
{
	char_t  **p;
	int     argc, taskId, fdin, fdout;

/*
 *  Open the stdIn and stdOut files and redirect stdin and stdout
 *  to them.
 */
	taskId = taskIdSelf();
	if ((fdout = gopen(stdOut, O_RDWR | O_CREAT, 0666)) < 0 &&
			(fdout = creat(stdOut, O_RDWR)) < 0) {
		exit(0);
	}
	ioTaskStdSet(taskId, 1, fdout);

	if ((fdin = gopen(stdIn, O_RDONLY | O_CREAT, 0666)) < 0 &&
			(fdin = creat(stdIn, O_RDWR)) < 0) {
		printf("content-type: text/html\n\n"
				"Can not create CGI stdin to %s\n", stdIn);
		gclose(fdout);
		exit (0);
	}
	ioTaskStdSet(taskId, 0, fdin);

/*
 *  Count the number of entries in argv
 */
	for (argc = 0, p = argp; p != NULL && *p != NULL; p++, argc++) {
	}

/*
 *  Create a private envirnonment and copy the envp strings to it.
 */
	if (envPrivateCreate(taskId, -1) != OK) {
		printf("content-type: text/html\n\n"
			"Can not create CGI environment space\n");
		gclose(fdin);
		gclose(fdout);
		exit (0);
	}
	for (p = envp; p != NULL && *p != NULL; p++) {
		putenv(*p);
	}

/*
 *  Call the user entry.
 */
	(*entryAddr)(argc, argp);

/*
 *  The user code should return here for cleanup.
 */

	envPrivateDestroy(taskId);
	gclose(fdin);
	gclose(fdout);
	exit(0);
}
Beispiel #2
0
/* N.B.!! We do *not* execute in the context of the dying task here,
   but rather that of tExcTask - we do get a pointer to the task's
   TCB though - this pointer is in fact also the task's ID.     */
static void save_reclaim(WIND_TCB *tcbp)
{
  int i, var, oldfd;
  struct task_data *tdp;
  struct mall_data *mdp, *mdnextp;

  if ((var = taskVarGet((int)tcbp, (int *)&task_data)) != ERROR &&
      var != 0) {
    tdp = (struct task_data *)var;
    if (tdp->version == (FUNCPTR)save_reclaim) { /* Only handle our own */
#ifdef DEBUG
      fdprintf(2, "Reclaiming for task id 0x%x:\nFiles: ", (int)tcbp);
#endif
      /* Ugh! VxWorks doesn't even flush stdout/err - we need to
	 get at those (which are task-private of course, i.e. we
	 can't just do fflush(stdout) here) - we could be really
	 pedantic and try to redefine stdout/err (which "are"
	 function calls) too, snarfing the values when they are
	 used - but besides the overhead this is problematic since
	 they are actually #defines already... We'll peek in the
	 TCB instead (no documentation of course). And of course,
	 we must also meddle with the *file descriptor* indirections,
	 or we'll just flush out on tExcTask's descriptors...   */
      for (i = 1; i <= 2; i++) {
	if (tcbp->taskStdFp[i] != NULL) {
#ifdef DEBUG
	  fdprintf(2, "fflush(%s) ", i == 1 ? "stdout" : "stderr");
#endif
	  oldfd = ioTaskStdGet(0, i);
	  ioTaskStdSet(0, i, tcbp->taskStd[i]);
	  fflush(tcbp->taskStdFp[i]);
	  ioTaskStdSet(0, i, oldfd);
	}
      }
      for (i = 3; i < tdp->max_files; i++) {
	if (FD_ISSET(i, &tdp->open_fds)) {
#ifdef DEBUG
	  fdprintf(2, "close(%d) ", i);
#endif
	  (void) close(i);
	}
	if (tdp->open_fps[i] != NULL) {
#ifdef DEBUG
	  fdprintf(2, "fclose(%0x%x) ", (int)tdp->open_fps[i]);
#endif
	  (void) fclose(tdp->open_fps[i]);
	}
      }
      i = 0;
      mdp = tdp->mall_data;
      while (mdp != NULL) {
	mdnextp = mdp->next;
	if(reclaim_free_function != NULL)
	    (*reclaim_free_function)(mdp->self);
	else
	    free(mdp->self);
	i++;
	mdp = mdnextp;
      }
#ifdef DEBUG
      fdprintf(2, "\nFreeing memory: total %d mallocs\n", i);
#endif
      
      if (tdp->delete_hook != NULL) {
#ifdef DEBUG
	  fdprintf(2, "Calling delete hook at 0x%08x\n", tdp->delete_hook);
#endif
	  (*tdp->delete_hook)(tdp->hook_data);
#ifdef DEBUG
	  fdprintf(2, "Called delete hook at 0x%08x\n", tdp->delete_hook);
#endif
      }
#ifdef DEBUG
      fdprintf(2, "Freeing own mem at 0x%08x\n", tdp);
#endif
      (void) free((char *)tdp);
#ifdef DEBUG
      fdprintf(2, "Freed own mem at 0x%08x, done (0x%08x)\n**********\n", tdp,
	       taskIdSelf());
      checkStack(0);
#endif
    }
  }
#ifdef DEBUG
  else
    fdprintf(2, "No task data found for id 0x%x, var = %d\n", (int)tcbp, var);
#endif
}
Beispiel #3
0
/*
    Executed by the child process
 */
static void cmdTaskEntry(char *program, MprCmdTaskFn entry, int cmdArg)
{
    MprCmd          *cmd;
    MprCmdFile      *files;
    WIND_TCB        *tcb;
    char            *item;
    int             inFd, outFd, errFd, id, next;

    cmd = (MprCmd*) cmdArg;

    /*
        Open standard I/O files (in/out are from the server's perspective)
     */
    files = cmd->files;
    inFd = open(files[MPR_CMD_STDIN].name, O_RDONLY, 0666);
    outFd = open(files[MPR_CMD_STDOUT].name, O_WRONLY, 0666);
    errFd = open(files[MPR_CMD_STDERR].name, O_WRONLY, 0666);

    if (inFd < 0 || outFd < 0 || errFd < 0) {
        exit(255);
    }
    id = taskIdSelf();
    ioTaskStdSet(id, 0, inFd);
    ioTaskStdSet(id, 1, outFd);
    ioTaskStdSet(id, 2, errFd);

    /*
        Now that we have opened the stdin and stdout, wakeup our parent.
     */
    semGive(cmd->startCond);

    /*
        Create the environment
     */
    if (envPrivateCreate(id, -1) < 0) {
        exit(254);
    }
    for (ITERATE_ITEMS(cmd->env, item, next)) {
        putenv(item);
    }

#if !VXWORKS
{
    char    *dir;
    int     rc;

    /*
        Set current directory if required
        WARNING: Setting working directory on VxWorks is global
     */
    if (cmd->dir) {
        rc = chdir(cmd->dir);
    } else {
        dir = mprGetPathDir(cmd->program);
        rc = chdir(dir);
    }
    if (rc < 0) {
        mprLog("error mpr cmd", 0, "Cannot change directory to %s", cmd->dir);
        exit(255);
    }
}
#endif

    /*
        Call the user's entry point
     */
    (entry)(cmd->argc, (char**) cmd->argv, (char**) cmd->env);

    tcb = taskTcb(id);
    cmd->status = tcb->exitCode;

    /*
        Cleanup
     */
    envPrivateDestroy(id);
    close(inFd);
    close(outFd);
    close(errFd);
    semGive(cmd->exitCond);
}
static int start_process(Channel * c, char ** envp, char * dir, char * exe, char ** args, int attach,
                int * pid, int * selfattach, ChildProcess ** prs) {
    int err = 0;
    char * ptr;
    SYM_TYPE type;

    if (symFindByName(sysSymTbl, exe, &ptr, &type) != OK) {
        err = errno;
        if (err == S_symLib_SYMBOL_NOT_FOUND) err = ERR_SYM_NOT_FOUND;
        assert(err != 0);
    }
    else {
        int i;
        int pipes[2][2];
        /* TODO: arguments, environment */
        *pid = taskCreate("tTcf", 100, 0, 0x4000, (FUNCPTR)ptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
        for (i = 0; i < 2; i++) {
            char pnm[32];
            char pnm_m[32];
            char pnm_s[32];
            snprintf(pnm, sizeof(pnm), "/pty/tcf-%0*lx-%d", sizeof(*pid) * 2, *pid, i);
            snprintf(pnm_m, sizeof(pnm_m), "%sM", pnm);
            snprintf(pnm_s, sizeof(pnm_m), "%sS", pnm);
            if (ptyDevCreate(pnm, PIPE_SIZE, PIPE_SIZE) == ERROR) {
                err = errno;
                break;
            }
            pipes[i][0] = open(pnm_m, O_RDWR, 0);
            pipes[i][1] = open(pnm_s, O_RDWR, 0);
            if (pipes[i][0] < 0 || pipes[i][1] < 0) {
                err = errno;
                break;
            }
        }
        if (err) {
            taskDelete(*pid);
            *pid = 0;
        }
        else {
            semTake(prs_list_lock, WAIT_FOREVER);
            ioTaskStdSet(*pid, 0, pipes[0][1]);
            ioTaskStdSet(*pid, 1, pipes[0][1]);
            ioTaskStdSet(*pid, 2, pipes[1][1]);
            *prs = loc_alloc_zero(sizeof(ChildProcess));
            (*prs)->inp = pipes[0][0];
            (*prs)->out = pipes[0][0];
            (*prs)->err = pipes[1][0];
            (*prs)->pid = *pid;
            (*prs)->bcg = c->bcg;
            list_add_first(&(*prs)->link, &prs_list);
            if (attach) {
                taskStop(*pid);
                taskActivate(*pid);
                assert(taskIsStopped(*pid));
            }
            else {
                taskActivate(*pid);
            }
            semGive(prs_list_lock);
        }
    }
    if (!err) return 0;
    errno = err;
    return -1;
}
Beispiel #5
0
/*
 *  Executed by the child process
 */
static void cmdTaskEntry(char *program, MprCmdTaskFn entry, int cmdArg)
{
    MprCmd          *cmd;
    MprCmdFile      *files;
    WIND_TCB        *tcb;
    char            **ep, *dir;
    int             inFd, outFd, errFd, id, rc;

    cmd = (MprCmd*) cmdArg;

    /*
     *  Open standard I/O files (in/out are from the server's perspective)
     */
    files = cmd->files;
    inFd = open(files[MPR_CMD_STDIN].name, O_RDONLY, 0666);
    outFd = open(files[MPR_CMD_STDOUT].name, O_WRONLY, 0666);
    errFd = open(files[MPR_CMD_STDERR].name, O_WRONLY, 0666);

    if (inFd < 0 || outFd < 0 || errFd < 0) {
        exit(255);
    }

    id = taskIdSelf();
    ioTaskStdSet(id, 0, inFd);
    ioTaskStdSet(id, 1, outFd);
    ioTaskStdSet(id, 2, errFd);

    /*
     *  Now that we have opened the stdin and stdout, wakeup our parent.
     */
    semGive(cmd->startCond);

    /*
     *  Create the environment
     */
    if (envPrivateCreate(id, -1) < 0) {
        exit(254);
    }
    for (ep = cmd->env; ep && *ep; ep++) {
        putenv(*ep);
    }

    /*
     *  Set current directory if required
     */
    if (cmd->dir) {
        rc = chdir(cmd->dir);
    } else {
        dir = mprGetPathDir(cmd, cmd->program);
        rc = chdir(dir);
        mprFree(dir);
    }
    if (rc < 0) {
        mprLog(cmd, 0, "cmd: Can't change directory to %s", cmd->dir);
        exit(255);
    }

    /*
     *  Call the user's entry point
     */
    (entry)(cmd->argc, cmd->argv, cmd->env);

    tcb = taskTcb(id);
    cmd->status = tcb->exitCode;

    /*
     *  Cleanup
     */
    envPrivateDestroy(id);
    close(inFd);
    close(outFd);
    close(errFd);
    semGive(cmd->exitCond);
}