Example #1
0
File: cmd.c Project: embedthis/mpr
/*
    Start the command to run (stdIn and stdOut are named from the client's perspective)
 */
PUBLIC int startProcess(MprCmd *cmd)
{
    MprCmdTaskFn    entryFn;
    MprModule       *mp;
    char            *entryPoint, *program, *pair;
    int             pri, next;

    mprLog("info mpr cmd", 4, "Program %s", cmd->program);
    entryPoint = 0;
    if (cmd->env) {
        for (ITERATE_ITEMS(cmd->env, pair, next)) {
            if (sncmp(pair, "entryPoint=", 11) == 0) {
                entryPoint = sclone(&pair[11]);
            }
        }
    }
    program = mprGetPathBase(cmd->program);
    if (entryPoint == 0) {
        program = mprTrimPathExt(program);
        entryPoint = program;
    }
#if ME_CPU_ARCH == MPR_CPU_IX86 || ME_CPU_ARCH == MPR_CPU_IX64 || ME_CPU_ARCH == MPR_CPU_SH
    /*
        A leading underscore is required on some architectures
     */
    entryPoint = sjoin("_", entryPoint, NULL);
#endif
    if (mprFindVxSym(sysSymTbl, entryPoint, (char**) (void*) &entryFn) < 0) {
        if ((mp = mprCreateModule(cmd->program, cmd->program, NULL, NULL)) == 0) {
            mprLog("error mpr cmd", 0, "Cannot create module");
            return MPR_ERR_CANT_CREATE;
        }
        if (mprLoadModule(mp) < 0) {
            mprLog("error mpr cmd", 0, "Cannot load DLL %s, errno %d", program, mprGetOsError());
            return MPR_ERR_CANT_READ;
        }
        if (mprFindVxSym(sysSymTbl, entryPoint, (char**) (void*) &entryFn) < 0) {
            mprLog("error mpr cmd", 0, "Cannot find symbol %s, errno %d", entryPoint, mprGetOsError());
            return MPR_ERR_CANT_ACCESS;
        }
    }
    taskPriorityGet(taskIdSelf(), &pri);

    cmd->pid = taskSpawn(entryPoint, pri, VX_FP_TASK | VX_PRIVATE_ENV, ME_STACK_SIZE, (FUNCPTR) cmdTaskEntry,
        (int) cmd->program, (int) entryFn, (int) cmd, 0, 0, 0, 0, 0, 0, 0);

    if (cmd->pid < 0) {
        mprLog("error mpr cmd", 0, "Cannot create task %s, errno %d", entryPoint, mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    if (semTake(cmd->startCond, MPR_TIMEOUT_START_TASK) != OK) {
        mprLog("error mpr cmd", 0, "Child %s did not initialize, errno %d", cmd->program, mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    semDelete(cmd->startCond);
    cmd->startCond = 0;
    return 0;
}
Example #2
0
static void netOutgoingService(MaQueue *q)
{
    MaConn      *conn;
    MaResponse  *resp;
    int         written, errCode;

    conn = q->conn;
    resp = conn->response;
    
    while (q->first || q->ioIndex) {
        written = 0;
        if (q->ioIndex == 0 && buildNetVec(q) <= 0) {
            break;
        }
        /*
         *  Issue a single I/O request to write all the blocks in the I/O vector
         */
        errCode = mprGetOsError();
        mprAssert(q->ioIndex > 0);
        written = mprWriteSocketVector(conn->sock, q->iovec, q->ioIndex);
        mprLog(q, 5, "Net connector written %d", written);
        if (written < 0) {
            errCode = mprGetOsError();
            if (errCode == EAGAIN || errCode == EWOULDBLOCK) {
                maRequestWriteBlocked(conn);
                break;
            }
            if (errCode == EPIPE || errCode == ECONNRESET) {
                maDisconnectConn(conn);
            } else {
                mprLog(conn, 7, "mprVectorWriteSocket failed, error %d", errCode);
                maDisconnectConn(conn);
            }
            freeNetPackets(q, MAXINT);
            break;

        } else if (written == 0) {
            /* 
             * Socket full. Wait for an I/O event. Conn.c will setup listening for write events if the queue is non-empty
             */
            maRequestWriteBlocked(conn);
            break;

        } else if (written > 0) {
            resp->bytesWritten += written;
            freeNetPackets(q, written);
            adjustNetVec(q, written);
        }
    }
    if (q->ioCount == 0 && q->flags & MA_QUEUE_EOF) {
        maCompleteRequest(conn);
    }
}
Example #3
0
static int makeChannel(MprCmd *cmd, int index)
{
    SECURITY_ATTRIBUTES clientAtt, serverAtt, *att;
    HANDLE              readHandle, writeHandle;
    MprCmdFile          *file;
    char                *path;
    int                 readFd, writeFd;

    memset(&clientAtt, 0, sizeof(clientAtt));
    clientAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
    clientAtt.bInheritHandle = 1;

    /*
     *  Server fds are not inherited by the child
     */
    memset(&serverAtt, 0, sizeof(serverAtt));
    serverAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
    serverAtt.bInheritHandle = 0;

    file = &cmd->files[index];
    path = mprGetTempPath(cmd, NULL);

    att = (index == MPR_CMD_STDIN) ? &clientAtt : &serverAtt;
    readHandle = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, att, OPEN_ALWAYS, 
        FILE_ATTRIBUTE_NORMAL,0);
    if (readHandle == INVALID_HANDLE_VALUE) {
        mprError(cmd, "Can't create stdio pipes %s. Err %d\n", path, mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    readFd = (int) (int64) _open_osfhandle((int*) readHandle, 0);

    att = (index == MPR_CMD_STDIN) ? &serverAtt: &clientAtt;
    writeHandle = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, att, OPEN_ALWAYS, 
        FILE_ATTRIBUTE_NORMAL, 0);
    writeFd = (int) _open_osfhandle((int*) writeHandle, 0);

    if (readFd < 0 || writeFd < 0) {
        mprError(cmd, "Can't create stdio pipes %s. Err %d\n", path, mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    if (index == MPR_CMD_STDIN) {
        file->clientFd = readFd;
        file->fd = writeFd;
        file->handle = writeHandle;
    } else {
        file->clientFd = writeFd;
        file->fd = readFd;
        file->handle = readHandle;
    }
    mprFree(path);
    return 0;
}
Example #4
0
/*
    Signals are hooked on demand and remain till the Mpr is destroyed
 */
static void hookSignal(int signo, MprSignal *sp)
{
    MprSignalService    *ssp;
    struct sigaction    act, old;
    int                 rc;

    mprAssert(0 < signo && signo < MPR_MAX_SIGNALS);

    ssp = MPR->signalService;
    lock(ssp);
    rc = sigaction(signo, 0, &old);
    if (rc == 0 && old.sa_sigaction != signalHandler) {
        sp->sigaction = old.sa_sigaction;
        ssp->prior[signo] = old;
        memset(&act, 0, sizeof(act));
        act.sa_sigaction = signalHandler;
        act.sa_flags |= SA_SIGINFO | SA_RESTART | SA_NOCLDSTOP;
        act.sa_flags &= ~SA_NODEFER;
        sigemptyset(&act.sa_mask);
        if (sigaction(signo, &act, 0) != 0) {
            mprError("Can't hook signal %d, errno %d", signo, mprGetOsError());
        }
    }
    unlock(ssp);
}
Example #5
0
/*
    Wait for I/O on all registered file descriptors. Timeout is in milliseconds. Return the number of events detected.
 */
PUBLIC void mprWaitForIO(MprWaitService *ws, MprTicks timeout)
{
    struct epoll_event  events[ME_MAX_EVENTS];
    int                 nevents;

    if (timeout < 0 || timeout > MAXINT) {
        timeout = MAXINT;
    }
#if ME_DEBUG
    if (mprGetDebugMode() && timeout > 30000) {
        timeout = 30000;
    }
#endif
    if (ws->needRecall) {
        mprDoWaitRecall(ws);
        return;
    }
    mprYield(MPR_YIELD_STICKY);

    if ((nevents = epoll_wait(ws->epoll, events, sizeof(events) / sizeof(struct epoll_event), timeout)) < 0) {
        if (errno != EINTR) {
            mprLog("error mpr event", 0, "epoll returned %d, errno %d", nevents, mprGetOsError());
        }
    }
    mprClearWaiting();
    mprResetYield();

    if (nevents > 0) {
        serviceIO(ws, events, nevents);
    }
    ws->wakeRequested = 0;
}
Example #6
0
//
//	This code has been debugged but requires changes to other portions of the
//	code to enable. Specifically, the cgiHandler.cpp.
//
int MprCmd::makeStdio()
{
	int		fds[2], i;

	resetFiles();

	for (i = 0; i < MPR_CMD_MAX_FD; i++) {
		if (pipe(fds) < 0) {
			mprError(MPR_L, MPR_LOG, "Can't create stdio pipes. Err %d",
				mprGetOsError());
			mprAssert(0);
			return -1;
		}
		if (i == MPR_CMD_OUT) {
			files.clientFd[i] = fds[0];			// read fd
			files.fd[i] = fds[1];				// write fd
		} else {
			files.clientFd[i] = fds[1];			// write fd
			files.fd[i] = fds[0];				// read fd
		}
		mprLog(7, log, "makeStdio: pipe handles[%d] read %d, write %d\n",
			i, fds[0], fds[1]);
	}

	return 0;
}
Example #7
0
File: cmd.c Project: embedthis/mpr
static int makeChannel(MprCmd *cmd, int index)
{
    MprCmdFile      *file;
    int             nonBlock;
    static int      tempSeed = 0;

    file = &cmd->files[index];
    file->name = sfmt("/pipe/%s_%d_%d", ME_NAME, taskIdSelf(), tempSeed++);

    if (pipeDevCreate(file->name, 6, ME_BUFSIZE) < 0) {
        mprLog("error mpr cmd", 0, "Cannot create pipes to run %s", cmd->program);
        return MPR_ERR_CANT_OPEN;
    }
    /*
        Open the server end of the pipe. MPR_CMD_STDIN is from the client's perspective.
     */
    if (index == MPR_CMD_STDIN) {
        file->fd = open(file->name, O_WRONLY, 0644);
    } else {
        file->fd = open(file->name, O_RDONLY, 0644);
    }
    if (file->fd < 0) {
        mprLog("error mpr cmd", 0, "Cannot create stdio pipes. Err %d", mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    nonBlock = 1;
    ioctl(file->fd, FIONBIO, (int) &nonBlock);
    return 0;
}
Example #8
0
static int makeChannel(MprCmd *cmd, int index)
{
    MprCmdFile      *file;
    static int      tempSeed = 0;

    file = &cmd->files[index];

    file->name = mprAsprintf(cmd, -1, "/pipe/%s_%d_%d", BLD_PRODUCT, taskIdSelf(), tempSeed++);

    if (pipeDevCreate(file->name, 5, MPR_BUFSIZE) < 0) {
        mprError(cmd, "Can't create pipes to run %s", cmd->program);
        return MPR_ERR_CANT_OPEN;
    }
    
    /*
     *  Open the server end of the pipe. MPR_CMD_STDIN is from the client's perspective.
     */
    if (index == MPR_CMD_STDIN) {
        file->fd = open(file->name, O_WRONLY, 0644);
    } else {
        file->fd = open(file->name, O_RDONLY, 0644);
    }
    if (file->fd < 0) {
        mprError(cmd, "Can't create stdio pipes. Err %d", mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    return 0;
}
Example #9
0
File: os.cpp Project: OPSF/uClinux
int mprGetRandomBytes(uchar *buf, int length, int block)
{
    HCRYPTPROV 		prov;
	int				rc;

	rc = 0;

    if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 
			CRYPT_VERIFYCONTEXT | 0x40)) {
		return -mprGetOsError();
    }
    if (!CryptGenRandom(prov, length, buf)) {
    	rc = -mprGetOsError();
    }
    CryptReleaseContext(prov, 0);
    return rc;
}
Example #10
0
File: cmd.c Project: embedthis/mpr
static int startProcess(MprCmd *cmd)
{
    PROCESS_INFORMATION procInfo;
    STARTUPINFO         startInfo;
    cchar               *envBlock;
    int                 err;

    memset(&startInfo, 0, sizeof(startInfo));
    startInfo.cb = sizeof(startInfo);

    startInfo.dwFlags = STARTF_USESHOWWINDOW;
    if (cmd->flags & MPR_CMD_SHOW) {
        startInfo.wShowWindow = SW_SHOW;
    } else {
        startInfo.wShowWindow = SW_HIDE;
    }
    startInfo.dwFlags |= STARTF_USESTDHANDLES;

    if (cmd->flags & MPR_CMD_IN) {
        if (cmd->files[MPR_CMD_STDIN].clientFd > 0) {
            startInfo.hStdInput = (HANDLE) _get_osfhandle(cmd->files[MPR_CMD_STDIN].clientFd);
        }
    } else {
        startInfo.hStdInput = (HANDLE) _get_osfhandle((int) fileno(stdin));
    }
    if (cmd->flags & MPR_CMD_OUT) {
        if (cmd->files[MPR_CMD_STDOUT].clientFd > 0) {
            startInfo.hStdOutput = (HANDLE) _get_osfhandle(cmd->files[MPR_CMD_STDOUT].clientFd);
        }
    } else {
        startInfo.hStdOutput = (HANDLE) _get_osfhandle((int) fileno(stdout));
    }
    if (cmd->flags & MPR_CMD_ERR) {
        if (cmd->files[MPR_CMD_STDERR].clientFd > 0) {
            startInfo.hStdError = (HANDLE) _get_osfhandle(cmd->files[MPR_CMD_STDERR].clientFd);
        }
    } else {
        startInfo.hStdError = (HANDLE) _get_osfhandle((int) fileno(stderr));
    }
    envBlock = makeWinEnvBlock(cmd);
    if (! CreateProcess(0, wide(cmd->command), 0, 0, 1, 0, (char*) envBlock, wide(cmd->dir), &startInfo, &procInfo)) {
        err = mprGetOsError();
        if (err == ERROR_DIRECTORY) {
            mprLog("error mpr cmd", 0, "Cannot create process: %s, directory %s is invalid", cmd->program, cmd->dir);
        } else {
            mprLog("error mpr cmd", 0, "Cannot create process: %s, %d", cmd->program, err);
        }
        return MPR_ERR_CANT_CREATE;
    }
    cmd->thread = procInfo.hThread;
    cmd->process = procInfo.hProcess;
    cmd->pid = procInfo.dwProcessId;
    return 0;
}
Example #11
0
int Mpr::loadDll(char *path, char *fnName, void *arg, void **handlePtr)
{
	MprDllEntryProc	fn;
	char			localPath[MPR_MAX_FNAME], dir[MPR_MAX_FNAME];
    void			*handle;
	char			*cp;
	int				rc;

	mprAssert(path && *path);
	mprAssert(fnName && *fnName);

	mprGetDirName(dir, sizeof(dir), path);
	mprSetModuleSearchPath(dir);

	mprStrcpy(localPath, sizeof(localPath), path);
	//	TODO - good to have a x-platform method for this.
	for (cp = localPath; *cp; cp++) {
		if (*cp == '/') {
			*cp = '\\';
		}
	}

    if ((handle = GetModuleHandle(mprGetBaseName(localPath))) == 0) {
		if ((handle = LoadLibraryEx(localPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
			char cwd[1024], *env;
			getcwd(cwd, sizeof(cwd) - 1);
			env = getenv("PATH");
			mprLog(0, "ERROR %d\n", GetLastError());
			mprLog(0, "Can't load %s\nReason: \"%d\"\n", path, mprGetOsError());
			mprLog(0, "CWD %s\n PATH %s\n", cwd, env);
			return MPR_ERR_CANT_OPEN;
		}
    }

	fn = (MprDllEntryProc) GetProcAddress((HINSTANCE) handle, fnName);
	if (fn == 0) {
		FreeLibrary((HINSTANCE) handle);
		mprLog(0, "Can't load %s\nReason: can't find function \"%s\"\n", 
			localPath, fnName);
		return MPR_ERR_NOT_FOUND;
	}
	mprLog(MPR_INFO, "Loading DLL %s\n", path);

	if ((rc = (fn)(arg)) < 0) {
		FreeLibrary((HINSTANCE) handle);
		mprError(MPR_L, MPR_LOG, "Initialization for %s failed.", path);
		return MPR_ERR_CANT_INITIALIZE;
	}
	if (handlePtr) {
		*handlePtr = handle;
	}
	return rc;
}
Example #12
0
PUBLIC int mprLoadNativeModule(MprModule *mp)
{
    MprModuleEntry  fn;
    void            *handle;

    assert(mp);

    if ((handle = (HANDLE) MPR->appInstance) == 0) {
        handle = GetModuleHandle(NULL);
    }
    if (!handle || !mp->entry || !GetProcAddress(handle, mp->entry)) {
#if ME_STATIC
        mprLog("error mpr", 0, "Cannot load module %s, product built static", mp->name);
        return MPR_ERR_BAD_STATE;
#else
        MprPath info;
        char    *at, *baseName;
        if ((at = mprSearchForModule(mp->path)) == 0) {
            mprLog("error mpr", 0, "Cannot find module \"%s\", cwd=\"%s\", search=\"%s\"", mp->path, mprGetCurrentPath(),
                mprGetModuleSearchPath());
            return MPR_ERR_CANT_ACCESS;
        }
        mp->path = at;
        mprGetPathInfo(mp->path, &info);
        mp->modified = info.mtime;
        baseName = mprGetPathBase(mp->path);
        mprLog("info mpr", 4, "Loading native module %s", baseName);
        if ((handle = LoadLibrary(wide(mp->path))) == 0) {
            mprLog("error mpr", 0, "Cannot load module %s, errno=\"%d\"", mp->path, mprGetOsError());
            return MPR_ERR_CANT_READ;
        }
        mp->handle = handle;
#endif /* !ME_STATIC */

    } else if (mp->entry) {
        mprLog("info mpr", 4, "Activating native module %s", mp->name);
    }
    if (mp->entry) {
        if ((fn = (MprModuleEntry) GetProcAddress((HINSTANCE) handle, mp->entry)) == 0) {
            mprLog("error mpr", 0, "Cannot load module %s, cannot find function \"%s\"", mp->name, mp->entry);
            FreeLibrary((HINSTANCE) handle);
            return MPR_ERR_CANT_ACCESS;
        }
        if ((fn)(mp->moduleData, mp) < 0) {
            mprLog("error mpr", 0, "Initialization for module %s failed", mp->name);
            FreeLibrary((HINSTANCE) handle);
            return MPR_ERR_CANT_INITIALIZE;
        }
    }
    return 0;
}
Example #13
0
/*
 *  Start the user's default browser
 */
static int runBrowser(char *page)
{
    PROCESS_INFORMATION procInfo;
    STARTUPINFO         startInfo;
    char                cmdBuf[MPR_MAX_STRING];
    char                *path;
    char                *pathArg;
    int                 port;

    port = getAppwebPort();
    if (port < 0) {
        mprError(mpr, "Can't get Appweb listening port");
        return -1;
    }

    path = getBrowserPath(MPR_MAX_STRING);
    if (path == 0) {
        mprError(mpr, "Can't get browser startup command");
        return -1;
    }

    pathArg = strstr(path, "\"%1\"");
    if (*page == '/') {
        page++;
    }

    if (pathArg == 0) {
        mprSprintf(cmdBuf, MPR_MAX_STRING, "%s http://localhost:%d/%s", path, port, page);

    } else {
        /*
         *  Patch out the "%1"
         */
        *pathArg = '\0';
        mprSprintf(cmdBuf, MPR_MAX_STRING, "%s \"http://localhost:%d/%s\"", path, port, page);
    }

    mprLog(mpr, 4, "Running %s\n", cmdBuf);

    memset(&startInfo, 0, sizeof(startInfo));
    startInfo.cb = sizeof(startInfo);

    if (! CreateProcess(0, cmdBuf, 0, 0, FALSE, 0, 0, 0, &startInfo, &procInfo)) {
        mprError(mpr, "Can't create process: %s, %d", cmdBuf, mprGetOsError());
        return -1;
    }
    CloseHandle(procInfo.hProcess);

    mprFree(path);
    return 0;
}
Example #14
0
static void unhookSignal(int signo)
{
    MprSignalService    *ssp;
    struct sigaction    act;
    int                 rc;

    ssp = MPR->signalService;
    lock(ssp);
    rc = sigaction(signo, 0, &act);
    if (rc == 0 && act.sa_sigaction == signalHandler) {
        if (sigaction(signo, &ssp->prior[signo], 0) != 0) {
            mprError("Can't unhook signal %d, errno %d", signo, mprGetOsError());
        }
    }
    unlock(ssp);
}
Example #15
0
MprModule *mprLoadModule(MprCtx ctx, cchar *moduleName, cchar *initFunction)
{
    MprModule       *mp;
    MprModuleEntry  fn;
    char            *module;
    char            *path, *name;
    void            *handle;

    mprAssert(moduleName && *moduleName);

    mp = 0;
    name = path = 0;
    module = mprGetNormalizedPath(ctx, moduleName);

    if (mprSearchForModule(ctx, module, &path) < 0) {
        mprError(ctx, "Can't find module \"%s\" in search path \"%s\"", moduleName, mprGetModuleSearchPath(ctx));

    } else {
        name = mprGetPathBase(ctx, module);
        mprLog(ctx, MPR_INFO, "Loading module %s from %s", name, path);

        if ((handle = GetModuleHandle(name)) == 0 && (handle = LoadLibrary(path)) == 0) {
            mprError(ctx, "Can't load module %s\nReason: \"%d\"\n",  path, mprGetOsError());

        } else if (initFunction) {
            if ((fn = (MprModuleEntry) GetProcAddress((HINSTANCE) handle, initFunction)) != 0) {
                if ((mp = (fn)(ctx, path)) == 0) {
                    mprError(ctx, "Initialization for module %s failed", name);
                    FreeLibrary((HINSTANCE) handle);

                } else {
                    mp->handle = handle;
                }

            } else {
                mprError(ctx, "Can't load module %s\nReason: can't find function \"%s\"\n",  name, initFunction);
                FreeLibrary((HINSTANCE) handle);

            }
        }
    }
    mprFree(name);
    mprFree(path);
    mprFree(module);
    return mp;
}
Example #16
0
/*
    Start the user's default browser
 */
static int runBrowser(char *page)
{
    PROCESS_INFORMATION procInfo;
    STARTUPINFO         startInfo;
    char                cmdBuf[ME_MAX_BUFFER];
    char                *path;
    char                *pathArg;
    int                 port;

    port = getAppwebPort();
    if (port < 0) {
        mprError("appweb monitor", "Cannot get Appweb listening port");
        return -1;
    }
    path = getBrowserPath(ME_MAX_BUFFER);
    if (path == 0) {
        mprError("appweb monitor", "Cannot get browser startup command");
        return -1;
    }
    pathArg = strstr(path, "\"%1\"");
    if (*page == '/') {
        page++;
    }
    if (sstarts(page, "http")) {
        fmt(cmdBuf, ME_MAX_BUFFER, "%s %s", path, page);
    } else if (pathArg == 0) {
        fmt(cmdBuf, ME_MAX_BUFFER, "%s http://localhost:%d/%s", path, port, page);
    } else {
        *pathArg = '\0';
        fmt(cmdBuf, ME_MAX_BUFFER, "%s \"http://localhost:%d/%s\"", path, port, page);
    }
    mprLog("appweb monitor", 4, "Running %s\n", cmdBuf);
    memset(&startInfo, 0, sizeof(startInfo));
    startInfo.cb = sizeof(startInfo);

    if (! CreateProcess(0, cmdBuf, 0, 0, FALSE, 0, 0, 0, &startInfo, &procInfo)) {
        mprError("appweb monitor", "Cannot create process: %s, %d", cmdBuf, mprGetOsError());
        return -1;
    }
    CloseHandle(procInfo.hProcess);
    return 0;
}
Example #17
0
static void writeToCGI(MaQueue *q)
{
    MaConn      *conn;
    MaPacket    *packet;
    MprCmd      *cmd;
    MprBuf      *buf;
    int         len, rc, err;

    cmd = (MprCmd*) q->pair->queueData;
    mprAssert(cmd);
    conn = q->conn;

    for (packet = maGet(q); packet && !conn->requestFailed; packet = maGet(q)) {
        buf = packet->content;
        len = mprGetBufLength(buf);
        mprAssert(len > 0);
        rc = mprWriteCmdPipe(cmd, MPR_CMD_STDIN, mprGetBufStart(buf), len);
        mprLog(q, 5, "CGI: write %d bytes to gateway. Rc rc %d, errno %d", len, rc, mprGetOsError());
        if (rc < 0) {
            err = mprGetError();
            if (err == EINTR) {
                continue;
            } else if (err == EAGAIN || err == EWOULDBLOCK) {
                break;
            }
            mprLog(q, 2, "CGI: write to gateway failed for %d bytes, rc %d, errno %d", len, rc, mprGetOsError());
            mprCloseCmdFd(cmd, MPR_CMD_STDIN);
            maFailRequest(conn, MPR_HTTP_CODE_BAD_GATEWAY, "Can't write body data to CGI gateway");
            break;

        } else {
            mprLog(q, 5, "CGI: write to gateway %d bytes asked to write %d", rc, len);
            mprAdjustBufStart(buf, rc);
            if (mprGetBufLength(buf) > 0) {
                maPutBack(q, packet);
            } else {
                maFreePacket(q, packet);
            }
        }
    }
}
Example #18
0
static int makeChannel(MprCmd *cmd, int index)
{
    MprCmdFile      *file;
    int             fds[2];

    file = &cmd->files[index];

    if (pipe(fds) < 0) {
        mprError(cmd, "Can't create stdio pipes. Err %d", mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    if (index == MPR_CMD_STDIN) {
        file->clientFd = fds[0];        /* read fd */
        file->fd = fds[1];              /* write fd */
    } else {
        file->clientFd = fds[1];        /* write fd */
        file->fd = fds[0];              /* read fd */
    }
    mprLog(cmd, 7, "mprMakeCmdIO: pipe handles[%d] read %d, write %d", index, fds[0], fds[1]);
    return 0;
}
Example #19
0
File: cmd.c Project: embedthis/mpr
static int makeChannel(MprCmd *cmd, int index)
{
    MprCmdFile      *file;
    int             fds[2];

    file = &cmd->files[index];

    if (pipe(fds) < 0) {
        mprLog("error mpr cmd", 0, "Cannot create stdio pipes. Err %d", mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    if (index == MPR_CMD_STDIN) {
        file->clientFd = fds[0];        /* read fd */
        file->fd = fds[1];              /* write fd */
    } else {
        file->clientFd = fds[1];        /* write fd */
        file->fd = fds[0];              /* read fd */
    }
    fcntl(file->fd, F_SETFL, fcntl(file->fd, F_GETFL) | O_NONBLOCK);
    return 0;
}
Example #20
0
File: os.cpp Project: OPSF/uClinux
int Mpr::loadDll(char *path, char *fnName, void *arg, void **handlePtr)
{
	MprEntryProc	fn;
	char			localPath[MPR_MAX_FNAME];
    void			*handle;
	char			*cp;
	int				rc;

	mprAssert(path && *path);
	mprAssert(fnName && *fnName);

	mprStrcpy(localPath, sizeof(localPath), path);
	for (cp = localPath; *cp; cp++) {
		if (*cp == '/') {
			*cp = '\\';
		}
	}
    if ((handle = GetModuleHandle(mprGetBaseName(localPath))) == 0) {
		if ((handle = LoadLibrary(localPath)) == 0) {
			mprLog(0, "Can't load %s\nReason: \"%d\"\n", path, mprGetOsError());
			return MPR_ERR_CANT_OPEN;
		}
    }

	if ((fn = (MprEntryProc) GetProcAddress((HINSTANCE) handle, fnName)) == 0) {
		FreeLibrary((HINSTANCE) handle);
		mprLog(0, "Can't load %s\nReason: can't find function \"%s\"\n", 
			localPath, fnName);
		return MPR_ERR_NOT_FOUND;
	}
	if ((rc = (fn)(arg)) < 0) {
		FreeLibrary((HINSTANCE) handle);
		return MPR_ERR_CANT_INITIALIZE;
	}
	mprLog(MPR_INFO, "Loading DLL %s\n", path);
	if (handlePtr) {
		*handlePtr = handle;
	}
	return rc;
}
Example #21
0
static EjsObj *saveXml(Ejs *ejs, EjsXML *xml, int argc, EjsObj **argv)
{
    MprBuf      *buf;
    MprFile     *file;
    char        *filename;
    ssize       bytes, len;

    if (argc != 1 || !ejsIs(ejs, argv[0], String)) {
        ejsThrowArgError(ejs, "Bad args. Usage: save(filename);");
        return 0;
    }
    filename = awtom(((EjsString*) argv[0])->value, NULL);

    /*
        Create a buffer to hold the output. All in memory.
     */
    buf = mprCreateBuf(ME_MAX_BUFFER, -1);
    mprPutStringToBuf(buf, "<?xml version=\"1.0\"?>\n");

    if (ejsXMLToBuf(ejs, buf, xml, 0) < 0) {
        return 0;
    }
    file = mprOpenFile(filename,  O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0664);
    if (file == 0) {
        ejsThrowIOError(ejs, "Cannot open: %s, %d", filename, mprGetOsError(ejs));
        return 0;
    }
    len = mprGetBufLength(buf);
    bytes = mprWriteFile(file, buf->start, len);
    if (bytes != len) {
        ejsThrowIOError(ejs, "Cannot write to: %s", filename);
        mprCloseFile(file);
        return 0;
    }
    mprWriteFile(file, "\n", 1);
    mprCloseFile(file);
    return 0;
}
Example #22
0
static void run()
{
    PROCESS_INFORMATION procInfo;
    STARTUPINFO         startInfo;
    MprTime             mark;
    ulong               status;
    char                *path, *cmd, *key;
    int                 createFlags;

    createFlags = 0;

#if USEFUL_FOR_DEBUG
    /* 
        This is useful to debug manager as a windows service.
     */
    DebugBreak();
#endif
    /*
        Read the service home directory and args. Default to the current dir if none specified.
     */
    key = sfmt("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\%s", app->serviceName);
    app->serviceHome = mprReadRegistry(key, "HomeDir");
    app->serviceArgs = mprReadRegistry(key, "Args");

    /*
        Expect to find the service executable in the same directory as this manager program.
     */
    if (app->serviceProgram == 0) {
        path = sfmt("\"%s\\%s.exe\"", mprGetAppDir(), BLD_PRODUCT);
    } else {
        path = sfmt("\"%s\"", app->serviceProgram);
    }
    if (app->serviceArgs && *app->serviceArgs) {
        cmd = sfmt("%s %s", path, app->serviceArgs);
    } else {
        cmd = path;
    }
    if (app->createConsole) {
        createFlags |= CREATE_NEW_CONSOLE;
    }
    mark = mprGetTime();

    while (! app->exiting) {
        if (mprGetElapsedTime(mark) > (3600 * 1000)) {
            mark = mprGetTime();
            app->restartCount = 0;
            app->restartWarned = 0;
        }
        if (app->servicePid == 0 && !app->serviceStopped) {
            if (app->restartCount >= RESTART_MAX) {
                if (! app->restartWarned) {
                    mprError("Too many restarts for %s, %d in ths last hour", app->appTitle, app->restartCount);
                    app->restartWarned++;
                }
                /*
                    This is not a real heart-beat. We are only waiting till the service process exits.
                 */
                WaitForSingleObject(app->heartBeatEvent, app->heartBeatPeriod);
                continue;
            }
            memset(&startInfo, 0, sizeof(startInfo));
            startInfo.cb = sizeof(startInfo);

            /*
                Launch the process
             */
            if (! CreateProcess(0, cmd, 0, 0, FALSE, createFlags, 0, app->serviceHome, &startInfo, &procInfo)) {
                mprError("Can't create process: %s, %d", cmd, mprGetOsError());
            } else {
                app->servicePid = (int) procInfo.hProcess;
            }
            app->restartCount++;
        }
        WaitForSingleObject(app->heartBeatEvent, app->heartBeatPeriod);

        if (app->servicePid) {
            if (GetExitCodeProcess((HANDLE) app->servicePid, (ulong*) &status)) {
                if (status != STILL_ACTIVE) {
                    CloseHandle((HANDLE) app->servicePid);
                    app->servicePid = 0;
                }
            } else {
                CloseHandle((HANDLE) app->servicePid);
                app->servicePid = 0;
            }
        }
        mprLog(1, "%s has exited with status %d", app->serviceProgram, status);
        mprLog(1, "%s will be restarted in 10 seconds", app->serviceProgram);
    }
}
Example #23
0
File: cmd.c Project: embedthis/mpr
/*
    Start the command to run (stdIn and stdOut are named from the client's perspective). This is the lower-level way to
    run a command. The caller needs to do code like mprRunCmd() themselves to wait for completion and to send/receive data.
    The routine does not wait. Callers must call mprWaitForCmd to wait for the command to complete.
 */
PUBLIC int mprStartCmd(MprCmd *cmd, int argc, cchar **argv, cchar **envp, int flags)
{
    MprPath     info;
    cchar       *pair;
    int         rc, next, i;

    assert(cmd);
    assert(argv);

    if (argc <= 0 || argv == NULL || argv[0] == NULL) {
        return MPR_ERR_BAD_ARGS;
    }
    resetCmd(cmd, 0);

    cmd->flags = flags;
    cmd->argc = argc;
    cmd->argv = mprAlloc((argc + 1) * sizeof(char*));
    for (i = 0; i < argc; i++) {
        cmd->argv[i] = sclone(argv[i]);
    }
    cmd->argv[i] = 0;

    prepWinProgram(cmd);

    if ((cmd->program = mprSearchPath(cmd->argv[0], MPR_SEARCH_EXE, cmd->searchPath, NULL)) == 0) {
        mprLog("error mpr cmd", 0, "Cannot access %s, errno %d", cmd->argv[0], mprGetOsError());
        return MPR_ERR_CANT_ACCESS;
    }
    if (mprGetPathInfo(cmd->program, &info) == 0 && info.isDir) {
        mprLog("error mpr cmd", 0, "Program \"%s\", is a directory", cmd->program);
        return MPR_ERR_CANT_ACCESS;
    }
    mprLog("info mpr cmd", 6, "Program: %s", cmd->program);
    cmd->argv[0] = cmd->program;

    prepWinCommand(cmd);

    if (envp == 0) {
        envp = cmd->defaultEnv;
    }
    if (blendEnv(cmd, envp, flags) < 0) {
        return MPR_ERR_MEMORY;
    }
    for (i = 0; i < cmd->argc; i++) {
        mprLog("info mpr cmd", 6, "    arg[%d]: %s", i, cmd->argv[i]);
    }
    for (ITERATE_ITEMS(cmd->env, pair, next)) {
        mprLog("info mpr cmd", 6, "    env[%d]: %s", next, pair);
    }
    slock(cmd);
    if (makeCmdIO(cmd) < 0) {
        sunlock(cmd);
        return MPR_ERR_CANT_OPEN;
    }
    /*
        Determine how many end-of-files will be seen when the child dies
     */
    cmd->requiredEof = 0;
    if (cmd->flags & MPR_CMD_OUT) {
        cmd->requiredEof++;
    }
    if (cmd->flags & MPR_CMD_ERR) {
        cmd->requiredEof++;
    }
    if (addCmdHandlers(cmd) < 0) {
        mprLog("error mpr cmd", 0, "Cannot open command handlers - insufficient I/O handles");
        return MPR_ERR_CANT_OPEN;
    }
    rc = startProcess(cmd);

    cmd->originalPid = cmd->pid;
    mprAddItem(MPR->cmdService->cmds, cmd);
    sunlock(cmd);
#if ME_WIN_LIKE
    if (!rc) {
        mprCreateTimerEvent(cmd->dispatcher, "pollWinTimer", 10, pollWinTimer, cmd, 0);
    }
#endif
    return rc;
}
Example #24
0
File: cmd.c Project: embedthis/mpr
static int startProcess(MprCmd *cmd)
{
    MprCmdFile      *files;
    int             i;

    files = cmd->files;
    if (!cmd->signal) {
        cmd->signal = mprAddSignalHandler(SIGCHLD, cmdChildDeath, cmd, cmd->dispatcher, MPR_SIGNAL_BEFORE);
    }
    /*
        Create the child
     */
    cmd->pid = fork();

    if (cmd->pid < 0) {
        mprLog("error mpr cmd", 0, "Cannot fork a new process to run %s, errno %d", cmd->program, mprGetOsError());
        return MPR_ERR_CANT_INITIALIZE;

    } else if (cmd->pid == 0) {
        /*
            Child
         */
        umask(022);
        if (cmd->flags & MPR_CMD_NEW_SESSION) {
            setsid();
        }
        if (cmd->dir) {
            if (chdir(cmd->dir) < 0) {
                mprLog("error mpr cmd", 0, "Cannot change directory to %s", cmd->dir);
                return MPR_ERR_CANT_INITIALIZE;
            }
        }
        if (cmd->flags & MPR_CMD_IN) {
            if (files[MPR_CMD_STDIN].clientFd >= 0) {
                dup2(files[MPR_CMD_STDIN].clientFd, 0);
                close(files[MPR_CMD_STDIN].fd);
            } else {
                close(0);
            }
        }
        if (cmd->flags & MPR_CMD_OUT) {
            if (files[MPR_CMD_STDOUT].clientFd >= 0) {
                dup2(files[MPR_CMD_STDOUT].clientFd, 1);
                close(files[MPR_CMD_STDOUT].fd);
            } else {
                close(1);
            }
        }
        if (cmd->flags & MPR_CMD_ERR) {
            if (files[MPR_CMD_STDERR].clientFd >= 0) {
                dup2(files[MPR_CMD_STDERR].clientFd, 2);
                close(files[MPR_CMD_STDERR].fd);
            } else {
                close(2);
            }
        }
        cmd->forkCallback(cmd->forkData);
        if (cmd->env) {
            (void) execve(cmd->program, (char**) cmd->argv, (char**) &cmd->env->items[0]);
        } else {
            (void) execv(cmd->program, (char**) cmd->argv);
        }
        /*
            Use _exit to avoid flushing I/O any other I/O.
         */
        _exit(-(MPR_ERR_CANT_INITIALIZE));

    } else {
        /*
            Close the client handles
         */
        for (i = 0; i < MPR_CMD_MAX_PIPE; i++) {
            if (files[i].clientFd >= 0) {
                close(files[i].clientFd);
                files[i].clientFd = -1;
            }
        }
    }
    return 0;
}
Example #25
0
File: cmd.c Project: embedthis/mpr
static int makeChannel(MprCmd *cmd, int index)
{
    SECURITY_ATTRIBUTES clientAtt, serverAtt, *att;
    HANDLE              readHandle, writeHandle;
    MprCmdFile          *file;
    MprTicks            now;
    char                *pipeName;
    int                 openMode, pipeMode, readFd, writeFd;
    static int          tempSeed = 0;

    memset(&clientAtt, 0, sizeof(clientAtt));
    clientAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
    clientAtt.bInheritHandle = 1;

    /*
        Server fds are not inherited by the child
     */
    memset(&serverAtt, 0, sizeof(serverAtt));
    serverAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
    serverAtt.bInheritHandle = 0;

    file = &cmd->files[index];
    now = ((int) mprGetTicks() & 0xFFFF) % 64000;

    lock(MPR->cmdService);
    pipeName = sfmt("\\\\.\\pipe\\MPR_%d_%d_%d.tmp", getpid(), (int) now, ++tempSeed);
    unlock(MPR->cmdService);

    /*
        Pipes are always inbound. The file below is outbound. we swap whether the client or server
        inherits the pipe or file. MPR_CMD_STDIN is the clients input pipe.
        Pipes are blocking since both ends share the same blocking mode. Client must be blocking.
     */
    openMode = PIPE_ACCESS_INBOUND;
    pipeMode = 0;

    att = (index == MPR_CMD_STDIN) ? &clientAtt : &serverAtt;
    readHandle = CreateNamedPipe(wide(pipeName), openMode, pipeMode, 1, 0, 256 * 1024, 1, att);
    if (readHandle == INVALID_HANDLE_VALUE) {
        mprLog("error mpr cmd", 0, "Cannot create stdio pipes %s. Err %d", pipeName, mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    readFd = _open_osfhandle((intptr_t) readHandle, 0);

    att = (index == MPR_CMD_STDIN) ? &serverAtt: &clientAtt;
    writeHandle = CreateFile(wide(pipeName), GENERIC_WRITE, 0, att, OPEN_EXISTING, openMode, 0);
    writeFd = _open_osfhandle((intptr_t) writeHandle, 0);

    if (readFd < 0 || writeFd < 0) {
        mprLog("error mpr cmd", 0, "Cannot create stdio pipes %s. Err %d", pipeName, mprGetOsError());
        return MPR_ERR_CANT_CREATE;
    }
    if (index == MPR_CMD_STDIN) {
        file->clientFd = readFd;
        file->fd = writeFd;
        file->handle = writeHandle;
    } else {
        file->clientFd = writeFd;
        file->fd = readFd;
        file->handle = readHandle;
    }
    return 0;
}
Example #26
0
static int writeToFile(HttpQueue *q, char *data, ssize len)
{
    HttpConn        *conn;
    HttpUploadFile  *file;
    HttpLimits      *limits;
    Upload          *up;
    ssize           rc;

    conn = q->conn;
    limits = conn->limits;
    up = q->queueData;
    file = up->currentFile;

    if ((file->size + len) > limits->uploadSize) {
        /*
            Abort the connection as we don't want the load of receiving the entire body
         */
        httpLimitError(conn, HTTP_ABORT | HTTP_CODE_REQUEST_TOO_LARGE, "Uploaded file exceeds maximum %lld", 
            limits->uploadSize);
        return MPR_ERR_CANT_WRITE;
    }
    if (len > 0) {
        /*
            File upload. Write the file data.
         */
        rc = mprWriteFile(up->file, data, len);
        if (rc != len) {
            httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR,
                "Cannot write to upload temp file %s, rc %zd, errno %d", up->tmpPath, rc, mprGetOsError());
            return MPR_ERR_CANT_WRITE;
        }
        file->size += len;
        conn->rx->bytesUploaded += len;
    }
    return 0;
}
Example #27
0
File: os.cpp Project: OPSF/uClinux
int MprCmd::start(char *program, char **argv, char **envp, MprCmdProc fn, 
	void *fnData, int userFlags)
{
	PROCESS_INFORMATION	procInfo;
	STARTUPINFO			startInfo;
	char				dirBuf[MPR_MAX_FNAME];
	char				*envBuf, **ep, *cmdBuf, **ap, *destp, *cp, *dir;
	char				progBuf[MPR_MAX_STRING], *localArgv[2], *saveArg0;
	int					argc, i, len, inheritFiles;

	mprAssert(program);
	mprAssert(argv);

	flags &= ~(MPR_CMD_WAITED | MPR_CMD_RUNNING);
	flags |= (userFlags & MPR_CMD_USER_FLAGS);
	exitStatus = -1;

	mprStrcpy(progBuf, sizeof(progBuf), program);
	progBuf[sizeof(progBuf) - 1] = '\0';
	program = progBuf;

	//
	//	Sanitize the command line (program name only)
	//
	for (cp = program; *cp; cp++) {
		if (*cp == '/') {
			*cp = '\\';
		} else if (*cp == '\r' || *cp == '\n') {
			*cp = ' ';
		}
	}
	if (*program == '"') {
		if ((cp = strrchr(++program, '"')) != 0) {
			*cp = '\0';
		}
	}

	saveArg0 = argv[0];
	if (argv == 0) {
		argv = localArgv;
		argv[1] = 0;
	}
	argv[0] = program;

	//
	//	Determine the command line length and arg count
	//
	argc = 0;
	for (len = 0, ap = argv; *ap; ap++) {
		len += strlen(*ap) + 1 + 2;			// Space and possible quotes
		argc++;
	}
	cmdBuf = (char*) mprMalloc(len + 1);
	cmdBuf[len] = '\0';
	
	//
	//	Add quotes to all args that have spaces in them including "program"
	//
	destp = cmdBuf;
	for (ap = &argv[0]; *ap; ) {
		cp = *ap;
		if ((strchr(cp, ' ') != 0) && cp[0] != '\"') {
			*destp++ = '\"';
			strcpy(destp, cp);
			destp += strlen(cp);
			*destp++ = '\"';
		} else {
			strcpy(destp, cp);
			destp += strlen(cp);
		}
		if (*++ap) {
			*destp++ = ' ';
		}
	}
	*destp = '\0';
	mprAssert((int) strlen(destp) < (len - 1));
	mprAssert(cmdBuf[len] == '\0');
	argv[0] = saveArg0;

	envBuf = 0;
	if (envp) {
		for (len = 0, ep = envp; *ep; ep++) {
			len += strlen(*ep) + 1;
		}
		envBuf = (char*) mprMalloc(len + 2);		// Win requires two nulls
		destp = envBuf;
		for (ep = envp; *ep; ep++) {
			strcpy(destp, *ep);
			mprLog(6, log, "Set CGI variable: %s\n", destp);
			destp += strlen(*ep) + 1;
		}
		*destp++ = '\0';
		*destp++ = '\0';						// WIN requires two nulls
	}
	
	memset(&startInfo, 0, sizeof(startInfo));
	startInfo.cb = sizeof(startInfo);

    startInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
	if (flags & MPR_CMD_SHOW) {
		startInfo.wShowWindow = SW_SHOW;
	} else {
		startInfo.wShowWindow = SW_HIDE;
	}

	if (files.clientFd[MPR_CMD_IN] > 0) {
		startInfo.hStdInput = 
			(HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_IN]);
	}
	if (files.clientFd[MPR_CMD_OUT] > 0) {
		startInfo.hStdOutput = 
			(HANDLE)_get_osfhandle(files.clientFd[MPR_CMD_OUT]);
	}
	if (files.clientFd[MPR_CMD_ERR] > 0) {
		startInfo.hStdError = 
			(HANDLE) _get_osfhandle(files.clientFd[MPR_CMD_ERR]);
	}

#if UNUSED
	SECURITY_ATTRIBUTES	secAtt;
	memset(&secAtt, 0, sizeof(secAtt));
	secAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
	secAtt.bInheritHandle = TRUE;
#endif

	if (userFlags & MPR_CMD_CHDIR) {
		if (cwd) {
			dir = cwd;
		} else {
			mprGetDirName(dirBuf, sizeof(dirBuf), argv[0]);
			dir = dirBuf;
		}
	} else {
		dir = 0;
	}

	inheritFiles = (flags & MPR_CMD_STDIO_MADE) ? 1 : 0;

	mprLog(5, log, "Running: %s\n", cmdBuf); 

	if (! CreateProcess(0, cmdBuf, 0, 0, inheritFiles, CREATE_NEW_CONSOLE,
			envBuf, dir, &startInfo, &procInfo)) {
		mprError(MPR_L, MPR_LOG, "Can't create process: %s, %d", 
			cmdBuf, mprGetOsError());
		return MPR_ERR_CANT_CREATE;
	}

	handle = (long) procInfo.hProcess;
	pid = procInfo.dwProcessId;

	if (procInfo.hThread != 0)  {
		CloseHandle(procInfo.hThread);
	}
	for (i = 0; i < MPR_CMD_MAX_FD; i++) {
		if (files.clientFd[i] >= 0) {
			close(files.clientFd[i]);
			files.clientFd[i] = -1;
		}
	}
	if (cmdBuf) {
		mprFree(cmdBuf);
	}
	if (envBuf) {
		mprFree(envBuf);
	}

	if (userFlags & MPR_CMD_WAIT) {
		waitForChild(INT_MAX);
		for (i = 0; i < MPR_CMD_MAX_FD; i++) {
			if (files.serverFd[i] >= 0) {
				close(files.serverFd[i]);
				files.serverFd[i] = -1;
			}
		}
		return exitStatus;
	}

	lock();
	outputDataProc = fn;
	data = fnData;
	flags |= MPR_CMD_RUNNING;

	if (1 || ! mpr->getAsyncSelectMode()) {
		timer = new MprTimer(MPR_TIMEOUT_CMD_WAIT, 
			singleThreadedOutputData, (void*) this);
#if FUTURE
		//
		//	Want non blocking reads if we are in single-threaded mode.
		//	Can't use this yet as we are holding a Request lock and so blocking
		//	in a read stops everything. Need proper Async I/O in windows.
		//
		if (mprGetMpr()->poolService->getMaxPoolThreads() == 0) {
		} else {
			task = new MprTask(multiThreadedOutputData, (void*) this);
			task->start();
		}
#endif
	}
	unlock();

	return 0;
}
Example #28
0
File: os.cpp Project: OPSF/uClinux
int MprCmd::makeStdioPipes(char *prefix, int fileFlags)
{
	SECURITY_ATTRIBUTES	clientAtt, serverAtt, *att;
	HANDLE				fileHandle;
	char				pipeBuf[MPR_MAX_FNAME];
	int					openMode, pipeMode, i, fdRead, fdWrite;

	openMode = PIPE_ACCESS_INBOUND;
#if FUTURE
	if (fileFlags & MPR_CMD_NON_BLOCK) {
		openMode |= FILE_FLAG_OVERLAPPED;
	}
#endif

	//
	//	The difference is server fds are not inherited by the child
	//
	memset(&clientAtt, 0, sizeof(clientAtt));
	clientAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
	clientAtt.bInheritHandle = TRUE;

	memset(&serverAtt, 0, sizeof(serverAtt));
	serverAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
	serverAtt.bInheritHandle = FALSE;


	fileFlags |= MPR_CMD_STDWAIT;

	for (i = 0; i < MPR_CMD_MAX_FD - 1; i++) {
		if ((fileFlags & (1 << (i + MPR_CMD_FD_SHIFT))) == 0) {
			continue;
		}
		att = (i == MPR_CMD_IN) ? &clientAtt : &serverAtt;
		mprMakeTempFileName(pipeBuf, sizeof(pipeBuf), "\\\\.\\pipe\\", 0);

		pipeMode = (i == MPR_CMD_OUT) ? PIPE_NOWAIT : 0;

		fileHandle = CreateNamedPipe(pipeBuf, openMode, 
			pipeMode, 1, 0, 65536, 1, att);
		fdRead = (int) _open_osfhandle((long) fileHandle, 0);

		att = (i != MPR_CMD_IN) ? &clientAtt : &serverAtt;
		fileHandle = CreateFile(pipeBuf, GENERIC_WRITE, 
			0, att, OPEN_EXISTING, openMode, 0);
		fdWrite = (int) _open_osfhandle((long) fileHandle, 0);

		if (fdRead < 0 || fdWrite < 0) {
			mprError(MPR_L, MPR_LOG, "Can't create stdio pipes. Err %d\n",
				mprGetOsError());
			mprAssert(0);
			return -1;
		}
		if (i == MPR_CMD_IN) {
			files.clientFd[i] = fdRead;
			files.serverFd[i] = fdWrite;
		} else {
			files.clientFd[i] = fdWrite;
			files.serverFd[i] = fdRead;
		}
	}
	return 0;
}
Example #29
0
static void browserToCgiService(HttpQueue *q)
{
    HttpConn    *conn;
    HttpPacket  *packet;
    Cgi         *cgi;
    MprCmd      *cmd;
    MprBuf      *buf;
    ssize       rc, len;
    int         err;

    if ((cgi = q->queueData) == 0) {
        return;
    }
    assert(q == cgi->writeq);
    cmd = cgi->cmd;
    assert(cmd);
    conn = cgi->conn;

    for (packet = httpGetPacket(q); packet; packet = httpGetPacket(q)) {
        if ((buf = packet->content) == 0) {
            /* End packet */
            continue;
        }
        len = mprGetBufLength(buf);
        rc = mprWriteCmd(cmd, MPR_CMD_STDIN, mprGetBufStart(buf), len);
        if (rc < 0) {
            err = mprGetError();
            if (err == EINTR) {
                continue;
            } else if (err == EAGAIN || err == EWOULDBLOCK) {
                httpPutBackPacket(q, packet);
                break;
            }
            httpTrace(conn, "cgi.error", "error", "msg=\"Cannot write to CGI gateway\", errno=%d", mprGetOsError());
            mprCloseCmdFd(cmd, MPR_CMD_STDIN);
            httpDiscardQueueData(q, 1);
            httpError(conn, HTTP_CODE_BAD_GATEWAY, "Cannot write body data to CGI gateway");
            break;
        }
        mprAdjustBufStart(buf, rc);
        if (mprGetBufLength(buf) > 0) {
            httpPutBackPacket(q, packet);
            break;
        }
    }
    if (q->count > 0) {
        /* Wait for writable event so cgiCallback can recall this routine */
        mprEnableCmdEvents(cmd, MPR_CMD_STDIN);
    } else if (conn->rx->eof) {
        mprCloseCmdFd(cmd, MPR_CMD_STDIN);
    } else {
        mprDisableCmdEvents(cmd, MPR_CMD_STDIN);
    }
}
Example #30
0
static void runService()
{
    MprTime     mark;
    char        **av, *env[3], **argv;
    int         err, i, status, ac, next;

    app->servicePid = 0;
    atexit(cleanup);

    mprLog(1, "%s: Watching over %s", app->appName, app->serviceProgram);

    if (access(app->serviceProgram, X_OK) < 0) {
        mprError("start: can't access %s, errno %d", app->serviceProgram, mprGetOsError());
        return;
    }
    if (writePid(getpid()) < 0) {
        return;
    }
    mark = mprGetTime();

    while (!mprIsStopping()) {
        if (mprGetElapsedTime(mark) > (3600 * 1000)) {
            mark = mprGetTime();
            app->restartCount = 0;
            app->restartWarned = 0;
        }
        if (app->servicePid == 0) {
            if (app->restartCount >= app->retries) {
                if (! app->restartWarned) {
                    mprError("Too many restarts for %s, %d in ths last hour", app->serviceProgram, app->restartCount);
                    mprError("Suspending restarts for one hour");
                    app->restartWarned++;
                }
                mprSleep(60 * 1000);
                continue;
            }

            /*
                Create the child
             */
            app->servicePid = vfork();
            if (app->servicePid < 0) {
                mprError("Can't fork new process to run %s", app->serviceProgram);
                continue;

            } else if (app->servicePid == 0) {
                /*
                    Child
                 */
                umask(022);
                setsid();

                mprLog(1, "%s: Change dir to %s", app->appName, app->serviceHome);
                if (chdir(app->serviceHome) < 0) {}

                for (i = 3; i < 128; i++) {
                    close(i);
                }
                if (app->serviceArgs && *app->serviceArgs) {
                    ac = mprMakeArgv(app->serviceArgs, &av, 0);
                } else {
                    ac = 0;
                }
                argv = mprAlloc(sizeof(char*) * (6 + ac));
                env[0] = sjoin("LD_LIBRARY_PATH=", app->serviceHome, NULL);
                env[1] = sjoin("PATH=", getenv("PATH"), NULL);
                env[2] = 0;

                next = 0;
                argv[next++] = app->serviceProgram;
                if (app->logSpec) {
                    argv[next++] = "--log";
                    argv[next++] = (char*) app->logSpec;
                }
                for (i = 0; i < ac; i++) {
                    argv[next++] = av[i];
                }
                argv[next++] = 0;

                mprLog(1, "%s: Running %s", app->appName, app->serviceProgram);
                for (i = 1; argv[i]; i++) {
                    mprLog(1, "%s: argv[%d] = %s", app->appName, i, argv[i]);
                }
                execve(app->serviceProgram, argv, (char**) &env);

                /* Should not get here */
                err = errno;
                mprError("%s: Can't exec %s, err %d, cwd %s", app->appName, app->serviceProgram, err, app->serviceHome);
                exit(MPR_ERR_CANT_INITIALIZE);
            }

            /*
                Parent
             */
            mprLog(1, "%s: create child %s at pid %d", app->appName, app->serviceProgram, app->servicePid);
            app->restartCount++;

            waitpid(app->servicePid, &status, 0);
            mprLog(1, "%s: %s has exited with status %d", app->appName, app->serviceProgram, WEXITSTATUS(status));
            if (!mprIsStopping()) {
                mprLog(1, "%s: Restarting %s (%d/%d)...", 
                    app->appName, app->serviceProgram, app->restartCount, app->retries);
            }
            app->servicePid = 0;
        }
    }
}