int CommandLine::run()

in aios/apps/facility/cm2/cm_basic/util/command_line.cpp [190:336]


int CommandLine::run(int argc, char* argv[])
{
    bool ret = false;
    bool needWait = false;
    char pidFile[PATH_MAX + 1] = {0};
    char confName[PATH_MAX + 1] = {0};
    pid_t curPid = 0;
    Args args(argc, argv);
    char* pconf = cm_basic::FileUtil::getRealPath(args.getConfPath(), confName);
    if (_server) {
        fprintf(stderr, "%s is running.\n", _name);
        return -1;
    }
    if (args.isForHelp()) {
        help();
        return 0;
    } else if (args.isForLongVersion()) {
        showLongVersion();
        return 0;
    } else if (args.isForShortVersion()) {
        showShortVersion();
        return 0;
    }

    if (setSigmask() == false)
        return -1;

    for (char* pTmp = pconf; *pTmp; pTmp++) {
        if (*pTmp == '/') {
            *pTmp = '_';
        }
    }
    snprintf(pidFile, strlen(_name) + strlen(pidFileTMPL) + strlen(pconf) + 1, pidFileTMPL, _name, pconf);
    curPid = getPidFromFile(pidFile);
    if (args.getCommandType() == cmd_unknown || strlen(args.getConfPath()) == 0) {
        help(-1);
        return -1;
    } else if (args.getCommandType() == cmd_stop) {
        if (curPid > 0) {
            if (kill(curPid, SIGTERM) != 0) {
                fprintf(stderr, "kill process error, pid = %ld\n", (int64_t)curPid);
            }
        } else {
            fprintf(stderr, "process not running.\n");
        }
        return -1;
    } else if (args.getCommandType() == cmd_restart) {
        if (curPid > 0) {
            if (kill(curPid, SIGTERM) != 0) {
                fprintf(stderr, "kill process error, pid = %ld\n", (int64_t)curPid);
                return -1;
            }
            needWait = true;
        } else {
            fprintf(stderr, "process not running.\n");
        }
    } else if (args.getCommandType() == cmd_start) {
        if (curPid > 0) {
            fprintf(stderr,
                    "process already running."
                    "stop it first. pid=%ld, pidfile=%s\n",
                    (int64_t)curPid, pidFile);
            return -1;
        }
    }

    if (args.asDaemon()) {
        if (daemon(1, 1) == -1) {
            fprintf(stderr, "set self process as daemon failed.\n");
        }
    }
    if ((args.getCommandType() == cmd_restart) && (needWait)) {
        int errnum = 0;
        while (getPidFromFile(pidFile) >= 0) {
            if (errnum > 3000) {
                fprintf(stderr, "shutdown previous server failed: too slow\n");
                alog::Logger::shutdown();
                return -1;
            }
            usleep(20);
            errnum++;
        }
    }
    if (updatePidFile(pidFile) < 0) {
        fprintf(stderr, "write pid to file %s error\n", pidFile);
        alog::Logger::shutdown();
        return -1;
    }
    if (strlen(args.getLogConfPath()) > 0) {
        try {
            alog::Configurator::configureLogger(args.getLogConfPath());
        } catch (std::exception& e) {
            fprintf(stderr, "config from '%s' failed, using default root.\n", args.getLogConfPath());
            alog::Configurator::configureRootLogger();
        }
    } else {
        alog::Configurator::configureRootLogger();
    }
    AUTIL_LOG(INFO, "server begin to start: pid=%ld", (int64_t)getpid());

    _server = makeServer();
    if (!_server) {
        AUTIL_LOG(ERROR, "create server failed.\n");
        alog::Logger::shutdown();
        return -1;
    }

    ret = _server->start(args.getConfPath());
    if (ret != true) {
        AUTIL_LOG(ERROR, "startting server by `%s' failed.\n", args.getConfPath());
        delete _server;
        _server = NULL;
        alog::Logger::shutdown();
        unlink(pidFile);
        return -2;
    }
    AUTIL_LOG(INFO, "server start success! pid=%ld", (int64_t)getpid());

    // 添加
    {
        autil::ScopedLock lock(G_CMD_LOCK);
        _next = G_CMD_LIST;
        G_CMD_LIST = this;
    }

    waitSig();

    _server->wait();
    delete _server;
    _server = NULL;

    alog::Logger::shutdown();
    unlink(pidFile);

    autil::ScopedLock lock(G_CMD_LOCK);
    if (G_CMD_LIST == this) {
        G_CMD_LIST = _next;
    } else {
        for (CommandLine* prev = G_CMD_LIST; prev; prev = prev->_next) {
            if (prev->_next == this) {
                prev->_next = _next;
                break;
            }
        }
    }
    return 0;
}