/* * 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); }
static os_result os_procWrapper( os_procContextData process_procContextData, char *executable_file, os_int32 *startRoutine, const char *arguments, TASK_ID parent, os_sem_t *blockParent) { int taskid; os_int32 status = os_resultSuccess; os_int32 routine_status = -1; os_int32 (*this_startRoutine)(const char *); #if ( _WRS_VXWORKS_MAJOR > 6 ) || ( _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR > 8 ) envPrivateCreate(taskIdSelf(), parent); os_sem_post(blockParent); #endif taskid = taskIdSelf(); os_procSetTaskId(process_procContextData, taskid); /* create & set context variable for the task */ status = os_procAddTaskVar(taskid, executable_file, process_procContextData, 0); if (status == os_resultSuccess) { status = os_threadNew(process_procContextData->procName); } if (status == os_resultSuccess) { this_startRoutine = (os_int32 *)startRoutine; routine_status = this_startRoutine(arguments); os_procLocalExit(OS_EXIT_SUCCESS); os_threadDeleteTaskVar(taskid, os_threadIdSelf()); os_procDeleteTaskVar(taskid, executable_file, process_procContextData); os_procSetExitValue(process_procContextData, routine_status); } #if ( _WRS_VXWORKS_MAJOR > 6 ) || ( _WRS_VXWORKS_MAJOR > 6 && _WRS_VXWORKS_MINOR > 8 ) envPrivateDestroy(taskIdSelf()); #endif return (status); }
/* 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); }
os_result os_procCreate( const char *executable_file, const char *name, const char *arguments, os_procAttr *procAttr, os_procId *procId) { int procTaskId; int sched_policy; os_result rv = os_resultSuccess; os_procContextData process_procContextData; os_int32 startRoutine = 0; os_int32 pOptions,privateSet; os_int32 len,i=0,n=0; char *converted = NULL; assert(executable_file != NULL); assert(name != NULL); assert(arguments != NULL); assert(procAttr != NULL); assert(procId != NULL); len = strlen(arguments); converted = (char*)os_malloc(len+1); for (; i < len ; i++) { if (arguments[i] != '\"') { converted[n] = arguments[i]; n++; } } converted[n] = '\0'; pOptions = 0; privateSet = 0; taskOptionsGet(taskIdSelf(),&pOptions); if ((pOptions & VX_PRIVATE_ENV) == 0) { envPrivateCreate(taskIdSelf(), 0); privateSet = 1; } putenv("SPLICE_NEW_PROCESS=no"); if (procAttr->schedClass == OS_SCHED_REALTIME) { sched_policy = SCHED_FIFO; } else if (procAttr->schedClass == OS_SCHED_TIMESHARE) { return os_resultInvalid; } else if (procAttr->schedClass == OS_SCHED_DEFAULT) { sched_policy = SCHED_OTHER; } else { return os_resultInvalid; } if ((procAttr->schedPriority > VXWORKS_PRIORITY_MIN) || (procAttr->schedPriority < VXWORKS_PRIORITY_MAX) ) { return os_resultInvalid; } { os_library binlib; os_libraryAttr attr; os_libraryAttrInit(&attr); /* Dynamic load of services is a special case, so try just static via os_libraryOpen */ attr.staticLibOnly=1; binlib = os_libraryOpen( executable_file, &attr); /* FIXME existing use of os_int32 for pointer is CRAZY!! */ if ( binlib != NULL ) { startRoutine = (os_int32)os_libraryGetSymbol( binlib, executable_file ); } if ( startRoutine == 0 && os_dynamicLibPlugin != NULL ) { startRoutine = (os_uint32)os_dynamicLibPlugin->dlp_loadLib( executable_file ); } if ( startRoutine == 0 ) { OS_REPORT(OS_ERROR, "os_procCreate", 1, "Unable to load %s (%s)", executable_file, name); rv = os_resultInvalid; } } if (rv == os_resultSuccess) { process_procContextData = (os_procContextData )os_malloc((size_t)OS_SIZEOF(os_procContextData)); if (process_procContextData == (os_procContextData) NULL) { OS_REPORT(OS_WARNING, "os_procCreate", 1, "malloc failed with error %d (%s, %s)", os_getErrno(), executable_file, name); rv = os_resultInvalid; } else { #if defined ( _WRS_VXWORKS_MAJOR ) && ( _WRS_VXWORKS_MAJOR > 6 ) || ( _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR > 8 ) /* the blockParent semaphore is used to prevent this task exiting before the spawned task has completed copying its environ. */ os_sem_t blockParent; os_sem_init( &blockParent, 0); #endif os_procInit(process_procContextData, name, executable_file, converted); process_procContextData->procAttrPrio = procAttr->schedPriority; procTaskId = taskSpawn((char *)name, procAttr->schedPriority, VX_FP_TASK #if ! defined ( _WRS_VXWORKS_MAJOR ) || _WRS_VXWORKS_MAJOR < 6 || ( _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR < 9 ) /* VX_PRIVATE_ENV flag is no longer functional in vxworks 6.9 */ | VX_PRIVATE_ENV #endif #if defined ( VXWORKS_55 ) || defined ( VXWORKS_54 ) | VX_STDIO | VX_DEALLOC_STACK #endif , VXWORKS_PROC_DEFAULT_STACK, (FUNCPTR)os_procWrapper, (int)process_procContextData, (int)process_procContextData->executable, (int)startRoutine, (int)process_procContextData->arguments, taskIdSelf(), #if ! defined ( _WRS_VXWORKS_MAJOR ) || _WRS_VXWORKS_MAJOR < 6 || ( _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR < 9 ) 0, #else &blockParent, #endif 0, 0, 0, 0); #if defined ( _WRS_VXWORKS_MAJOR ) && ( _WRS_VXWORKS_MAJOR > 6 || ( _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR > 8 ) ) os_sem_wait(&blockParent); os_sem_destroy(&blockParent); #endif if (procTaskId == ERROR) { os_free(process_procContextData); rv = os_resultInvalid; } else { *procId = *(os_procId *)&process_procContextData; rv = os_resultSuccess; } } } putenv("SPLICE_NEW_PROCESS=empty"); if ( privateSet == 1) { envPrivateDestroy(taskIdSelf()); } os_free(converted); return rv; }
/* * 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); }