コード例 #1
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
void check_arguments() {
    if (oj_solution.sid == 0) {
        FM_LOG_FATAL("Miss parameter: solution id");
        exit(EXIT_MISS_PARAM);
    }
    if (oj_solution.pid == 0) {
        FM_LOG_FATAL("Miss parameter: problem id");
        exit(EXIT_MISS_PARAM);
    }
    if (strlen(data_dir_root) == 0) {
        FM_LOG_FATAL("Miss parameter: data directory");
        exit(EXIT_MISS_PARAM);
    }

    switch (oj_solution.lang) {
        case LANG_C99:
        case LANG_C11:
        case LANG_CPP98:
        case LANG_CPP11:
        case LANG_CPP14:
        case LANG_CPP17:
        case LANG_PASCAL:
        case LANG_JAVA:
        case LANG_PYTHON27:
        case LANG_PYTHON3:
        case LANG_KOTLIN:
            break;
        default:
            FM_LOG_FATAL("Unknown language id: %d", oj_solution.lang);
            exit(EXIT_BAD_PARAM);
    }
}
コード例 #2
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
void set_compile_limit() {
    if (oj_solution.lang == LANG_JAVA || oj_solution.lang == LANG_PYTHON27 || oj_solution.lang == LANG_PYTHON3 ||
        oj_solution.lang == LANG_KOTLIN)
        return;

    rlimit lim{};
    lim.rlim_cur = lim.rlim_max = compile_time_limit / 1000;
    if (setrlimit(RLIMIT_CPU, &lim) < 0) {
        FM_LOG_FATAL("setrlimit RLIMIT_CPU failed: %s", strerror(errno));
        exit(EXIT_SET_LIMIT);
    }

    if (EXIT_SUCCESS != malarm(ITIMER_REAL, compile_time_limit)) {
        FM_LOG_FATAL("malarm for compiler failed: %s", strerror(errno));
        exit(EXIT_SET_LIMIT);
    }

    lim.rlim_cur = lim.rlim_max = compile_memory_limit * STD_MB;
    if (setrlimit(RLIMIT_AS, &lim) < 0) {
        FM_LOG_FATAL("setrlimit RLIMIT_AS failed: %s", strerror(errno));
        exit(EXIT_SET_LIMIT);
    }

    lim.rlim_cur = lim.rlim_max = compile_fsize_limit * STD_MB;
    if (setrlimit(RLIMIT_FSIZE, &lim) < 0) {
        FM_LOG_FATAL("setrlimit RLIMIT_FSIZE failed: %s", strerror(errno));
        exit(EXIT_SET_LIMIT);
    }

    FM_LOG_DEBUG("set compile limit ok");
}
コード例 #3
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
// Run spj
int oj_compare_output_spj(const char *file_in,    // std input file
                          const char *file_out,   // std output file
                          const char *file_user,  // user output file
                          const char *spj_exec)   // path of spj
{
    FM_LOG_TRACE("start compare spj");

    pid_t pid_spj = fork();  // create a child process for spj
    if (pid_spj < 0) {
        FM_LOG_FATAL("fork for spj failed: %s", strerror(errno));
        exit(EXIT_COMPARE_SPJ);
    } else if (pid_spj == 0) {  // child process
        log_add_info("spj");

        // Set spj timeout
        if (EXIT_SUCCESS == malarm(ITIMER_REAL, spj_time_limit)) {
            FM_LOG_TRACE("load spj: %s", spj_exec);
            execlp(spj_exec, spj_exec, file_in, file_out, file_user, NULL);
            FM_LOG_FATAL("execute spj failed");
            exit(EXIT_COMPARE_SPJ_FORK);
        } else {
            FM_LOG_FATAL("malarm for spj failed: %s", strerror(errno));
            exit(EXIT_COMPARE_SPJ);
        }
    } else {
        int status = 0;
        if (waitpid(pid_spj, &status, 0) < 0) {
            FM_LOG_FATAL("waitpid for spj failed: %s", strerror(errno));
            exit(EXIT_COMPARE_SPJ);
        }

        if (WIFEXITED(status)) {
            switch (WEXITSTATUS(status)) {
                case SPJ_AC:
                    return OJ_AC;
                case SPJ_PE:
                    return OJ_PE;
                case SPJ_WA:
                    return OJ_WA;
                default:
                    return OJ_VE;
            }
        } else if (WIFSIGNALED(status) && WTERMSIG(status) == SIGALRM) {
            // recv SIGNALRM
            FM_LOG_WARNING("spj: time out");
        } else {
            // spj RE
            FM_LOG_WARNING("unkown termination, status = %d", status);
        }
    }
    return OJ_VE;
}
コード例 #4
0
int main(int argc, char *argv[]) {

    log_open("./core_log.txt"); //或许写成参数更好,懒得写了

    atexit(output_result);  //退出程序时的回调函数,用于输出判题结果

    //为了构建沙盒,必须要有root权限
    if (geteuid() != 0) {
        FM_LOG_FATAL("You must run this program as root.");
        exit(JUDGE_CONF::EXIT_UNPRIVILEGED);
    }

    parse_arguments(argc, argv);

    JUDGE_CONF::JUDGE_TIME_LIMIT += PROBLEM::time_limit;

    if (EXIT_SUCCESS != malarm(ITIMER_REAL, JUDGE_CONF::JUDGE_TIME_LIMIT)) {
        FM_LOG_WARNING("Set the alarm for this judge program failed, %d: %s", errno, strerror(errno));
        exit(JUDGE_CONF::EXIT_VERY_FIRST);
    }
    signal(SIGALRM, timeout);

    compiler_source_code();

    judge();

    if (PROBLEM::spj) {
        run_spj();
    } else {
        if (PROBLEM::result == JUDGE_CONF::SE)
            PROBLEM::result = compare_output(PROBLEM::output_file, PROBLEM::exec_output);
    }

    return 0;
}
コード例 #5
0
ファイル: platform_config.c プロジェクト: huiweics/IES
/* fmPlatformCfgSchedulerGetTokenList
 * \ingroup intPlatform
 *
 * \desc            Configure the scheduler token list for manual mode based
 *                  on the given switch.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \param[out]      schedTokenList is a pointer to the caller-supplied
 *                  scheduler token list structure and should be filled
 *                  with the scheduler properties of the specified switch.
 *                  Refer to fm_schedulerToken for details on the limits
 *                  of certains structure fields and which fields
 *                  are required.
 *
 * \return          the number of tokens configured in the schedTokenList.
 * \return          0 if no configuration token were found in the properties.
 *
 *****************************************************************************/
fm_int fmPlatformCfgSchedulerGetTokenList(fm_int sw,
                                          fm_schedulerToken *schedTokenList)
{
    FM_LOG_FATAL(FM_LOG_CAT_PLATFORM,
                 "No support for scheduler manual mode\n");

    FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, 0);

}   /* end fmPlatformCfgSchedulerGetTokenList */
コード例 #6
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
void io_redirect(const char *input_file, const char *stdout_file, const char *stderr_file) {
    // io_redirect
    stdin = freopen(input_file, "r", stdin);
    stdout = freopen(stdout_file, "w", stdout);
    stderr = freopen(stderr_file, "a+", stderr);

    if (stdin == nullptr || stdout == nullptr || stderr == nullptr) {
        FM_LOG_FATAL("error freopen: stdin(%p) stdout(%p), stderr(%p)", stdin, stdout, stderr);
        exit(EXIT_PRE_JUDGE);
    }
    FM_LOG_TRACE("io redirect ok!");
}
コード例 #7
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
int main(int argc, char *argv[], char *envp[]) {
    if (nice(10) == -1) {  // increase nice value(decrease pripority)
        FM_LOG_WARNING("increase nice value failed: %s", strerror(errno));
    }

    init();

    parse_arguments(argc, argv);

    if (geteuid() == 0) {  // effective user is not root
        FM_LOG_FATAL("please do not run as root, run as judge");
        exit(EXIT_PRIVILEGED);
    }

    if (EXIT_SUCCESS != chdir(oj_solution.work_dir)) {  // change current directory
        FM_LOG_FATAL("chdir(%s) failed: %s", oj_solution.work_dir, strerror(errno));
        exit(EXIT_CHDIR);
    }
    FM_LOG_DEBUG("\n\x1b[31m----- Power Judge 1.0 -----\x1b[0m");

    judge_time_limit += oj_solution.time_limit;
    judge_time_limit *= get_num_of_test();

    if (EXIT_SUCCESS != malarm(ITIMER_REAL, judge_time_limit)) {
        FM_LOG_FATAL("set alarm for judge failed: %s", strerror(errno));
        exit(EXIT_VERY_FIRST);
    }

    if (signal(SIGALRM, timeout_hander) == SIG_ERR) {  // install signal hander for timeout
        FM_LOG_FATAL("cannot handle SIGALRM");
        exit(EXIT_VERY_FIRST);
    }
    init_connet();
    compile();

    run_solution();
    close_connet();
    return 0;
}
コード例 #8
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
void set_security_option() {
    if (oj_solution.lang != LANG_JAVA && oj_solution.lang != LANG_KOTLIN
#ifdef FAST_JUDGE
        && oj_solution.lang != LANG_PYTHON3 && oj_solution.lang != LANG_PYTHON27
#endif
            ) {
        char cwd[PATH_SIZE];
        char *tmp = getcwd(cwd, PATH_SIZE - 1);
        if (tmp == nullptr) {
            FM_LOG_FATAL("getcwd failed: %s", strerror(errno));
            exit(EXIT_SET_SECURITY);
        }

        // chroot, current directory will be the root dir
        if (EXIT_SUCCESS != chroot(cwd)) {
            FM_LOG_FATAL("chroot(%s) failed: %s", cwd, strerror(errno));
            exit(EXIT_SET_SECURITY);
        }
        FM_LOG_DEBUG("chroot(%s)", cwd);
    }

    FM_LOG_TRACE("set_security_option ok");
}
コード例 #9
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
void set_limit(off_t fsize) {
    rlimit lim{};

    // Set CPU time limit round up, raise SIGXCPU
    lim.rlim_max = (oj_solution.time_limit + 999) / 1000 + 1;
    lim.rlim_cur = lim.rlim_max;
    if (setrlimit(RLIMIT_CPU, &lim) < 0) {
        FM_LOG_FATAL("setrlimit RLIMIT_CPU failed: %s", strerror(errno));
        exit(EXIT_SET_LIMIT);
    }

    if (oj_solution.lang <= LANG_PASCAL) {
        // Memory control, raise SIGSEGV
        lim.rlim_cur = lim.rlim_max = (STD_MB << 10) + oj_solution.memory_limit * STD_KB;
        if (setrlimit(RLIMIT_AS, &lim) < 0) {
            FM_LOG_FATAL("setrlimit RLIMIT_AS failed: %s", strerror(errno));
            exit(EXIT_SET_LIMIT);
        }
    }

    // Stack space, raise SIGSEGV
    lim.rlim_cur = lim.rlim_max = stack_size_limit * STD_KB;
    if (setrlimit(RLIMIT_STACK, &lim) < 0) {
        FM_LOG_FATAL("setrlimit RLIMIT_STACK failed: %s", strerror(errno));
        exit(EXIT_SET_LIMIT);
    }

    // Output file size limit, raise SIGXFSZ
    lim.rlim_cur = lim.rlim_max = (rlim_t) (4 * MAX_LOG_FILE_SIZE);
    if (setrlimit(RLIMIT_FSIZE, &lim) < 0) {
        FM_LOG_FATAL("setrlimit RLIMIT_FSIZE failed: %s", strerror(errno));
        exit(EXIT_SET_LIMIT);
    }
    FM_LOG_DEBUG("File size limit: %d", lim.rlim_max);

    FM_LOG_TRACE("set execute limit ok");
}
コード例 #10
0
ファイル: judged.cpp プロジェクト: w703710691d/PowerJudge
void check_pid() {
    pid_t otherpid;

    FM_LOG_NOTICE("pid file: %s", PID_FILE);
    pfh = pidfile_open(PID_FILE, 0644, &otherpid);
    if (pfh == nullptr) {
        if (errno == EEXIST) {
            FM_LOG_FATAL("Daemon already running, pid: %jd", (intmax_t) otherpid);
            exit(EXIT_FAILURE);
        }

        /* If we cannot create pidfile from other reasons, only warn. */
        FM_LOG_WARNING("Cannot open or create pidfile");
    }
}
コード例 #11
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
int get_num_of_test() {
    struct dirent **namelist;
    int num_of_test;
    num_of_test = scandir(oj_solution.data_dir, &namelist, data_filter, alphasort);
    if (num_of_test < 0) {
        FM_LOG_FATAL("scan data directory failed: %s", strerror(errno));
        exit(EXIT_PRE_JUDGE_DAA);
    }
    for (int i = 0; i < num_of_test; ++i) {
        free(namelist[i]);
    }
    free(namelist);
    return num_of_test;

}
コード例 #12
0
ファイル: platform_config.c プロジェクト: huiweics/IES
/* fmPlatformGetSchedulerConfigMode
 * \ingroup intPlatform
 *
 * \desc            Get the scheduler configuration mode for the given switch.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \return          the scheduler configuration mode for the specified switch.
 *
 *****************************************************************************/
fm_schedulerConfigMode fmPlatformGetSchedulerConfigMode(fm_int sw)
{
    fm_platformCfgSwitch *swCfg;

    swCfg = FM_PLAT_GET_SWITCH_CFG(sw);

    if (swCfg->schedListSelect == FM_AAD_API_PLATFORM_SCHED_LIST_SELECT)
    {
        return (FM_SCHED_INIT_MODE_AUTOMATIC); 
    }
    else 
    {
        FM_LOG_FATAL(FM_LOG_CAT_PLATFORM,
                 "No support for scheduler manual mode\n");
        return (FM_SCHED_INIT_MODE_MANUAL);
    }

}   /* end fmPlatformGetSchedulerConfigMode */
コード例 #13
0
/** fm10000FastMaintenanceTask
 * \ingroup intFastMaint
 *
 * \desc            Chip-specific fast maintenance thread.
 * 
 * \note            The caller has ensured that the switch is UP and has
 *                  taken the switch protection lock.
 *
 * \param[in]       sw is the switch on which to operate
 *
 * \param[in]       args is the thread argument pointer.
 *
 * \return          None.
 *
 *****************************************************************************/
void * fm10000FastMaintenanceTask(fm_int sw, void *args)
{
    fm_status err;

    FM_NOT_USED(args);

    fm10000MacUsedTableSweeper(sw);

    err = fm10000MTablePeriodicMaintenance(sw);
    if (err != FM_OK)
    {
        FM_LOG_FATAL(FM_LOG_CAT_EVENT_FAST_MAINT, 
                     "MTableMaintenance returned error: %s\n" ,
                     fmErrorMsg(err));
    }

    return NULL;

}   /* end fm10000FastMaintenanceTask */
コード例 #14
0
ファイル: fm_api_parity.c プロジェクト: gdb-glibc/IES
/** fmSendParityErrorEvent
 * \ingroup intParity
 *
 * \desc            Send a Parity error event to the upper layer.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \param[in]       parityEvent contains the parity event error information.
 *
 * \param[in]       eventHandler points to the event handler to which the
 *                  parity event should be sent.
 *
 * \return          Should never exit.
 *
 *****************************************************************************/
fm_status fmSendParityErrorEvent(fm_int              sw, 
                                 fm_eventParityError parityEvent, 
                                 fm_thread *         eventHandler)
{
    fm_status            err;
    fm_event *           eventPtr;
    fm_eventParityError *parityErrEvent;

    FM_LOG_ENTRY(FM_LOG_CAT_PARITY,
                 "sw=%d ParityEvent=%p\n",
                 sw, (void *) &parityEvent);

    eventPtr = fmAllocateEvent(sw,
                               FM_EVID_SYSTEM,
                               FM_EVENT_PARITY_ERROR,
                               FM_EVENT_PRIORITY_LOW);

    if (eventPtr == NULL)
    {
        FM_LOG_FATAL(FM_LOG_CAT_PARITY, "Out of event buffers\n");
        FM_LOG_EXIT(FM_LOG_CAT_PARITY, FM_ERR_NO_EVENTS_AVAILABLE);
    }

    /* Init event structure */
    parityErrEvent = &eventPtr->info.fpParityErrorEvent;

    FM_MEMCPY_S( parityErrEvent,
                 sizeof(*parityErrEvent),
                 &parityEvent,
                 sizeof(parityEvent) );

    err = fmSendThreadEvent(eventHandler, eventPtr);

    if (err != FM_OK)
    {
        /* Free the event since we could not send it to thread */
        fmReleaseEvent(eventPtr);
    }

    FM_LOG_EXIT(FM_LOG_CAT_PARITY, err);

}   /* end fmSendParityErrorEvent */
コード例 #15
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
bool judge(const char *input_file,
           const char *output_file_std,
           const char *stdout_file_executive,
           const char *stderr_file_executive) {
    rusage rused{};
    pid_t executor = fork();  // create a child process for executor

    if (executor < 0) {
        FM_LOG_FATAL("fork executor failed: %s", strerror(errno));
        exit(EXIT_PRE_JUDGE);
    } else if (executor == 0) {  // child process
        log_add_info("executor");

        off_t fsize = file_size(output_file_std);

        // io redirect, must before set_security_option()
        io_redirect(input_file, stdout_file_executive, stderr_file_executive);

        // chroot & setuid
        set_security_option();

        // set memory, time and file size limit etc.
        set_limit(fsize);  // must after set_security_option()

        FM_LOG_DEBUG("time limit: %d, time limit addtion: %d",
                     oj_solution.time_limit, time_limit_addtion);


        uint64_t real_time_limit = oj_solution.time_limit + time_limit_addtion;  // time fix
        // set real time alarm
        if (EXIT_SUCCESS != malarm(ITIMER_REAL, real_time_limit)) {
            FM_LOG_FATAL("malarm for executor failed: %s", strerror(errno));
            exit(EXIT_PRE_JUDGE);
        }

        FM_LOG_TRACE("begin execute");

        if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) < 0) {
            FM_LOG_FATAL("Trace executor failed: %s", strerror(errno));
            exit(EXIT_PRE_JUDGE_PTRACE);
        }

        // load program
        if (oj_solution.lang == LANG_JAVA) {
            print_executor(EXEC_J);
            execvp(EXEC_J[0], (char *const *) EXEC_J);
        } else if (oj_solution.lang == LANG_KOTLIN) {
            print_executor(EXEC_KT);
            execvp(EXEC_KT[0], (char *const *) EXEC_KT);
        } else if (oj_solution.lang == LANG_PYTHON27) {
            print_executor(EXEC_PY27);
#ifdef FAST_JUDGE
            execvp(EXEC_PY27[0], (char * const *) EXEC_PY27);
#else
            execv(EXEC_PY27[0], (char *const *) EXEC_PY27);
#endif
        } else if (oj_solution.lang == LANG_PYTHON3) {
            print_executor(EXEC_PY3);
#ifdef FAST_JUDGE
            execvp(EXEC_PY3[0], (char * const *) EXEC_PY3);
#else
            execv(EXEC_PY3[0], (char *const *) EXEC_PY3);
#endif
        } else {
            execl("./Main", "./Main", NULL);
        }

        // exec error
        FM_LOG_FATAL("exec error");
        exit(EXIT_PRE_JUDGE_EXECLP);
    } else {
        // Judger
        int status = 0;
        user_regs_struct regs{};
        stderr = freopen("error.txt", "a+", stderr);

        init_syscalls(oj_solution.lang);

        while (true) {
            if (wait4(executor, &status, 0, &rused) < 0) {
                FM_LOG_FATAL("wait4 executor failed: %s", strerror(errno));
                kill(executor, SIGKILL);
                exit(EXIT_JUDGE);
            }

            if (WIFEXITED(status)) {
                if ((oj_solution.lang != LANG_JAVA && oj_solution.lang != LANG_KOTLIN) ||
                    WEXITSTATUS(status) == EXIT_SUCCESS) {
                    // AC PE WA
                    FM_LOG_TRACE("normal quit");
                    int result;
                    if (oj_solution.spj) {
                        // use SPJ
                        result = oj_compare_output_spj(input_file, output_file_std, stdout_file_executive,
                                                       oj_solution.spj_exe_file);
                    } else {
                        // compare file
                        result = oj_compare_output(output_file_std, stdout_file_executive);
                    }
                    // WA
                    if (result == OJ_WA) {
                        oj_solution.result = OJ_WA;
                    } else if (oj_solution.result != OJ_PE) {  // previous case is AC
                        oj_solution.result = result;  // AC or PE
                    } else /* (oj_solution.result == OJ_PE) */ {  // previous case is PE
                        oj_solution.result = OJ_PE;
                    }
                    FM_LOG_NOTICE("case result: %d, problem result: %d", result, oj_solution.result);
                } else {
                    // not return 0
                    oj_solution.result = OJ_RE;
                    FM_LOG_NOTICE("abnormal quit, exit_code: %d", WEXITSTATUS(status));
                }
                break;
            }

            // RE/TLE/OLE
            if (WIFSIGNALED(status) || (WIFSTOPPED(status) && WSTOPSIG(status) != SIGTRAP)) {
                int signo = 0;
                if (WIFSIGNALED(status)) {
                    signo = WTERMSIG(status);
                    FM_LOG_NOTICE("child process killed by signal %d, %s", signo, strsignal(signo));
                } else {
                    signo = WSTOPSIG(status);
                    FM_LOG_NOTICE("child process stopped by signal %d, %s", signo, strsignal(signo));
                }
                switch (signo) {
                    // Ignore
                    case SIGCHLD:
                        oj_solution.result = OJ_AC;
                        break;
                        // TLE
                    case SIGALRM:    // alarm() and setitimer(ITIMER_REAL)
                    case SIGVTALRM:  // setitimer(ITIMER_VIRTUAL)
                    case SIGXCPU:    // exceeds soft processor limit
                        oj_solution.result = OJ_TLE;
                        FM_LOG_TRACE("Time Limit Exceeded: %s", strsignal(signo));
                        break;
                        // OLE
                    case SIGXFSZ:  // exceeds file size limit
                        oj_solution.result = OJ_OLE;
                        FM_LOG_TRACE("Output Limit Exceeded");
                        break;
                        // RE
                    case SIGSEGV:  // segmentation violation
                    case SIGFPE:   // any arithmetic exception
                    case SIGBUS:   // the process incurs a hardware fault
                    case SIGABRT:  // abort() function
                    case SIGKILL:  // exceeds hard processor limit
                    default:
                        oj_solution.result = OJ_RE;
                        FILE *fp = fopen(stderr_file_executive, "a+");
                        if (fp == nullptr) {
                            fprintf(stderr, "%s\n", strsignal(signo));
                            FM_LOG_WARNING("Runtime Error: %s", strsignal(signo));
                        } else {
                            fprintf(fp, "%s\n", strsignal(signo));
                            fclose(fp);
                        }
                        break;
                }  // end of swtich
                kill(executor, SIGKILL);
                break;
            }  // end of  "if (WIFSIGNALED(status) ...)"

            oj_solution.memory_usage = std::max(oj_solution.memory_usage, (unsigned long) rused.ru_maxrss);
            // TODO(power): check why memory exceed too much
            if (oj_solution.memory_usage > oj_solution.memory_limit) {
                oj_solution.result = OJ_MLE;
                kill(executor, SIGKILL);
                break;
            }

            // check syscall
            if (ptrace(PTRACE_GETREGS, executor, NULL, &regs) < 0) {
                FM_LOG_FATAL("ptrace(PTRACE_GETREGS) failed: %s", strerror(errno));
                kill(executor, SIGKILL);
                exit(EXIT_JUDGE);
            }
            int syscall_id = 0;
#ifdef __i386__
            syscall_id = (int)regs.orig_eax;
#else
            syscall_id = (int) regs.orig_rax;
#endif
            if (syscall_id > 0 && !is_valid_syscall(syscall_id)) {
                oj_solution.result = OJ_RF;
                FM_LOG_FATAL("restricted function, syscall_id: %d", syscall_id);
                kill(executor, SIGKILL);
                break;
            }

            if (ptrace(PTRACE_SYSCALL, executor, NULL, NULL) < 0) {
                FM_LOG_FATAL("ptrace(PTRACE_SYSCALL) failed: %s", strerror(errno));
                kill(executor, SIGKILL);
                exit(EXIT_JUDGE);
            }
        }  // end of while
    }  // end of fork for judge process

    oj_solution.memory_usage = std::max(oj_solution.memory_usage, (unsigned long) rused.ru_maxrss);
    if (oj_solution.memory_usage > oj_solution.memory_limit) {
        oj_solution.result = OJ_MLE;
        FM_LOG_NOTICE("memory limit exceeded: %d (fault: %d * %d)",
                      oj_solution.memory_usage, rused.ru_minflt, page_size);
    }

    oj_solution.time_usage = std::max(oj_solution.time_usage,
                                      (unsigned long) rused.ru_utime.tv_sec * 1000 + rused.ru_utime.tv_usec / 1000);

    if (oj_solution.time_usage > oj_solution.time_limit) {
        oj_solution.result = OJ_TLE;
        FM_LOG_TRACE("Time Limit Exceeded");
    }

    if (oj_solution.result != OJ_AC) {
        if (oj_solution.judge_type == ACM) {
            FM_LOG_NOTICE("not AC/PE, no need to continue");
        }
        if (oj_solution.result == OJ_TLE) {
            oj_solution.time_usage = oj_solution.time_limit;
        } else if (oj_solution.result == OJ_WA) {
            if (oj_solution.lang == LANG_JAVA) { // TODO: kotlin
                fix_java_result(stdout_file_executive, stderr_file_executive);
            } else if ((oj_solution.lang == LANG_PYTHON27 || oj_solution.lang == LANG_PYTHON3) &&
                       file_size(stderr_file_executive)) {
                oj_solution.result = OJ_RE;
                FM_LOG_TRACE("Runtime Error");
            }
        }
        return false;
    }
    return true;
}
コード例 #16
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
void run_solution() {
    FM_LOG_DEBUG("run_solution");
#ifndef FAST_JUDGE
    if (oj_solution.lang == LANG_PYTHON27) {
        copy_python_runtime_python2(oj_solution.work_dir);
        FM_LOG_DEBUG("copy_python_runtime");
    } else if (oj_solution.lang == LANG_PYTHON3) {
        copy_python_runtime_python3(oj_solution.work_dir);
        FM_LOG_DEBUG("copy_python_runtime");
    }
#endif

    check_spj();

    struct dirent **namelist;
    int num_of_test;

    num_of_test = scandir(oj_solution.data_dir, &namelist, data_filter, alphasort);
    if (num_of_test < 0) {
        FM_LOG_FATAL("scan data directory failed: %s", strerror(errno));
        exit(EXIT_PRE_JUDGE_DAA);
    }

    int first_failed_test = 0;
    char input_file[PATH_SIZE];
    char output_file_std[PATH_SIZE];
    char stdout_file_executive[PATH_SIZE];
    char stderr_file_executive[PATH_SIZE];

    snprintf(stderr_file_executive, PATH_SIZE, "%s/stderr_executive.txt", oj_solution.work_dir);
    FM_LOG_DEBUG("start run solution (%d cases)", num_of_test);

    for (int i = 0; i < num_of_test; ++i) {
        update_solution_status(oj_solution.cid, oj_solution.sid, OJ_RUN, i + 1);

        prepare_files(namelist[i]->d_name, input_file, output_file_std, stdout_file_executive);

        FM_LOG_TRACE("run case: %d", i + 1);

        bool result = judge(input_file, output_file_std, stdout_file_executive, stderr_file_executive);

        if (oj_solution.result != OJ_AC && !first_failed_test) {
            first_failed_test = i + 1;
        }

        if (!result && oj_solution.judge_type == ACM) {
            break;
        }
    }

    for (int i = 0; i < num_of_test; ++i) {
        free(namelist[i]);
    }
    free(namelist);

#ifndef FAST_JUDGE
    if (oj_solution.lang == LANG_PYTHON27 || oj_solution.lang == LANG_PYTHON3) {
        clean_workdir(oj_solution.work_dir);
    }
#endif

    output_acm_result(oj_solution.result, oj_solution.time_usage, oj_solution.memory_usage, first_failed_test);
}
コード例 #17
0
ファイル: judged.cpp プロジェクト: w703710691d/PowerJudge
void run(oj_solution_t &oj_solution) {
    if (oj_solution.cid > 0) {
        snprintf(oj_solution.work_dir, PATH_SIZE, "%s/c%d", oj_config.temp_dir, oj_solution.cid);
    } else {
        strncpy(oj_solution.work_dir, oj_config.temp_dir, strlen(oj_config.temp_dir) + 1);
    }
    char stderr_file[PATH_SIZE];
    snprintf(stderr_file, PATH_SIZE, "%s/%s/error.txt", oj_solution.work_dir, oj_solution.sid);
    FM_LOG_NOTICE("/usr/local/bin/powerjudge -s %s -p %s -l %s -t %s -m %s -w %s -D %s",
                  oj_solution.sid, oj_solution.pid, oj_solution.language,
                  oj_solution.time_limit, oj_solution.memory_limit,
                  oj_solution.work_dir, oj_config.data_dir);
    pid_t pid = fork();
    if (pid < 0) {
        FM_LOG_FATAL("fork judger failed: %s", strerror(errno));
        SendQueue.push(std::make_pair(EXIT_FORK_ERROR, oj_solution));
    } else if (pid == 0) {
        execl("/usr/local/bin/powerjudge",
              "/usr/local/bin/powerjudge",
              "-s", oj_solution.sid,
              "-p", oj_solution.pid,
              "-l", oj_solution.language,
              "-t", oj_solution.time_limit,
              "-m", oj_solution.memory_limit,
              "-w", oj_solution.work_dir,
              "-D", oj_config.data_dir,
              "-c", std::to_string(oj_solution.cid).c_str(),
              NULL);
        stderr = freopen(stderr_file, "a+", stderr);
        FM_LOG_FATAL("exec error: %s", strerror(errno));
        SendQueue.push(std::make_pair(EXIT_EXEC_ERROR, oj_solution));
    } else {
        int status = 0;
        FM_LOG_TRACE("process ID=%d", pid);
        if (waitpid(pid, &status, WUNTRACED) == -1) {
            FM_LOG_FATAL("waitpid for judger failed: %s", strerror(errno));
        }

        if (WIFEXITED(status))    // normal termination
        {
            if (EXIT_SUCCESS == WEXITSTATUS(status)) {
                FM_LOG_DEBUG("judge succeeded");
                SendQueue.push(std::make_pair(EXIT_OK, oj_solution));
            } else if (EXIT_COMPILE_ERROR == WEXITSTATUS(status)) {
                FM_LOG_TRACE("compile error");
                SendQueue.push(std::make_pair(EXIT_OK, oj_solution));
            } else if (EXIT_JUDGE == WEXITSTATUS(status)) {
                FM_LOG_TRACE("judge error");
                SendQueue.push(std::make_pair(OJ_SE, oj_solution));
            } else {
                FM_LOG_TRACE("judge error");
                SendQueue.push(std::make_pair(WEXITSTATUS(status), oj_solution));
            }
        } else {
            if (WIFSIGNALED(status))    // killed by signal
            {
                int signo = WTERMSIG(status);
                FM_LOG_WARNING("judger killed by signal: %s", strsignal(signo));
                SendQueue.push(std::make_pair(signo, oj_solution));
            } else if (WIFSTOPPED(status))      // stopped by signal
            {
                int signo = WSTOPSIG(status);
                FM_LOG_FATAL("judger stopped by signal: %s\n", strsignal(signo));
                SendQueue.push(std::make_pair(signo, oj_solution));
            } else {
                FM_LOG_FATAL("judger stopped with unknown reason, status(%d)", status);
                SendQueue.push(std::make_pair(EXIT_UNKNOWN, oj_solution));
            }
        }
    }
}
コード例 #18
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
/*
 * #error "This make CE"
 * #warning "Just warning message"
 * #include </dev/core>
 * #include </dev/zero>
 * #include </dev/random>
 * #include </etc/passwd>
 * #include <../../../etc/passwd>
 * egrep '^\s*#include\s*[<"][./].*[>"]' Main.cc
 */
void compile() {
    update_solution_status(oj_solution.cid, oj_solution.sid, OJ_COM, 0);
    char stdout_compiler[PATH_SIZE];
    char stderr_compiler[PATH_SIZE];
    snprintf(stdout_compiler, PATH_SIZE, "%s/stdout_compiler.txt", oj_solution.work_dir);
    snprintf(stderr_compiler, PATH_SIZE, "%s/stderr_compiler.txt", oj_solution.work_dir);

    pid_t compiler = fork();  // create a child process for compiler

    if (compiler < 0) {
        FM_LOG_FATAL("fork compiler failed: %s", strerror(errno));
        exit(EXIT_FORK_COMPILER);
    } else if (compiler == 0) {
        // child process: run compiler
        log_add_info("compiler");

        set_compile_limit();

        stdout = freopen(stdout_compiler, "w", stdout);
        stderr = freopen(stderr_compiler, "w", stderr);
        if (stdout == nullptr || stderr == nullptr) {
            FM_LOG_FATAL("error freopen: stdout(%p), stderr(%p)", stdout, stderr);
            exit(EXIT_COMPILE_IO);
        }
        print_user_group();
        print_word_dir();

        switch (oj_solution.lang) {
            case LANG_C99:
                print_compiler(CP_C99);
                execvp(CP_C99[0], (char *const *) CP_C99);
                break;
            case LANG_C11:
                print_compiler(CP_C11);
                execvp(CP_C11[0], (char *const *) CP_C11);
                break;
            case LANG_CPP98:
                print_compiler(CP_CC98);
                execvp(CP_CC98[0], (char *const *) CP_CC98);
                break;
            case LANG_CPP11:
                print_compiler(CP_CC11);
                execvp(CP_CC11[0], (char *const *) CP_CC11);
                break;
            case LANG_CPP14:
                print_compiler(CP_CC14);
                execvp(CP_CC14[0], (char *const *) CP_CC14);
                break;
            case LANG_CPP17:
                print_compiler(CP_CC98);
                execvp(CP_CC98[0], (char *const *) CP_CC17);
                break;
            case LANG_PASCAL:
                print_compiler(CP_PAS);
                execvp(CP_PAS[0], (char *const *) CP_PAS);
                break;
            case LANG_JAVA:
                print_compiler(CP_J);
                execvp(CP_J[0], (char *const *) CP_J);
                break;
            case LANG_PYTHON27:
                print_compiler(CP_PY27);
                execvp(CP_PY27[0], (char *const *) CP_PY27);
                break;
            case LANG_PYTHON3:
                print_compiler(CP_PY3);
                execvp(CP_PY3[0], (char *const *) CP_PY3);
                break;
            case LANG_KOTLIN:
                print_compiler(CP_KT);
                execvp(CP_KT[0], (char *const *) CP_KT);
                break;
            default:
                FM_LOG_FATAL("Unknown language %d", oj_solution.lang);
                break;
        }

        // execvp error
        FM_LOG_FATAL("execvp compiler error");
        exit(EXIT_COMPILE_EXEC);
    } else {
        // parent process: Judger
        int status = 0;
        if (waitpid(compiler, &status, WUNTRACED) == -1) {
            FM_LOG_FATAL("waitpid for compiler failed: %s", strerror(errno));
            exit(EXIT_COMPILE_ERROR);  // SE
        }
        FM_LOG_DEBUG("compiler finished");

        if ((oj_solution.lang == LANG_PYTHON27 || oj_solution.lang == LANG_PYTHON3) && file_size(stderr_compiler)) {
            FM_LOG_TRACE("compile error");
            output_acm_result(OJ_CE, 0, 0, 0);
            exit(EXIT_OK);
        }

        if (WIFEXITED(status)) {  // normal termination
            if (EXIT_SUCCESS == WEXITSTATUS(status)) {
                FM_LOG_DEBUG("compile succeeded");
            } else if (GCC_COMPILE_ERROR == WEXITSTATUS(status)) {
                FM_LOG_TRACE("compile error");
                output_acm_result(OJ_CE, 0, 0, 0);
                exit(EXIT_OK);
            } else {
                if (fix_gcc_result(stderr_compiler)) {
                    FM_LOG_WARNING("Compiler Limit Exceeded!");
                    output_acm_result(OJ_CE, 0, 0, 0);
                    exit(EXIT_OK);
                } else {
                    FM_LOG_FATAL("compiler unknown exit status %d", WEXITSTATUS(status));
                    output_acm_result(OJ_CE, 0, 0, 0);
                    exit(EXIT_COMPILE_ERROR);
                }
            }
        } else {
            if (WIFSIGNALED(status)) {  // killed by signal
                int signo = WTERMSIG(status);
                FM_LOG_WARNING("Compiler Limit Exceeded: %s", strsignal(signo));
                output_acm_result(OJ_CE, 0, 0, 0);
                stderr = freopen(stderr_compiler, "w", stderr);
                fprintf(stderr, "Compiler Limit Exceeded: %s\n", strsignal(signo));
                exit(EXIT_OK);
            } else if (WIFSTOPPED(status)) {  // stopped by signal
                int signo = WSTOPSIG(status);
                FM_LOG_FATAL("stopped by signal: %s\n", strsignal(signo));
            } else {
                FM_LOG_FATAL("unknown stop reason, status(%d)", status);
            }
            exit(EXIT_COMPILE_ERROR);  // SE
        }
    }
}
コード例 #19
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
void timeout_hander(int signo) {
    if (signo == SIGALRM) {
        FM_LOG_FATAL("Judge Timeout");
        exit(EXIT_TIMEOUT);
    }
}
コード例 #20
0
ファイル: judged.cpp プロジェクト: w703710691d/PowerJudge
int main(int argc, char *argv[], char *envp[]) {
    log_open(LOG_FILE);
    FM_LOG_TRACE("---");
    check_pid();

    int sockfd;
    socklen_t clilen;
    struct sockaddr_in serv_addr{};
    struct sockaddr_in cli_addr{};
    const char *cfg_file;

    if (argc > 1) {
        cfg_file = argv[1];
    } else {
        cfg_file = DEFAULT_CFG_FILE;
    }
    read_config(cfg_file);
    FM_LOG_TRACE("read_config");

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        fatal_error("ERROR opening socket");
    }
    FM_LOG_TRACE("socket");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    if (inet_aton(oj_config.ip, &serv_addr.sin_addr) == 0) {
        serv_addr.sin_addr.s_addr = INADDR_ANY;
    }
    serv_addr.sin_port = htons(oj_config.port);
    FM_LOG_NOTICE("IP address: %s %s", oj_config.ip, inet_ntoa(serv_addr.sin_addr));
    FM_LOG_NOTICE("port: %d %d", oj_config.port, ntohs(serv_addr.sin_port));

    int yes = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
        fatal_error("setsockopt SO_REUSEADDR failed");
    }

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        fatal_error("ERROR on binding");
    }
    FM_LOG_TRACE("bind");

    clilen = sizeof(cli_addr);

    if (listen(sockfd, oj_config.backlog) < 0) {
        fatal_error("ERROR on listening");
    }
    FM_LOG_NOTICE("listen  backlog: %d", oj_config.backlog);

    if (daemon(0, 0) == -1) {
        FM_LOG_FATAL("Cannot daemonize");
        pidfile_remove(pfh);

        exit(EXIT_FAILURE);
    }

    print_word_dir();
    print_user_group();

    pidfile_write(pfh);

    struct sigaction sa{};
    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGTERM, &sa, nullptr) == -1) {   // install signal hander for timeout
        FM_LOG_FATAL("cannot handle SIGTERM");
        exit(EXIT_FAILURE);
    } else {
        FM_LOG_DEBUG("set signal_handler");
    }
    for (int i = 0; i < oj_config.thread_num; i++) {
        std::thread t(ThreadWork);
        t.detach();
    }
    FM_LOG_NOTICE("thread count: %d", oj_config.thread_num);

    std::thread(SendWork).detach();

    while (isRunning) {
        int newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
        if (newsockfd != -1) {
            work(newsockfd, cli_addr);
        }
    }

    pidfile_remove(pfh);
    close(sockfd);
    return 0;
}
コード例 #21
0
ファイル: fm_netsock.c プロジェクト: huiweics/IES
/** fmCreateNetworkClient
 * \ingroup platformUtil
 *
 * \desc            Creates a network client socket.
 *
 * \param[out]      socketInfo points to the information structure for the
 *                  client socket.
 *
 * \param[in]       type is the type of socket to create.
 *
 * \param[in]       host points to a string specifying the hostname.
 *
 * \param[in]       port is the port number.
 *
 * \return          FM_OK if successful.
 *
 *****************************************************************************/
fm_status fmCreateNetworkClient(fm_socket *   socketInfo, 
                                fm_socketType type,
                                fm_text       host, 
                                fm_int        port)
{
    struct hostent  h;
    struct hostent *hp;
    fm_int          errResult;
    char            strErrBuf[FM_STRERROR_BUF_SIZE];
    errno_t         strErrNum;
    char            buf[FM_GETHOSTBYNAME_BUF_SIZE];
    int             herrno;

    FM_LOG_ENTRY_VERBOSE(FM_LOG_CAT_PLATFORM,
                         "socketInfo=%p, port=%d\n",
                         (void *) socketInfo, 
                         port);

    if (!socketInfo)
    {
        FM_LOG_EXIT_VERBOSE(FM_LOG_CAT_PLATFORM, FM_ERR_INVALID_ARGUMENT);
    }

    FM_CLEAR(*socketInfo);

    if (type == FM_SOCKET_TYPE_TCP)
    {
        socketInfo->sock = socket(AF_INET, SOCK_STREAM, 0);
    }
    else if (type == FM_SOCKET_TYPE_UDP)
    {
        socketInfo->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    }

    if (socketInfo->sock == -1)
    {
        FM_LOG_FATAL(FM_LOG_CAT_PLATFORM,
                     "Unable to create socket type %d\n",
                     type);
        FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_FAIL);
    }

    FM_CLEAR(socketInfo->address);

    socketInfo->address.sin_family = AF_INET;

    if ((gethostbyname_r(host,
                         &h,
                         buf,
                         FM_GETHOSTBYNAME_BUF_SIZE,
                         &hp,
                         &herrno) != 0)
        || (hp == NULL))
    {
        FM_LOG_FATAL(FM_LOG_CAT_PLATFORM,
                     "Unable to resolve hostname: %s\n", 
                     host);
    }

    FM_LOG_SYS_EXIT_ON_COND(FM_LOG_CAT_PLATFORM, !hp);

    FM_MEMCPY_S(&socketInfo->address.sin_addr.s_addr,
                sizeof(socketInfo->address.sin_addr.s_addr),
                hp->h_addr,
                hp->h_length);

    socketInfo->address.sin_port = htons(port);

    if (type == FM_SOCKET_TYPE_TCP)
    {
        errResult = connect(socketInfo->sock,
                            (struct sockaddr *) &socketInfo->address,
                            SOCKET_ADDRLEN);
        FM_LOG_SYS_EXIT_ON_COND(FM_LOG_CAT_PLATFORM, errResult != 0);
    }

    FM_LOG_EXIT_VERBOSE(FM_LOG_CAT_PLATFORM, FM_OK);

}   /* end fmCreateNetworkClient */
コード例 #22
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
void parse_arguments(int argc, char *argv[]) {
    int opt;

    while ((opt = getopt(argc, argv, "s:p:t:m:l:w:d:D:j:c:")) != -1) {
        switch (opt) {
            case 's':  // Solution ID
                oj_solution.sid = atoi(optarg);
                break;
            case 'p':  // Problem ID
                oj_solution.pid = atoi(optarg);
                break;
            case 'l':  // Language ID
                oj_solution.lang = atoi(optarg);
                break;
            case 'j':  // judge type
                oj_solution.judge_type = atoi(optarg);
                break;
            case 't':  // Time limit
                oj_solution.time_limit = (unsigned int) atoi(optarg);
                break;
            case 'm':  // Memory limit
                oj_solution.memory_limit = (unsigned int) atoi(optarg);
                break;
            case 'w':
            case 'd':  // Work directory
                if (realpath(optarg, work_dir_root) == nullptr) {
                    fprintf(stderr, "resolve work dir failed:%s\n", strerror(errno));
                    exit(EXIT_BAD_PARAM);
                }
                break;
            case 'D':  // Data directory
                if (realpath(optarg, data_dir_root) == nullptr) {
                    fprintf(stderr, "resolve data dir failed: %s\n", strerror(errno));
                    exit(EXIT_BAD_PARAM);
                }
                break;
            case 'c':  // Contest ID
                oj_solution.cid = atoi(optarg);
                break;
            default:
                fprintf(stderr, "unknown option provided: -%c %s\n", opt, optarg);
                exit(EXIT_BAD_PARAM);
        }
    }
    char buff[PATH_SIZE];
    snprintf(buff, PATH_SIZE, "%s/oj-judge.log", work_dir_root);
    check_and_rename_log(buff);
    log_open(buff);

    check_arguments();

    snprintf(oj_solution.work_dir, PATH_SIZE, "%s/%d", work_dir_root, oj_solution.sid);
    snprintf(oj_solution.data_dir, PATH_SIZE, "%s/%d", data_dir_root, oj_solution.pid);

    char source_file[PATH_SIZE];
    snprintf(source_file, PATH_SIZE, "%s/Main.%s", oj_solution.work_dir, lang_ext[oj_solution.lang]);
    if (access(source_file, F_OK) == -1) {
        FM_LOG_FATAL("Source code file is missing.");
        exit(EXIT_NO_SOURCE_CODE);
    }

    if (oj_solution.lang == LANG_JAVA) {
        oj_solution.memory_limit *= java_memory_factor;
        oj_solution.time_limit *= java_time_factor;
    } else if (oj_solution.lang == LANG_PYTHON27 || oj_solution.lang == LANG_PYTHON3) {
        oj_solution.memory_limit *= python_memory_factor;
        oj_solution.time_limit *= python_time_factor;
    } else if (oj_solution.lang == LANG_KOTLIN) {
        oj_solution.memory_limit *= kotlin_memory_factor;
        oj_solution.time_limit *= kotlin_time_factor;
    }

    snprintf(buff, PATH_SIZE, "%s/last", work_dir_root);
    unlink(buff);
    if (symlink(oj_solution.work_dir, buff) == -1) {
        FM_LOG_NOTICE("make symlink for %s failed: %s", buff, strerror(errno));
    }

    print_solution();
}
コード例 #23
0
ファイル: judged.cpp プロジェクト: w703710691d/PowerJudge
void send_multi_result(char *file_path, oj_solution_t &oj_solution) {
    FM_LOG_TRACE("send_multi_result");
    CURL *curl;

    CURLM *multi_handle;
    int still_running = 1;

    struct curl_httppost *formpost = nullptr;
    struct curl_httppost *lastptr = nullptr;
    struct curl_slist *headerlist = nullptr;
    static const char buf[] = "Expect:";
    const size_t size = 25;
    char data[size] = {0};
    curl_formadd(&formpost,
                 &lastptr,
                 CURLFORM_COPYNAME, "sid",
                 CURLFORM_COPYCONTENTS, oj_solution.sid,
                 CURLFORM_END);

    curl_formadd(&formpost,
                 &lastptr,
                 CURLFORM_COPYNAME, "token",
                 CURLFORM_COPYCONTENTS, oj_solution.token,
                 CURLFORM_END);

    snprintf(data, size, "%d", oj_solution.cid);
    curl_formadd(&formpost,
                 &lastptr,
                 CURLFORM_COPYNAME, "cid",
                 CURLFORM_COPYCONTENTS, data,
                 CURLFORM_END);

    snprintf(data, size, "%d", oj_solution.result);
    curl_formadd(&formpost,
                 &lastptr,
                 CURLFORM_COPYNAME, "result",
                 CURLFORM_COPYCONTENTS, data,
                 CURLFORM_END);

    snprintf(data, size, "%d", oj_solution.time_usage);
    curl_formadd(&formpost,
                 &lastptr,
                 CURLFORM_COPYNAME, "time",
                 CURLFORM_COPYCONTENTS, data,
                 CURLFORM_END);

    snprintf(data, size, "%d", oj_solution.memory_usage);
    curl_formadd(&formpost,
                 &lastptr,
                 CURLFORM_COPYNAME, "memory",
                 CURLFORM_COPYCONTENTS, data,
                 CURLFORM_END);

    snprintf(data, size, "%d", oj_solution.test);
    curl_formadd(&formpost,
                 &lastptr,
                 CURLFORM_COPYNAME, "test",
                 CURLFORM_COPYCONTENTS, data,
                 CURLFORM_END);

    if (file_path != NULL && access(file_path, F_OK) != -1) {
        truncate_upload_file(file_path);
        FM_LOG_NOTICE("will upload error file %s", file_path);
        curl_formadd(&formpost,
                     &lastptr,
                     CURLFORM_COPYNAME, "error",
                     CURLFORM_FILE, file_path,
                     CURLFORM_END);
    }

    FM_LOG_TRACE("try curl_easy_init");
    curl = curl_easy_init();
    multi_handle = curl_multi_init();

    headerlist = curl_slist_append(headerlist, buf);
    if (curl && multi_handle) {
        FM_LOG_TRACE("curl_multi_init OK");
        curl_easy_setopt(curl, CURLOPT_URL, oj_config.api_url);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
        curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);

        curl_multi_add_handle(multi_handle, curl);

        curl_multi_perform(multi_handle, &still_running);

        do {
            struct timeval timeout{};
            int rc; /* select() return code */
            CURLMcode mc; /* curl_multi_fdset() return code */

            fd_set fdread;
            fd_set fdwrite;
            fd_set fdexcep;
            int maxfd = -1;

            long curl_timeo = -1;

            FD_ZERO(&fdread);
            FD_ZERO(&fdwrite);
            FD_ZERO(&fdexcep);

            /* set a suitable timeout to play around with */
            timeout.tv_sec = 1;
            timeout.tv_usec = 0;

            curl_multi_timeout(multi_handle, &curl_timeo);
            if (curl_timeo >= 0) {
                timeout.tv_sec = curl_timeo / 1000;
                if (timeout.tv_sec > 1)
                    timeout.tv_sec = 1;
                else
                    timeout.tv_usec = (curl_timeo % 1000) * 1000;
            }

            /* get file descriptors from the transfers */
            mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

            if (mc != CURLM_OK) {
                fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
                break;
            }

            if (maxfd == -1) {
#ifdef _WIN32
                Sleep(100);
                rc = 0;
#else
                /* Portable sleep for platforms other than Windows. */
                struct timeval wait = {0, 100 * 1000}; /* 100ms */
                rc = select(0, NULL, NULL, NULL, &wait);
#endif
            } else {
                /* Note that on some platforms 'timeout' may be modified by select().
                   If you need access to the original value save a copy beforehand. */
                rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
            }

            switch (rc) {
                case -1:
                    /* select error */
                    break;
                case 0:
                default:
                    /* timeout or readable/writable sockets */
                    curl_multi_perform(multi_handle, &still_running);
                    break;
            }
        } while (still_running);

        curl_multi_cleanup(multi_handle);

        curl_easy_cleanup(curl);

        curl_formfree(formpost);

        curl_slist_free_all(headerlist);
        FM_LOG_DEBUG("send_multi_result finished");
    } else {
        FM_LOG_FATAL("cannot init curl: %s", strerror(errno));
        update_system_error(EXIT_CURL_ERROR, oj_solution);
    }
}
コード例 #24
0
ファイル: fm_generic_rawsocket.c プロジェクト: gdb-glibc/IES
/** fmIsRawPacketSocketDeviceOperational
 * \ingroup intPlatformCommon
 *
 * \desc            If raw packet socket was initialized, it verifies that
 *                  the underlying network device is operational.
 *
 * \param[in]       sw refers to the switch number to send packets to.
 *
 * \param[out]      isRawSocket is a pointer to a variable specifying if raw
 *                  socket is used.
 *
 * \param[out]      mtu is a pointer to a variable storing mtu value of
 *                  the raw sockets network device.
 *
 * \return          TRUE if either raw packet socket was not initialized or
 *                  raw packet socket is initialized and the underlying network
 *                  device is operational.
 * \return          FALSE if raw packet socket is initialized and the underlying
 *                  network device is not operational.
 *
 *****************************************************************************/
fm_bool fmIsRawPacketSocketDeviceOperational(fm_int   sw,
                                             fm_bool *isRawSocket,
                                             fm_int * mtu)
{
    fm_switch    *switchPtr;
    char         strErrBuf[FM_STRERROR_BUF_SIZE];
    errno_t      strErrNum;
    struct ifreq ifr;

    FM_LOG_ENTRY(FM_LOG_CAT_PLATFORM, "sw=%d\n", sw);

    switchPtr = GET_SWITCH_PTR(sw);

    if (isRawSocket != NULL)
    {
        *isRawSocket = FM_DISABLED;
    }
    
    if (switchPtr->isRawSocketInitialized ==  FM_DISABLED)
    {
        FM_LOG_EXIT_CUSTOM(FM_LOG_CAT_PLATFORM, TRUE, "No raw packet socket\n");
    }

    FM_STRNCPY_S(ifr.ifr_name,
                 IF_NAMESIZE,
                 GET_PLAT_STATE(sw)->ifaceName,
                 IF_NAMESIZE);
    
    if (ioctl(GET_PLAT_STATE(sw)->rawSocket, SIOCGIFFLAGS, &ifr) == -1)
    {
        strErrNum = FM_STRERROR_S(strErrBuf, FM_STRERROR_BUF_SIZE, errno);
        if (strErrNum == 0)
        {
            FM_LOG_FATAL(FM_LOG_CAT_PLATFORM, 
                         "Failed to get socket %d flags for device %s: %s\n",
                         GET_PLAT_STATE(sw)->rawSocket,
                         ifr.ifr_name,
                         strErrBuf);
        }
        else
        {
            FM_LOG_FATAL(FM_LOG_CAT_PLATFORM, 
                         "Failed to get socket %d flags for device %s: %d\n",
                         GET_PLAT_STATE(sw)->rawSocket,
                         ifr.ifr_name,
                         errno);
        }
        FM_LOG_EXIT_CUSTOM(FM_LOG_CAT_PLATFORM, FALSE, "Not operational\n");
    }

    if ((ifr.ifr_flags & IFF_RUNNING) == 0)
    {    
        FM_LOG_WARNING(FM_LOG_CAT_PLATFORM,
                       "Network device %s resources are not allocated.\n",
                       ifr.ifr_name);
        FM_LOG_EXIT_CUSTOM(FM_LOG_CAT_PLATFORM, FALSE, "Not operational\n");
    }

    if (ioctl(GET_PLAT_STATE(sw)->rawSocket, SIOCGIFMTU, &ifr) == -1)
    {
        FM_LOG_WARNING(FM_LOG_CAT_SWITCH,
                       "WARNING: failed to read netdev MTU\n");
        FM_LOG_EXIT_CUSTOM(FM_LOG_CAT_PLATFORM,
                           FALSE,
                           "MTU could not be retrieved\n");
    }

    if ( (isRawSocket != NULL) && (mtu != NULL) )
    {
        *isRawSocket = FM_ENABLED;
        *mtu         = ifr.ifr_mtu;
    }

    FM_LOG_EXIT_CUSTOM(FM_LOG_CAT_PLATFORM, TRUE, "Operational\n");

} /* fmIsRawPacketSocketDeviceOperational */
コード例 #25
0
ファイル: fm_netsock.c プロジェクト: huiweics/IES
/** fmWaitForNetworkEvent
 * \ingroup platformUtil
 *
 * \desc            Waits for network events.
 *
 * \param[out]      sockets points to an array of active and inactive sockets.
 *                  This function can activate inactive sockets when a client
 *                  attempts to make a connection. The array must be maxSockets
 *                  in length.
 *
 * \param[in]       numSockets is the current number of active sockets; it must
 *                  be in the range [1..maxSockets).
 *
 * \param[in]       maxSockets is the maximum number of sockets this function
 *                  can activate.
 *
 * \param[out]      eventReceived points to an array where this function places
 *                  the network event type for each active socket. The array
 *                  must be maxSockets elements in length.
 *
 * \param[in]       timeout is the amount of time to wait for a network event.
 *                  Set to ''FM_WAIT_FOREVER'' to wait indefinitely.
 *
 * \return          FM_OK if successful.
 * \return          Other ''Status Codes'' as appropriate in case of failure.
 *
 *****************************************************************************/
fm_status fmWaitForNetworkEvent(fm_socket **  sockets, 
                                fm_int *      numSockets,
                                fm_int        maxSockets,
                                fm_int *      eventReceived, 
                                fm_timestamp *timeout)
{
    fm_int         currNumSockets;
    fm_int         errResult;
    fm_int         i;
    fm_int         j;
    fm_int         slot;
    fm_bool        doIncrement;
    struct pollfd  fds[FM_MAX_FDS_NUM] = { {0} };
    fm_int         fdsCnt;
    socklen_t      addrLen = SOCKET_ADDRLEN;
    struct timeval ts;
    char           strErrBuf[FM_STRERROR_BUF_SIZE];
    errno_t        strErrNum;

    FM_LOG_ENTRY_VERBOSE(FM_LOG_CAT_PLATFORM,
                         "sockets=%p, numSockets=%p(%d), maxSockets=%d, "
                         "eventReceived=%p, timeout=%p\n",
                         (void *) sockets, 
                         (void *) numSockets, 
                         (numSockets ? *numSockets : -1),
                         maxSockets,
                         (void *) eventReceived, 
                         (void *) timeout);

    if ((!sockets || !eventReceived || !numSockets || (*numSockets == 0) || \
        (maxSockets > FM_MAX_FDS_NUM) || (*numSockets > FM_MAX_FDS_NUM)))
    {
        FM_LOG_EXIT_VERBOSE(FM_LOG_CAT_PLATFORM, FM_ERR_INVALID_ARGUMENT);
    }

    currNumSockets = *numSockets;

    for ( i = 0, fdsCnt = 0 ; i < currNumSockets ; i++ )
    {
#ifdef VERBOSE
        FM_LOG_DEBUG2(FM_LOG_CAT_PLATFORM, "Watching descriptor %d\n", sockets[i]->sock);
#endif

        if (sockets[i]->type != FM_SOCKET_TYPE_CLOSED)
        {
            fds[fdsCnt].fd = sockets[i]->sock;
            fds[fdsCnt].events = POLLIN;
            fds[fdsCnt].revents = 0;
            fdsCnt++;
        }
    }

    if (timeout != FM_WAIT_FOREVER)
    {
        FM_CLEAR(ts);
        ts.tv_sec  = (int) timeout->sec;
        ts.tv_usec = (int) timeout->usec;
    }

    errResult = poll(fds,
                     fdsCnt,
                     ((timeout == FM_WAIT_FOREVER) ? -1 : \
                      ((ts.tv_sec * 1000) + (ts.tv_usec / 1000)) ));

    FM_LOG_SYS_EXIT_ON_COND(FM_LOG_CAT_PLATFORM, errResult == -1);

    for ( i = 0, fdsCnt = 0 ; i < currNumSockets ; i++, fdsCnt++)
    {
        /* Default case */
        eventReceived[i] = FM_NETWORK_EVENT_NONE;

        if (sockets[i]->type != FM_SOCKET_TYPE_CLOSED && fds[fdsCnt].revents & POLLIN)
        {
            /* Handle TCP connection on server socket */
            if ((sockets[i]->type == FM_SOCKET_TYPE_TCP) &&
                (sockets[i]->serverPort > 0))
            {
                doIncrement = TRUE;
                slot = *numSockets;

                for ( j = 0 ; j < currNumSockets ; j++ )
                {
                    if (sockets[j]->type == FM_SOCKET_TYPE_CLOSED)
                    {
                        doIncrement = FALSE;
                        slot = j;
                        break;
                    }
                }

                if (slot >= maxSockets)
                {
                    FM_LOG_FATAL(FM_LOG_CAT_PLATFORM,
                                 "Not enough socket slots left to accept client\n");
                    break;
                }

                FM_CLEAR(*sockets[slot]);

                sockets[slot]->sock
                    = accept(sockets[i]->sock,
                             (struct sockaddr *) &sockets[slot]->address,
                             &addrLen);
                FM_LOG_SYS_EXIT_ON_COND(FM_LOG_CAT_PLATFORM,
                                        sockets[slot]->sock == -1);

                sockets[slot]->type = FM_SOCKET_TYPE_TCP;

                eventReceived[i] = FM_NETWORK_EVENT_NEW_CLIENT;

#ifdef VERBOSE
                FM_LOG_DEBUG2(FM_LOG_CAT_PLATFORM,
                              "Handled new client connection\n");
#endif

                if (doIncrement)
                {
                    (*numSockets)++;
                }

                break;
            }
            else
            {
                eventReceived[i] = FM_NETWORK_EVENT_DATA_AVAILABLE;

#ifdef VERBOSE
                FM_LOG_DEBUG2(FM_LOG_CAT_PLATFORM,
                              "Data available on client #%d\n", i - 1);
#endif
            }
        }
    }

    FM_LOG_EXIT_VERBOSE(FM_LOG_CAT_PLATFORM, FM_OK);

}   /* end fmWaitForNetworkEvent */
コード例 #26
0
ファイル: fm_generic_rawsocket.c プロジェクト: gdb-glibc/IES
/** fmRawPacketSocketHandlingInitialize
 * \ingroup intPlatformCommon
 *
 * \desc            Initializes the raw packet socket transfer module.
 *
 * \param[in]       sw is the switch number to initialize.
 * 
 * \param[in]       hasFcs is TRUE if the packet includes the FCS field.
 * 
 * \param[in]       iface is a string containing the netdev's interface name
 *                  through which the packets should be sent / received.
 *
 * \return          FM_OK if successful.
 *
 *****************************************************************************/
fm_status fmRawPacketSocketHandlingInitialize(fm_int  sw, 
                                              fm_bool hasFcs, 
                                              fm_text iface)
{
    fm_status                err = FM_OK;
    fm_int                   rawSock = -1;
    struct ifreq             ifr;
    struct sockaddr_ll       sa;
    struct ethtool_value     ethValue;
#ifdef ENABLE_TIMESTAMP
    struct ifreq             hwtstamp;
    struct hwtstamp_config   hwconfig;
    struct hwtstamp_config   hwconfig_requested;
    fm_int                   val;
    socklen_t                len;
    fm_int                   so_timestamping_flags;
    struct cmsghdr *         cmsg;
#endif
    char                     strErrBuf[FM_STRERROR_BUF_SIZE];
    errno_t                  strErrNum;
    fm_switch               *switchPtr;

    FM_LOG_ENTRY(FM_LOG_CAT_PLATFORM,
                 "sw=%d hasFcs=%s\n",
                 sw,
                 FM_BOOLSTRING(hasFcs));

    if (iface == NULL)
    {
        err = FM_ERR_INVALID_ARGUMENT;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_PLATFORM, err);
    }

    err = fmGenericPacketHandlingInitializeV2(sw, hasFcs);
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_PLATFORM, err);

    /* initialize the raw packet socket */
    rawSock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_XDSA));
    if (rawSock == -1)
    {
        FM_LOG_FATAL(FM_LOG_CAT_PLATFORM, 
                     "couldn't create raw packet socket\n");
        err = FM_FAIL;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_PLATFORM, err);
    }

    /* retrieve ethernet interface index */
    FM_STRNCPY_S(ifr.ifr_name, IF_NAMESIZE, iface, IF_NAMESIZE);
    if (ioctl(rawSock, SIOCGIFINDEX, &ifr) == -1) 
    {
        FM_LOG_FATAL(FM_LOG_CAT_PLATFORM, 
                     "Failed to retrieve index for interface %s\n",
                     iface);
        err = FM_ERR_INVALID_ARGUMENT;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_PLATFORM, err);
    }

    /* initialize sockaddr_ll */
    FM_CLEAR(sa);
    sa.sll_family   = PF_PACKET;
    sa.sll_protocol = htons(ETH_P_XDSA);
    sa.sll_ifindex  = ifr.ifr_ifindex;
    if (bind(rawSock, (struct sockaddr *)&sa, sizeof(sa)) < 0)
    {
        FM_LOG_FATAL(FM_LOG_CAT_PLATFORM, 
                     "Failed to bind to the raw packet socket\n");
        err = FM_FAIL;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_PLATFORM, err);
    }
    
#ifdef ENABLE_TIMESTAMP
    /*Set timestamp related configurations */
    FM_CLEAR(hwconfig);
    FM_CLEAR(hwconfig_requested);
    FM_CLEAR(hwtstamp);

    strncpy(hwtstamp.ifr_name, iface, IF_NAMESIZE);
    hwtstamp.ifr_data = (void *)&hwconfig;
    hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
    hwconfig_requested = hwconfig;

    errno = 0;
    if (ioctl(rawSock, SIOCSHWTSTAMP, &hwtstamp) < 0) 
    {
        strErrNum = FM_STRERROR_S(strErrBuf, FM_STRERROR_BUF_SIZE, errno);
        if (strErrNum == 0)
        {
            FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
                         "Failed to configure RX hardware timestamp for all"
                         " received packets. Error: %s\n",
                         strErrBuf);
        }
        else
        {
            FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
                         "Failed to configure RX hardware timestamp for all"
                         " received packets. Error: %d\n",
                         errno);
        }
    }

    FM_LOG_DEBUG(FM_LOG_CAT_PLATFORM,
                 "SIOCSHWTSTAMP: tx_type %d requested, got %d; "
                 " rx_filter %d requested, got %d\n",
                  hwconfig_requested.tx_type, 
                  hwconfig.tx_type,
                  hwconfig_requested.rx_filter, 
                  hwconfig.rx_filter);

    so_timestamping_flags = SOF_TIMESTAMPING_RX_HARDWARE | 
                            SOF_TIMESTAMPING_RAW_HARDWARE;

    if (setsockopt(rawSock,
                   SOL_SOCKET,
                   SO_TIMESTAMPING,
                   &so_timestamping_flags,
                   sizeof(so_timestamping_flags)) < 0)
    {
        FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
                     "Failed to set timestamping on socket\n");
        /* Continue without timestamp */
    }

    len = sizeof(val);
    errno = 0;
    if (getsockopt(rawSock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0)
    {
        strErrNum = FM_STRERROR_S(strErrBuf, FM_STRERROR_BUF_SIZE, errno);
        if (strErrNum == 0)
        {
            FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
                         "Failed to retrieve SO_TIMESTAMPING socket options."
                         " Error %s",
                         strErrBuf);
        }
        else
        {
            FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
                         "Failed to retrieve SO_TIMESTAMPING socket options."
                         " Error %d",
                         errno);
        }
    }
    else
    {
        FM_LOG_DEBUG(FM_LOG_CAT_PLATFORM, "SO_TIMESTAMPING %d\n", val);
        if (val != so_timestamping_flags)
        {
            FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
                         "Expected value %d but retrieved %d\n",
                         so_timestamping_flags,
                         val);
        }
    }
#endif

    /* Set the Driver in ies-tagging mode on management PEP */
    ethValue.cmd = ETHTOOL_SPFLAGS;
    ethValue.data = ETHTOOL_PRV_FLAG_IES;
    ifr.ifr_data = (void*) &ethValue;
    if (ioctl(rawSock, SIOCETHTOOL, &ifr) == -1)
    {
        strErrNum = FM_STRERROR_S(strErrBuf, FM_STRERROR_BUF_SIZE, errno);
        if (strErrNum == 0)
        {
            FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
                         "Failed to set ies-tagging: %s\n",
                         strErrBuf);
        }
        else
        {
            FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
                         "Failed to set ies-tagging: %d\n",
                         errno);
        }
    }

    if (ioctl(rawSock, SIOCGIFFLAGS, &ifr) == -1)
    {
        strErrNum = FM_STRERROR_S(strErrBuf, FM_STRERROR_BUF_SIZE, errno);
        if (strErrNum == 0)
        {
            FM_LOG_FATAL(FM_LOG_CAT_PLATFORM, 
                         "Failed to get socket flags: %s\n",
                         strErrBuf);
        }
        else
        {
            FM_LOG_FATAL(FM_LOG_CAT_PLATFORM, 
                         "Failed to get socket flags: %d\n",
                         errno);
        }

        err = FM_FAIL;
        FM_LOG_ABORT(FM_LOG_CAT_PLATFORM, err);
    }

    if ((ifr.ifr_flags & IFF_UP) == 0)
    {
        /* Bring the NIC up */
        ifr.ifr_flags |= IFF_UP;

        if (ioctl(rawSock, SIOCSIFFLAGS, &ifr) == -1)
        {
            strErrNum = FM_STRERROR_S(strErrBuf, FM_STRERROR_BUF_SIZE, errno);
            if (strErrNum == 0)
            {
                FM_LOG_FATAL(FM_LOG_CAT_PLATFORM, 
                             "Failed to bring up: %s\n",
                             strErrBuf);
            }
            else
            {
                FM_LOG_FATAL(FM_LOG_CAT_PLATFORM, 
                             "Failed to bring up: %d\n",
                             errno);
            }
            
            err = FM_FAIL;
            FM_LOG_ABORT(FM_LOG_CAT_PLATFORM, err);
        }
    }

    GET_PLAT_STATE(sw)->rawSocket = rawSock;
    FM_STRNCPY_S(GET_PLAT_STATE(sw)->ifaceName, IF_NAMESIZE, iface, IF_NAMESIZE);

    /* Create the receive packet thread */
    err = fmCreateThread("raw_packet_socket receive",
                         FM_EVENT_QUEUE_SIZE_NONE,
                         &fmRawPacketSocketReceivePackets,
                         &(GET_PLAT_STATE(sw)->sw),
                         GET_PLAT_RAW_LISTENER(sw));

    switchPtr = GET_SWITCH_PTR(sw);
    if (switchPtr)
    {
        switchPtr->isRawSocketInitialized = FM_ENABLED;
    }

ABORT:
    if ( (err != FM_OK) &&
         (rawSock != -1) )
    {
        close(rawSock);
    }

    FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, err);

}   /* end fmRawPacketSocketHandlingInitialize */
コード例 #27
0
ファイル: fm_generic_rawsocket.c プロジェクト: gdb-glibc/IES
/** fmRawPacketSocketSendPackets
 * \ingroup intPlatformCommon
 *
 * \desc            When called, iterates through the packet queue and
 *                  continues to send packets until either the queue empties.
 *
 * \param[in]       sw refers to the switch number to send packets to.
 *
 * \return          FM_OK if successful.
 *
 *****************************************************************************/
fm_status fmRawPacketSocketSendPackets(fm_int sw)
{
    fm_status               err = FM_OK;
    fm_switch *             switchPtr;
    fm_packetHandlingState *pktState;
    fm_packetQueue *        txQueue;
    fm_packetEntry *        packet;
    fm_int32                rc;
    fm_buffer               *sendBuf;
    struct msghdr           msg;
    struct iovec            iov[UIO_MAXIOV];
    fm_islTag               islTag;
    fm_uint32               fcs;
    fm_uint64               rawTS;
    char                    strErrBuf[FM_STRERROR_BUF_SIZE];
    errno_t                 strErrNum;
    struct ifreq            ifr;

    FM_LOG_ENTRY(FM_LOG_CAT_EVENT_PKT_TX, "sw = %d\n", sw);

    switchPtr = GET_SWITCH_PTR(sw);
    pktState  = GET_PLAT_PKT_STATE(sw);

    if (GET_PLAT_STATE(sw)->rawSocket <= 0)
    {
        FM_LOG_ERROR(FM_LOG_CAT_EVENT_PKT_TX, 
                     "Socket is not initialized.\n");
        FM_LOG_EXIT(FM_LOG_CAT_EVENT_PKT_TX, FM_ERR_UNINITIALIZED);
    }

    /* initialize the message header */
    FM_CLEAR(msg);
    msg.msg_name = NULL; /* Optional field */
    msg.msg_namelen = 0;
    msg.msg_iov = iov;
    msg.msg_iovlen = 0;
    msg.msg_flags = 0;

    FM_STRNCPY_S(ifr.ifr_name, IF_NAMESIZE, GET_PLAT_STATE(sw)->ifaceName, IF_NAMESIZE);

    txQueue = &pktState->txQueue;
    fmPacketQueueLock(txQueue);

    if (ioctl(GET_PLAT_STATE(sw)->rawSocket, SIOCGIFFLAGS, &ifr) == -1)
    {
        strErrNum = FM_STRERROR_S(strErrBuf, FM_STRERROR_BUF_SIZE, errno);
        if (strErrNum == 0)
        {
            FM_LOG_FATAL(FM_LOG_CAT_EVENT_PKT_TX, 
                         "Failed to get socket %d flags for device %s: %s\n",
                         GET_PLAT_STATE(sw)->rawSocket,
                         ifr.ifr_name,
                         strErrBuf);
        }
        else
        {
            FM_LOG_FATAL(FM_LOG_CAT_EVENT_PKT_TX, 
                         "Failed to get socket %d flags for device %s: %d\n",
                         GET_PLAT_STATE(sw)->rawSocket,
                         ifr.ifr_name,
                         errno);
        }
        switchPtr->transmitterLock = TRUE;
        err = FM_FAIL;
        FM_LOG_ABORT(FM_LOG_CAT_EVENT_PKT_TX, err);
    }

    if ((ifr.ifr_flags & IFF_RUNNING) == 0)
    {    
        FM_LOG_WARNING(FM_LOG_CAT_EVENT_PKT_TX,
                       "Network device %s resources are not allocated.\n",
                       ifr.ifr_name);
        switchPtr->transmitterLock = TRUE;
        err = FM_FAIL;
        FM_LOG_ABORT(FM_LOG_CAT_EVENT_PKT_TX, err);
    }

    /* Iterate through the packets in the tx queue */
    for ( ;
          txQueue->pullIndex != txQueue->pushIndex ;
          txQueue->pullIndex = (txQueue->pullIndex + 1) % FM_PACKET_QUEUE_SIZE)
    {
        packet = &txQueue->packetQueueList[txQueue->pullIndex];

        FM_LOG_DEBUG(FM_LOG_CAT_EVENT_PKT_TX,
                     "sending packet in slot %d, length=%d tag=%d fcs=%08x\n",
                     txQueue->pullIndex, packet->length,
                     packet->suppressVlanTag, packet->fcsVal);
        msg.msg_iovlen = 0;

        /* Add the 8 byte timetag iovec. Note that the value is ignored
         * by the driver as it gets overwritten by the PEP. */
        rawTS = 0;
        iov[msg.msg_iovlen].iov_base = &rawTS;
        iov[msg.msg_iovlen].iov_len = sizeof(rawTS);
        msg.msg_iovlen++;

        if (packet->islTagFormat == FM_ISL_TAG_F56)
        {
            /* Add the FTAG (F56) iovec */
            islTag.f56.tag[0] = htonl(packet->islTag.f56.tag[0]);
            islTag.f56.tag[1] = htonl(packet->islTag.f56.tag[1]);
            iov[msg.msg_iovlen].iov_base = &islTag.f56.tag[0];
            iov[msg.msg_iovlen].iov_len = FM_F56_BYTE_LEN;
            msg.msg_iovlen++;
        }
        
        /* iterate through all buffers */
        for ( sendBuf = packet->packet ; sendBuf ; sendBuf = sendBuf->next )
        {
            /* if first buffer ... */
            if (sendBuf == packet->packet)
            {
                /* Cannot modify the send buffer, since the same buffer can be
                 * used multiple times to send to multiple ports */

                /* second iovec is the mac header */
                iov[msg.msg_iovlen].iov_base = sendBuf->data;
                iov[msg.msg_iovlen].iov_len = FM_MAC_HDR_BYTE_LEN;
                msg.msg_iovlen++;

                if (packet->islTagFormat == FM_ISL_TAG_F64)
                {
                    /* Insert the F64 ISL tag */
                    islTag.f64.tag[0] = htonl(packet->islTag.f64.tag[0]);
                    islTag.f64.tag[1] = htonl(packet->islTag.f64.tag[1]);
                    iov[msg.msg_iovlen].iov_base = &islTag.f64.tag[0];
                    iov[msg.msg_iovlen].iov_len = FM_F64_BYTE_LEN;
                    msg.msg_iovlen++;
                }

                /* Third is the data in the first chain */
                if (packet->suppressVlanTag)
                {
                    iov[msg.msg_iovlen].iov_base = &sendBuf->data[4];
                    iov[msg.msg_iovlen].iov_len = sendBuf->len-16;
                    msg.msg_iovlen++;
                }
                else
                {
                    iov[msg.msg_iovlen].iov_base = &sendBuf->data[3];
                    iov[msg.msg_iovlen].iov_len = sendBuf->len-12;
                    msg.msg_iovlen++;
                }
            }
            else
            {
                /* The rest of the chain */
                iov[msg.msg_iovlen].iov_base = sendBuf->data;
                iov[msg.msg_iovlen].iov_len = sendBuf->len;
                msg.msg_iovlen++;
            }

        }   /* end for (...) */

        /* Append user-supplied FCS value to packet. */
        if (pktState->sendUserFcs)
        {
            fcs = htonl(packet->fcsVal);
            iov[msg.msg_iovlen].iov_base = &fcs;
            iov[msg.msg_iovlen].iov_len = sizeof(fcs);
            msg.msg_iovlen++;
        }

        /* now send it to the driver */
        errno = 0;
        rc = sendmsg(GET_PLAT_STATE(sw)->rawSocket, &msg, MSG_DONTWAIT);
        if (rc == -1)
        {
            switchPtr->transmitterLock = TRUE;
            if (errno != EWOULDBLOCK)
            {
                err = FM_FAIL;

                FM_LOG_DEBUG(FM_LOG_CAT_EVENT_PKT_TX,
                             "rawSocket %d\n",
                             GET_PLAT_STATE(sw)->rawSocket);

                strErrNum = FM_STRERROR_S(strErrBuf,
                                          FM_STRERROR_BUF_SIZE,
                                          errno);
                if (strErrNum == 0)
                {
                    FM_LOG_ERROR(FM_LOG_CAT_EVENT_PKT_TX,
                                 "sendmsg failed: %s - errno %d\n",
                                 strErrBuf,
                                 errno);
                }
                else
                {
                    FM_LOG_ERROR(FM_LOG_CAT_EVENT_PKT_TX, 
                                 "sendmsg failed - errno %d\n", errno);
                }
            }
            if (errno == EMSGSIZE)
            {
                switchPtr->transmitterLock = FALSE;
            }
            else
            {
                goto ABORT;
            }
        }
        else
        {
            FM_LOG_DEBUG(FM_LOG_CAT_EVENT_PKT_TX, "%d bytes were sent\n", rc);

            switchPtr->transmitterLock = FALSE;
            fmDbgDiagCountIncr(sw, FM_CTR_TX_PKT_COMPLETE, 1);
        }

        /**************************************************
         * free buffer only when
         * (1) sending to a single port;
         * or (2) this is the last packet of multiple 
         * identical packets
         **************************************************/

        if (packet->freePacketBuffer)
        {
            /* ignore the error code since it's better to continue */
            (void) fmFreeBufferChain(sw, packet->packet);

            fmDbgGlobalDiagCountIncr(FM_GLOBAL_CTR_TX_BUFFER_FREES, 1);
        }
    }

ABORT:
    fmPacketQueueUnlock(txQueue);

    FM_LOG_EXIT(FM_LOG_CAT_EVENT_PKT_TX, err);

}   /* end fmRawPacketSocketSendPackets */
コード例 #28
0
ファイル: judge.cpp プロジェクト: w703710691d/PowerJudge
int oj_compare_output(const char *file_out, const char *file_user) {
    FM_LOG_TRACE("start compare");
    FILE *fp_std = fopen(file_out, "r");
    if (fp_std == nullptr) {
        FM_LOG_FATAL("open standard output file (%s) failed: %s", file_out, strerror(errno));
        exit(EXIT_COMPARE);
    }

    FILE *fp_exe = fopen(file_user, "r");
    if (fp_exe == nullptr) {
        FM_LOG_FATAL("open user output file (%s) failed: %s", file_user, strerror(errno));
        exit(EXIT_COMPARE);
    }

    int a, b, Na = 0, Nb = 0;
    enum {
        AC = OJ_AC,
        PE = OJ_PE,
        WA = OJ_WA
    } status = AC;

    while (true) {
        /*
         * Windows / DOS uses '\r\n';
         * Unix / Linux / OS X uses '\n';
         * Macs before OS X use '\r';
         * TODO(power): out file with '\r' line ending get incorrect PE
         */
        while ((a = fgetc(fp_std)) == '\r') {}
        while ((b = fgetc(fp_exe)) == '\r') {}
        Na++, Nb++;

        // deal with '\r' and '\n'
        if (a == '\r') a = '\n';
        if (b == '\r') b = '\n';

        if (feof(fp_std) && feof(fp_exe)) {
            break;
        } else if (feof(fp_std) || feof(fp_exe)) {
            // deal with tailing white spaces
            FILE *fp_tmp;
            if (feof(fp_std)) {
                FM_LOG_TRACE("std out file ended");
                if (!is_space_char(b)) {
                    FM_LOG_TRACE("WA exe['%c':0x%x @%d]", b, b, Nb);
                    status = WA;
                    break;
                }
                fp_tmp = fp_exe;
            } else { /* feof(fp_exe) */
                FM_LOG_TRACE("user out file ended");
                if (!is_space_char(a)) {
                    FM_LOG_TRACE("WA std['%c':0x%x @%d]", a, a, Na);
                    status = WA;
                    break;
                }
                fp_tmp = fp_std;
            }
            int c;
            while (c = fgetc(fp_tmp), c != EOF) {
                if (c == '\r') c = '\n';
                if (!is_space_char(c)) {
                    FM_LOG_TRACE("WA ['%c':0x%x]", c, c);
                    status = WA;
                    break;
                }
            }
            break;
        }

        if (a != b) {
            status = PE;
            if (is_space_char(a) && is_space_char(b)) {
                continue;
            }
            if (is_space_char(a)) {
                ungetc(b, fp_exe);
                Nb--;
            } else if (is_space_char(b)) {
                ungetc(a, fp_std);
                Na--;
            } else {
                FM_LOG_TRACE("WA ['%c':0x%x @%d] : ['%c':0x%x @%d]", a, a, Na, b, b, Nb);
                status = WA;
                break;
            }
        }
    }  // end of while

    fclose(fp_std);
    fclose(fp_exe);

    if (status == WA || status == PE) {
        make_diff_out2(file_out, file_user, oj_solution.work_dir, file_out);
    }
    FM_LOG_TRACE("compare finished, result=%s", status == AC ? "AC" : (status == PE ? "PE" : "WA"));
    return status;
}
コード例 #29
0
ファイル: fm_debug_selftest.c プロジェクト: huiweics/IES
fm_status fmDbgSwitchSelfTest(fm_int sw, fm_bool ctrlState)
{
    fm_status               err;
    fm_status               testResult = FM_FAIL;
    fm_switch               *switchPtr;
    fm_bool                 switchLocked = FALSE;

    FM_LOG_ENTRY_API(FM_LOG_CAT_SWITCH, "sw=%d\n", sw);
    VALIDATE_SWITCH_LOCK(sw);

    /* Take write access to the switch lock */
    err = LOCK_SWITCH(sw);

    if (err != FM_OK)
    {
        FM_LOG_FATAL(FM_LOG_CAT_SWITCH,
                     "Unable to capture switch write lock %p for switch %d\n",
                     (void *) fmRootApi->fmSwitchLockTable[sw],
                     sw);

        goto ABORT;
    }

    switchLocked = TRUE;

    /* return error if switch is not found. */
    if (!fmRootApi->fmSwitchStateTable[sw])
    {
        err = FM_ERR_INVALID_SWITCH;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_SWITCH, err);
    }

    switchPtr = fmRootApi->fmSwitchStateTable[sw];

    /* Do not perform test on a SWAG or a member of a SWAG. */
    if (switchPtr->switchFamily == FM_SWITCH_FAMILY_SWAG ||
            switchPtr->swag >= 0)
    {
        err = FM_ERR_INVALID_SWITCH;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_SWITCH, err);
    }

    if (ctrlState)
    {
        /**************************************************
         * First bring the switch down. This will clear
         * all API soft state and delete VLANs, LAGs,
         * multicast groups, routes, etc.
         **************************************************/

        err = fmSetSwitchState(sw, FALSE);
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_SWITCH, err);

        /**************************************************
         * Now bring the switch back up so we can perform
         * the memory test.
         **************************************************/

        err = fmSetSwitchState(sw, TRUE);
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_SWITCH, err);

    }


    UNLOCK_SWITCH(sw);
    switchLocked = FALSE;

    /**************************************************
     * Now perform the test.
     **************************************************/
    FM_API_CALL_FAMILY(testResult, switchPtr->DbgSwitchSelfTest, sw);

    if (ctrlState)
    {
        /**************************************************
         * Bring switch down again. We have a test result,
         * so ignore the return code when calling
         * fmSetSwitchState since we only care about the
         * test result now.
         **************************************************/

        fmSetSwitchState(sw, FALSE);
    }

ABORT:

    if (switchLocked)
    {
        UNLOCK_SWITCH(sw);
    }

    if (err == FM_OK)
    {
        err = testResult;
    }

    FM_LOG_EXIT_API(FM_LOG_CAT_SWITCH, err);

}   /* end fmDbgSwitchSelfTest */