Example #1
0
    def compile(self, sub):

        sub.status = jcnf.SUB_STATUS['compiling']

        if os.path.exists(self.run_path):
            shutil.rmtree(self.run_path)

        try:
            os.mkdir(self.run_path, 0755)
        except (OSError): # TODO write log
            sys.stderr.write('could not remake run path')
            raise Exception('could not remake run path')

        if sub.code_path:
            self.code_path = sub.code_path
        else:
            self.code_path = jcnf.getSubPath(sub.sid)
        try:
            shutil.copyfile(self.code_path, self.run_path+jcnf.getSrcName(sub.lang))
        except (shutil.Error, IOError): # TODO write log
            sys.stderr.write('source file does not exist')
            raise Exception('source file does not exist')

        cmpl_pid = os.fork()

        if cmpl_pid == 0:  # child process

            cmpl_cmd = jcnf.CMPL_CMD[sub.lang]
            cmpl_param = jcnf.CMPL_PARAM[sub.lang]

            try:
                cmpl_err = open(self.run_path+'ce', 'w')
            except:
                sys.stderr.write('cannot log compilation info')
                raise Exception('cannot log compilation info')
            os.dup2(cmpl_err.fileno(), 2)

            resource.setrlimit(resource.RLIMIT_CPU, jcnf.CMPL_RLIM['RLIMIT_CPU'])
            os.execvp(cmpl_cmd, cmpl_param)

            cmpl_err.flush()
            cmpl_err.close()
            os._exit(os.EX_OK)

        else:
            
            cmpl_ret = 0
            while True:
                cmpl_status = os.waitpid(cmpl_pid, 0)
                if os.WIFEXITED(cmpl_status[1]):
                    cmpl_ret = 0
                    break
                elif os.WIFSIGNALED(cmpl_status[1]) or os.WIFSTOPPED(cmpl_status[1]):
                    cmpl_ret = 1
                    break
                os.stderr.write('unknown stat')

            if os.WEXITSTATUS(cmpl_status[1]) != 0:
                cmpl_ret = 1

            if cmpl_ret != 0:
                cmpl_err = open(self.run_path+'ce', 'r')
                sub.ce = self._ceFilter(cmpl_err.read())
                sub.status = jcnf.SUB_STATUS['compilation error']
                cmpl_err.close()

            try:
                os.kill(cmpl_pid, signal.SIGKILL)
            except:
                pass

            if sub.status == jcnf.SUB_STATUS['compiling']:
                sub.status = jcnf.SUB_STATUS['judging']
            return sub.status