aboutsummaryrefslogtreecommitdiffstats
path: root/judge/check.c
diff options
context:
space:
mode:
Diffstat (limited to 'judge/check.c')
-rw-r--r--judge/check.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/judge/check.c b/judge/check.c
new file mode 100644
index 0000000..bfe4a14
--- /dev/null
+++ b/judge/check.c
@@ -0,0 +1,128 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<limits.h>
+#include<fcntl.h>
+#include<signal.h>
+#include<pthread.h>
+#include<semaphore.h>
+#include<termios.h>
+
+#include"judge_def.h"
+#include"judgx.h"
+
+struct check_thread_info{
+ int status;
+ sem_t *done_sem;
+};
+
+int mptd;
+char ptname[PATH_MAX + 1];
+int infd;
+int ansfd;
+
+DLL_PUBLIC int init(char *runpath,char *datapath){
+ struct termios tes;
+ char tpath[PATH_MAX + 1];
+ char newpath[PATH_MAX + 1];
+
+ printf("check1\n");
+
+ mptd = posix_openpt(O_RDWR);
+ grantpt(mptd);
+ unlockpt(mptd);
+ ptsname_r(mptd,ptname,sizeof(ptname));
+ tcgetattr(mptd,&tes);
+ cfmakeraw(&tes);
+ tcsetattr(mptd,TCSANOW,&tes);
+
+ snprintf(tpath,sizeof(tpath),"%s/in.txt",datapath);
+ snprintf(newpath,sizeof(newpath),"%s/in.txt",runpath);
+ if(link(tpath,newpath) == -1){
+ unlink(newpath);
+ link(tpath,newpath);
+ }
+ infd = open(tpath,O_RDONLY);
+ snprintf(tpath,sizeof(tpath),"%s/ans.txt",datapath);
+ ansfd = open(tpath,O_RDONLY);
+ if(infd == -1 || ansfd == -1){
+ goto error;
+ }
+
+ printf("check2\n");
+
+ return 0;
+
+error:
+
+ close(mptd);
+ close(infd);
+ close(ansfd);
+
+ return -1;
+}
+
+static void thread_clean(void *arg){
+ close(mptd);
+ close(infd);
+ close(ansfd);
+ return;
+}
+DLL_PUBLIC void* thread(void *arg){
+ int ret;
+ struct check_thread_info *thread_info;
+
+ int flag;
+ char outbuf[4096];
+ char ansbuf[4096];
+
+ pthread_cleanup_push(thread_clean,NULL);
+ thread_info = (struct check_thread_info*)arg;
+
+ flag = 0;
+ while(1){
+ if((ret = read(mptd,outbuf,4096)) <= 0){
+ if(read(ansfd,ansbuf,1) > 0){
+ flag = 1;
+ break;
+ }else{
+ break;
+ }
+ }
+ if(read(ansfd,ansbuf,ret) != ret){
+ flag = 1;
+ break;
+ }
+ if(memcmp(ansbuf,outbuf,ret) != 0){
+ flag = 1;
+ break;
+ }
+ }
+
+ if(flag == 0){
+ thread_info->status = JUDGE_AC;
+ }else{
+ thread_info->status = JUDGE_WA;
+ }
+
+ pthread_cleanup_pop(thread_clean);
+ sem_post(thread_info->done_sem);
+ return NULL;
+}
+DLL_PUBLIC int stop(void){
+ return 0;
+}
+
+DLL_PUBLIC int run(){
+ int sptd;
+ struct termios tes;
+
+ sptd = open(ptname,O_RDWR);
+ tcgetattr(sptd,&tes);
+ cfmakeraw(&tes);
+ tcsetattr(sptd,TCSANOW,&tes);
+
+ dup2(infd,0);
+ dup2(sptd,1);
+ dup2(sptd,2);
+ return 0;
+}