Пример #1
0
static void standardSignalHandler(void *ignored, MprSignal *sp)
{
    mprLog(6, "standardSignalHandler signo %d, flags %x", sp->signo, sp->flags);
    if (sp->signo == SIGTERM) {
        mprTerminate(MPR_EXIT_GRACEFUL, -1);

    } else if (sp->signo == SIGINT) {
#if BIT_UNIX_LIKE
        /*  Ensure shell input goes to a new line */
        if (isatty(1)) {
            if (write(1, "\n", 1) < 0) {}
        }
#endif
        mprTerminate(MPR_EXIT_IMMEDIATE, -1);

    } else if (sp->signo == SIGUSR1) {
        mprTerminate(MPR_EXIT_GRACEFUL | MPR_EXIT_RESTART, 0);

    } else if (sp->signo == SIGPIPE || sp->signo == SIGXFSZ) {
        /* Ignore */

#if MACOSX && BIT_DEBUG
    } else if (sp->signo == SIGSEGV || sp->signo == SIGBUS) {
        printf("PAUSED for watson to debug\n");
        sleep(120);
#endif

    } else {
        mprTerminate(MPR_EXIT_DEFAULT, -1);
    }
}
Пример #2
0
bool mprStop(Mpr *mpr)
{
    int     stopped;

    stopped = 1;

    mprLock(mpr->mutex);
    if (! (mpr->flags & MPR_STARTED) || (mpr->flags & MPR_STOPPED)) {
        mprUnlock(mpr->mutex);
        return 0;
    }
    mpr->flags |= MPR_STOPPED;

    /*
        Trigger graceful termination. This will prevent further tasks and events being created.
     */
    mprTerminate(mpr, 1);

#if BLD_FEATURE_HTTP
    mprStopHttpService(mpr->httpService);
#endif
    mprStopSocketService(mpr->socketService);
#if BLD_FEATURE_MULTITHREAD
    if (!mprStopWorkerService(mpr->workerService, MPR_TIMEOUT_STOP_TASK)) {
        stopped = 0;
    }
    if (!mprStopThreadService(mpr->threadService, MPR_TIMEOUT_STOP_TASK)) {
        stopped = 0;
    }
#endif
    mprStopModuleService(mpr->moduleService);
    mprStopOsService(mpr->osService);
    return stopped;
}
Пример #3
0
/*  
    Exit the application
    static function exit(status: Number, how: String = "default"): void
    MOB - status is not implemented
 */
static EjsObj *app_exit(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    cchar   *how;
    int     status, mode;

    if (ejs->dontExit) {
        ejsThrowStateError(ejs, "App.exit has been disabled");
        return 0;
    }
    status = argc >= 1 ? ejsGetInt(ejs, argv[0]) : 0;
    how = ejsToMulti(ejs, argc >= 2 ? ejsToString(ejs, argv[1]): ESV(empty));

    if (scmp(how, "default") == 0) {
        mode = MPR_EXIT_DEFAULT;
    } else if (scmp(how, "immediate") == 0) {
        mode = MPR_EXIT_IMMEDIATE;
    } else if (scmp(how, "graceful") == 0) {
        mode = MPR_EXIT_GRACEFUL;
    } else {
        mode = MPR_EXIT_NORMAL;
    }
    mprTerminate(mode, status);
    ejsAttention(ejs);
    return 0;
}
Пример #4
0
/*
    Wait for I/O on all registered descriptors. Timeout is in milliseconds. Return the number of events serviced.
    Should only be called by the thread that calls mprServiceEvents
 */
PUBLIC void mprWaitForIO(MprWaitService *ws, MprTicks timeout)
{
    MSG     msg;

    assert(ws->hwnd);

    if (timeout < 0 || timeout > MAXINT) {
        timeout = MAXINT;
    }
#if BIT_DEBUG
    if (mprGetDebugMode() && timeout > 30000) {
        timeout = 30000;
    }
#endif
    if (ws->needRecall) {
        mprDoWaitRecall(ws);
        return;
    }
    SetTimer(ws->hwnd, 0, (UINT) timeout, NULL);

    mprYield(MPR_YIELD_STICKY);
    if (GetMessage(&msg, NULL, 0, 0) == 0) {
        mprResetYield();
        mprTerminate(MPR_EXIT_DEFAULT, -1);
    } else {
        mprClearWaiting();
        mprResetYield();
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    ws->wakeRequested = 0;
}
Пример #5
0
static long msgProc(HWND hwnd, UINT msg, UINT wp, LPARAM lp)
{
    MprThread   *tp;
    char        buf[MPR_MAX_FNAME];

    switch (msg) {
    case WM_DESTROY:
    case WM_QUIT:
        mprTerminate(MPR_EXIT_GRACEFUL, -1);
        break;
    
    case APPWEB_MONITOR_MESSAGE:
        return monitorEvent(hwnd, wp, lp);

    case WM_COMMAND:
        switch (LOWORD(wp)) {
        case MA_MENU_STATUS:
            break;

        case MA_MENU_DOC:
            runBrowser("/doc/index.html");
            break;

        case MA_MENU_MANAGE:
            runBrowser("/index.html");
            break;

        case MA_MENU_START:
            tp = mprCreateThread("startService", startService, 0, 0);
            mprStartThread(tp);
            break;

        case MA_MENU_STOP:
            tp = mprCreateThread("stopService", stopService, 0, 0);
            mprStartThread(tp);
            break;

        case MA_MENU_ABOUT:
            /*
                Single-threaded users beware. This blocks !!
             */
            mprSprintf(buf, sizeof(buf), "%s %s-%s", BIT_TITLE, BIT_VERSION, BIT_BUILD_NUMBER);
            MessageBoxEx(hwnd, buf, mprGetAppTitle(), MB_OK, 0);
            break;

        case MA_MENU_EXIT:
            PostMessage(hwnd, WM_QUIT, 0, 0L);
            break;

        default:
            return (long) DefWindowProc(hwnd, msg, wp, lp);
        }
        break;

    default:
        return (long) DefWindowProc(hwnd, msg, wp, lp);
    }
    return 0;
}
Пример #6
0
/*
    Catch signals. Do a graceful shutdown.
 */
static void catchSignal(int signo, siginfo_t *info, void *arg)
{
    Mpr     *mpr;

    mpr = mprGetMpr();
    if (mpr) {
#if DEBUG_IDE
        if (signo == SIGINT) return;
#endif
        mprLog(mpr, 2, "Received signal %d", signo);
        if (signo == SIGTERM) {
            mprLog(mpr, 1, "Executing a graceful exit. Waiting for all requests to complete.");
            mprTerminate(mpr, 1);
        } else {
            mprLog(mpr, 1, "Exiting immediately ...");
            mprTerminate(mpr, 0);
        }
    }
}
Пример #7
0
static void finishThread(MprThread *tp)
{
    if (tp) {
        mprLock(app->mutex);
        if (--app->activeLoadThreads <= 0) {
            mprTerminate(MPR_EXIT_DEFAULT, -1);
        }
        mprUnlock(app->mutex);
    }
}
Пример #8
0
/**
 *  Exit the application
 *
 *  static function exit(status: Number): void
 */
static EjsVar *exitApp(Ejs *ejs, EjsVar *unused, int argc, EjsVar **argv)
{
    int     status;

    status = argc == 0 ? 0 : ejsGetInt(argv[0]);
    mprBreakpoint();
    if (!ejs->dontExit) {
        if (status != 0) {
            exit(status);
        } else {
            mprTerminate(mprGetMpr(ejs), 1);
        }
    }
    return 0;
}
Пример #9
0
/*
    Windows message processing loop for wakeup and socket messages
 */
static LRESULT msgProc(HWND hwnd, UINT msg, UINT wp, LPARAM lp)
{
    MprWaitService      *ws;
    int                 sock, winMask;

    ws = MPR->waitService;

    if (msg == WM_DESTROY || msg == WM_QUIT) {
        mprTerminate(MPR_EXIT_DEFAULT, -1);

    } else if (msg && msg == ws->socketMessage) {
        sock = wp;
        winMask = LOWORD(lp);
        mprServiceWinIO(MPR->waitService, sock, winMask);

    } else if (ws->msgCallback) {
        return ws->msgCallback(hwnd, msg, wp, lp);

    } else {
        return DefWindowProc(hwnd, msg, wp, lp);
    }
    return 0;
}
Пример #10
0
MAIN(ejsMain, int argc, char **argv, char **envp)
{
    Mpr             *mpr;
    EcCompiler      *cp;
    Ejs             *ejs;
    cchar           *cmd, *className, *method, *homeDir;
    char            *argp, *searchPath, *modules, *name, *tok, *extraFiles;
    int             nextArg, err, ecFlags, stats, merge, bind, noout, debug, optimizeLevel, warnLevel, strict, i, next;

    /*  
        Initialize Multithreaded Portable Runtime (MPR)
     */
    mpr = mprCreate(argc, argv, 0);
    app = mprAllocObj(App, manageApp);
    mprAddRoot(app);
    mprAddStandardSignals();

    if (mprStart(mpr) < 0) {
        mprError("Cannot start mpr services");
        return EJS_ERR;
    }
    err = 0;
    className = 0;
    cmd = 0;
    method = 0;
    searchPath = 0;
    stats = 0;
    merge = 0;
    bind = 1;
    noout = 1;
    debug = 1;
    warnLevel = 1;
    optimizeLevel = 9;
    strict = 0;
    app->files = mprCreateList(-1, 0);
    app->iterations = 1;
    argc = mpr->argc;
    argv = (char**) mpr->argv;

    for (nextArg = 1; nextArg < argc; nextArg++) {
        argp = argv[nextArg];
        if (*argp != '-') {
            break;
        }
        if (smatch(argp, "--bind")) {
            bind = 1;

        } else if (smatch(argp, "--class")) {
            if (nextArg >= argc) {
                err++;
            } else {
                className = argv[++nextArg];
            }

        } else if (smatch(argp, "--chdir") || smatch(argp, "--home") || smatch(argp, "-C")) {
            if (nextArg >= argc) {
                err++;
            } else {
                homeDir = argv[++nextArg];
                if (chdir((char*) homeDir) < 0) {
                    mprError("Cannot change directory to %s", homeDir);
                }
            }

#if BIT_UNIX_LIKE
        } else if (smatch(argp, "--chroot")) {
            /* Not documented or supported */
            if (nextArg >= argc) {
                err++;
            } else {
                homeDir = mprGetAbsPath(argv[++nextArg]);
                if (chroot(homeDir) < 0) {
                    if (errno == EPERM) {
                        mprPrintfError("%s: Must be super user to use the --chroot option", mprGetAppName(mpr));
                    } else {
                        mprPrintfError("%s: Cannot change change root directory to %s, errno %d",
                            mprGetAppName(), homeDir, errno);
                    }
                    return 4;
                }
            }
#endif

        } else if (smatch(argp, "--cmd") || smatch(argp, "-c")) {
            if (nextArg >= argc) {
                err++;
            } else {
                cmd = argv[++nextArg];
            }

#if BIT_WIN_LIKE
        } else if (smatch(argp, "--cygroot")) {
            if (nextArg >= argc) {
                err++;
            } else {
                app->cygroot = sclone(argv[++nextArg]);
            }
#endif
        } else if (smatch(argp, "--debug")) {
            debug = 1;

        } else if (smatch(argp, "--debugger") || smatch(argp, "-D")) {
            mprSetDebugMode(1);

        } else if (smatch(argp, "--files") || smatch(argp, "-f")) {
            /* Compatibility with mozilla shell */
            if (nextArg >= argc) {
                err++;
            } else {
                extraFiles = sclone(argv[++nextArg]);
                name = stok(extraFiles, " \t", &tok);
                while (name != NULL) {
                    mprAddItem(app->files, sclone(name));
                    name = stok(NULL, " \t", &tok);
                }
            }

        } else if (smatch(argp, "--iterations") || smatch(argp, "-i")) {
            if (nextArg >= argc) {
                err++;
            } else {
                app->iterations = atoi(argv[++nextArg]);
            }

        } else if (smatch(argp, "--log")) {
            if (nextArg >= argc) {
                err++;
            } else {
                mprStartLogging(argv[++nextArg], 0);
                mprSetCmdlineLogging(1);
            }

        } else if (smatch(argp, "--method")) {
            if (nextArg >= argc) {
                err++;
            } else {
                method = argv[++nextArg];
            }

        } else if (smatch(argp, "--name")) {
            /* Just ignore. Used to tag commands with a unique command line */ 
            nextArg++;

        } else if (smatch(argp, "--nobind")) {
            bind = 0;

        } else if (smatch(argp, "--nodebug")) {
            debug = 0;

        } else if (smatch(argp, "--optimize")) {
            if (nextArg >= argc) {
                err++;
            } else {
                optimizeLevel = atoi(argv[++nextArg]);
            }

        } else if (smatch(argp, "-s")) {
            /* Compatibility with mozilla shell. Just ignore */

        } else if (smatch(argp, "--search") || smatch(argp, "--searchpath")) {
            if (nextArg >= argc) {
                err++;
            } else {
                searchPath = argv[++nextArg];
            }

        } else if (smatch(argp, "--standard")) {
            strict = 0;

        } else if (smatch(argp, "--stats")) {
            stats = 1;

        } else if (smatch(argp, "--strict")) {
            strict = 1;

        } else if (smatch(argp, "--require")) {
            if (nextArg >= argc) {
                err++;
            } else {
                if (app->modules == 0) {
                    app->modules = mprCreateList(-1, 0);
                }
                modules = sclone(argv[++nextArg]);
                name = stok(modules, " \t", &tok);
                while (name != NULL) {
                    require(name);
                    name = stok(NULL, " \t", &tok);
                }
            }

        } else if (smatch(argp, "--verbose") || smatch(argp, "-v")) {
            mprStartLogging("stderr:2", 0);
            mprSetCmdlineLogging(1);

        } else if (smatch(argp, "--version") || smatch(argp, "-V")) {
            mprPrintf("%s-%s\n", BIT_VERSION, BIT_BUILD_NUMBER);
            return 0;

        } else if (smatch(argp, "--warn")) {
            if (nextArg >= argc) {
                err++;
            } else {
                warnLevel = atoi(argv[++nextArg]);
            }

        } else {
            err++;
            break;
        }
    }

    if (err) {
        /*  
            If --method or --class is specified, then the named class.method will be run (method defaults to "main", class
            defaults to first class with a "main").

            Examples:
                ejs
                ejs script.es arg1 arg2 arg3
                ejs --class "Customer" --method "start" --files "script1.es script2.es" main.es
         */
        mprPrintfError("Usage: %s [options] script.es [arguments] ...\n"
            "  Ejscript shell program options:\n"
            "  --class className        # Name of class containing method to run\n"
            "  --cmd ejscriptCode       # Literal ejscript statements to execute\n"
            "  --cygroot path           # Set cygwin root for resolving script paths\n"
            "  --debug                  # Use symbolic debugging information (default)\n"
            "  --debugger               # Disable timeouts to make using a debugger easier\n"
            "  --files \"files..\"        # Extra source to compile\n"
            "  --log logSpec            # Internal compiler diagnostics logging\n"
            "  --method methodName      # Name of method to run. Defaults to main\n"
            "  --nodebug                # Omit symbolic debugging information\n"
            "  --optimize level         # Set the optimization level (0-9 default is 9)\n"
            "  --require 'module,...'   # Required list of modules to pre-load\n"
            "  --search ejsPath         # Module search path\n"
            "  --standard               # Default compilation mode to standard (default)\n"
            "  --stats                  # Print memory stats on exit\n"
            "  --strict                 # Default compilation mode to strict\n"
            "  --verbose | -v           # Same as --log stderr:2 \n"
            "  --version                # Emit the compiler version information\n"
            "  --warn level             # Set the warning message level (0-9 default is 0)\n\n",
            mpr->name);
        return -1;
    }
    if ((ejs = ejsCreateVM(argc - nextArg, (cchar **) &argv[nextArg], 0)) == 0) {
        return MPR_ERR_MEMORY;
    }
    app->ejs = ejs;
    if (ejsLoadModules(ejs, searchPath, app->modules) < 0) {
        return MPR_ERR_CANT_READ;
    }

    ecFlags = 0;
    ecFlags |= (merge) ? EC_FLAGS_MERGE: 0;
    ecFlags |= (bind) ? EC_FLAGS_BIND: 0;
    ecFlags |= (noout) ? EC_FLAGS_NO_OUT: 0;
    ecFlags |= (debug) ? EC_FLAGS_DEBUG: 0;

    cp = app->compiler = ecCreateCompiler(ejs, ecFlags);
    if (cp == 0) {
        return MPR_ERR_MEMORY;
    }
    ecSetRequire(cp, app->modules);

    ecSetOptimizeLevel(cp, optimizeLevel);
    ecSetWarnLevel(cp, warnLevel);
    ecSetStrictMode(cp, strict);
    if (nextArg < argc) {
        mprAddItem(app->files, sclone(argv[nextArg]));
    }
    if (app->cygroot) {
        /*  
            When cygwin invokes a script with shebang, it passes a cygwin path to the script
            The ejs --cygroot option permits ejscript to conver this to a native path
         */
        for (next = 0; (name = mprGetNextItem(app->files, &next)) != 0; ) {
            if (*name == '/' || *name == '\\') {
                mprSetItem(app->files, next - 1, sjoin(app->cygroot, name, NULL));
            }
        }
    }
    for (i = 0; !err && i < app->iterations; i++) {
        if (cmd) {
            if (interpretCommands(cp, cmd) < 0) {
                err++;
            }
        } else if (mprGetListLength(app->files) > 0) {
            if (interpretFiles(cp, app->files, argc - nextArg, &argv[nextArg], className, method) < 0) {
                err++;
            }
        } else {
            /*  
                No args - run as an interactive shell
             */
            if (interpretCommands(cp, NULL) < 0) {
                err++;
            }
        }
    }
    if (stats) {
#if BIT_DEBUG
        mprSetLogLevel(1);
        mprPrintMem("Memory Usage", 1);
#endif
    }
    if (!err) {
        err = mpr->exitStatus;
    }
    app->ejs = 0;
    mprTerminate(MPR_EXIT_DEFAULT, err);
    ejsDestroyVM(ejs);
    mprDestroy(MPR_EXIT_DEFAULT);
    return err;
}
Пример #11
0
MAIN(ejsMain, int argc, char **argv, char **envp)
{
    Mpr         *mpr;
    Ejs         *ejs;
    EcCompiler  *ec;
    char    *argp, *searchPath, *path, *homeDir;
    int     nextArg, err, flags;

    /*  
        Initialize Multithreaded Portable Runtime (MPR)
     */
    mpr = mprCreate(argc, argv, 0);
    app = mprAllocObj(App, manageApp);
    mprAddRoot(app);
    mprAddStandardSignals();

    if (mprStart(mpr) < 0) {
        mprError("Cannot start mpr services");
        return EJS_ERR;
    }
    err = 0;
    searchPath = 0;
    argc = mpr->argc;
    argv = (char**) mpr->argv;

    for (nextArg = 1; nextArg < argc; nextArg++) {
        argp = argv[nextArg];
        if (*argp != '-') {
            break;
        }
        if (smatch(argp, "--chdir") || smatch(argp, "--home") || smatch(argp, "-C")) {
            if (nextArg >= argc) {
                err++;
            } else {
                homeDir = argv[++nextArg];
                if (chdir((char*) homeDir) < 0) {
                    mprError("Cannot change directory to %s", homeDir);
                }
            }

        } else if (smatch(argp, "--debugger") || smatch(argp, "-D")) {
            mprSetDebugMode(1);

        } else if (smatch(argp, "--log")) {
            if (nextArg >= argc) {
                err++;
            } else {
                mprStartLogging(argv[++nextArg], 0);
                mprSetCmdlineLogging(1);
            }

        } else if (smatch(argp, "--name")) {
            /* Just ignore. Used to tag commands with a unique command line */ 
            nextArg++;

        } else if (smatch(argp, "--search") || smatch(argp, "--searchpath")) {
            if (nextArg >= argc) {
                err++;
            } else {
                searchPath = argv[++nextArg];
            }

        } else if (smatch(argp, "--verbose") || smatch(argp, "-v")) {
            mprStartLogging("stderr:1", 0);
            mprSetCmdlineLogging(1);

        } else if (smatch(argp, "--version") || smatch(argp, "-V")) {
            mprPrintf("%s-%s\n", BIT_VERSION, BIT_BUILD_NUMBER);
            return 0;

        } else {
            /* Ignore */
        }
    }
    path = mprJoinPath(mprGetAppDir(), mprGetPathBase(argv[0]));
    path = mprReplacePathExt(path, ".es");
    mprAddRoot(path);
    argv[0] = path;
    if ((ejs = ejsCreateVM(argc, (cchar **) &argv[0], 0)) == 0) {
        return MPR_ERR_MEMORY;
    }
    app->ejs = ejs;
    if (ejsLoadModules(ejs, searchPath, NULL) < 0) {
        return MPR_ERR_CANT_READ;
    }
    mprLog(2, "Load script \"%s\"", path);
    flags = EC_FLAGS_BIND | EC_FLAGS_DEBUG | EC_FLAGS_NO_OUT | EC_FLAGS_THROW;
    if ((ec = ecCreateCompiler(ejs, flags)) == 0) {
        return MPR_ERR_MEMORY;
    }
    mprAddRoot(ec);
    ecSetOptimizeLevel(ec, 9);
    ecSetWarnLevel(ec, 1);
    if (ecCompile(ec, 1, (char**) &path) < 0) {
        if (flags & EC_FLAGS_THROW) {
            ejsThrowSyntaxError(ejs, "%s", ec->errorMsg ? ec->errorMsg : "Cannot parse script");
            ejsReportError(ejs, "Error in script");
        }
        err = MPR_ERR;
    } else {
        mprRemoveRoot(ec);
        if (ejsRunProgram(ejs, NULL, NULL) < 0) {
            ejsReportError(ejs, "Error in script");
            err = MPR_ERR;
        }
    }
    if (!err) {
        err = mpr->exitStatus;
    }
    app->ejs = 0;
    mprTerminate(MPR_EXIT_DEFAULT, err);
    ejsDestroyVM(ejs);
    mprDestroy(MPR_EXIT_DEFAULT);
    return err;
}