aboutsummaryrefslogtreecommitdiffstats
path: root/src/ProcCheckTime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ProcCheckTime.c')
-rw-r--r--src/ProcCheckTime.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/ProcCheckTime.c b/src/ProcCheckTime.c
new file mode 100644
index 0000000..9efbe05
--- /dev/null
+++ b/src/ProcCheckTime.c
@@ -0,0 +1,70 @@
+#ifdef HAVE_CONFIG_H
+# include "SctConfig.h"
+#endif
+
+#include "SctConst.h"
+#include "SctCommon.h"
+#include "ProcCommon.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <pthread.h>
+#include <semaphore.h>
+
+volatile sig_atomic_t sctproc_abort;
+
+static void break_handler(int signo){
+ sctproc_abort = 1;
+ sem_post(&checktime_sem);
+}
+
+void* sctproc_checktime(void* arg){
+ PROCINFO* procinfo = arg;
+ struct sigaction break_catch;
+ struct timespec timelimit, timeinit, timecur, timeexpire;
+ long long sleeptime = (long long)(procinfo->i_limit_time) * 1000000;
+
+ pthread_mutex_lock(&checktime_mutex);
+ checktime_exist = 1;
+ pthread_mutex_unlock(&checktime_mutex);
+
+ clock_gettime(CLOCK_REALTIME, &timeinit);
+
+#ifndef HAVE_CONF_CAP
+ enable_setuid();
+#endif
+
+ sctproc_abort = 0;
+ memset(&break_catch, 0, sizeof(break_catch));
+ break_catch.sa_handler = &break_handler;
+ sigaction(SIGINT, &break_catch, NULL);
+ sigaction(SIGTERM, &break_catch, NULL);
+
+ timelimit.tv_sec = timeinit.tv_sec + sleeptime / 1000000000;
+ timelimit.tv_nsec = timeinit.tv_nsec + sleeptime % 1000000000;
+ checktimespec(&timelimit);
+
+ do{
+ clock_gettime(CLOCK_REALTIME, &timecur);
+ timeexpire.tv_sec = timecur.tv_sec;
+ timeexpire.tv_nsec = timecur.tv_nsec + SCTJUDGE_PROC_CHECKTIME_INTERVAL;
+ checktimespec(&timeexpire);
+ }while(comparetimespec(&timecur, &timelimit) < 0 &&
+ sem_timedwait(&checktime_sem, &timeexpire));
+
+ if(!sctproc_abort){
+ pthread_mutex_lock(&sctproc_tle_mutex);
+ sctproc_tle = 1;
+ pthread_mutex_unlock(&sctproc_tle_mutex);
+ }
+
+ kill(child_pid, SIGKILL);
+
+ pthread_mutex_lock(&checktime_mutex);
+ checktime_exist = 0;
+ pthread_mutex_unlock(&checktime_mutex);
+ return NULL;
+}
+