diff options
author | LAN-TW <lantw44@gmail.com> | 2013-11-16 15:23:40 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2013-11-16 15:23:40 +0800 |
commit | 69ac4b3704e5360c7e67903dbfa9e0780bffa040 (patch) | |
tree | f8f3aa32ce96c739c46d621a29c92a4dab9ee319 | |
parent | e6d786a403a36b98e4f6082ee9848473825db8e8 (diff) | |
download | sp2013-69ac4b3704e5360c7e67903dbfa9e0780bffa040.tar.gz sp2013-69ac4b3704e5360c7e67903dbfa9e0780bffa040.tar.zst sp2013-69ac4b3704e5360c7e67903dbfa9e0780bffa040.zip |
HW2: 修正 judge 使第一輪可以正常執行、修正輸出結果、處理 zombie child
-rw-r--r-- | hw2/judge.c | 74 | ||||
-rw-r--r-- | hw2/logger.c | 2 |
2 files changed, 42 insertions, 34 deletions
diff --git a/hw2/judge.c b/hw2/judge.c index 02b513a..9c707a0 100644 --- a/hw2/judge.c +++ b/hw2/judge.c @@ -18,6 +18,7 @@ #include <sys/stat.h> #include <sys/time.h> #include <sys/types.h> +#include <sys/wait.h> #include <time.h> #include <unistd.h> @@ -39,6 +40,10 @@ static void player_tle_setter (int signo) { player_tle = 1; } +static void cleanup_child (int signo) { + waitpid (-1, NULL, WUNTRACED | WNOHANG); +} + static void fdata_clear (FData* d) { d->last = 0; d->score = 0; @@ -87,6 +92,11 @@ int main (int argc, char* argv[]) { }; for (int i = 0; i < ARRAY_LEN (ffd, FData); i++) { + struct stat st; + if (stat (ffd[i].fname, &st) >= 0 && S_ISFIFO (st.st_mode)) { + unlink (ffd[i].fname); + } + if (mkfifo (ffd[i].fname, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0) { fprintf (stderr, "%s: cannot create FIFO `%s\': %s\n", argv[0], ffd[i].fname, strerror (errno)); @@ -132,18 +142,14 @@ int main (int argc, char* argv[]) { }; sigemptyset (&sa.sa_mask); sigaction (SIGALRM, &sa, NULL); + sa.sa_handler = cleanup_child; + sigaction (SIGCHLD, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, NULL); char *linestr = NULL; size_t linelen = 0; bool request_exit = false; - fd_set rset; - int nfds; - - FD_ZERO (&rset); - FD_SET (ffd[0].fd, &rset); - nfds = ffd[0].fd + 1; comp135_log (comp, "Waiting for initial request from big_judge"); while (!request_exit && getline (&linestr, &linelen, stdin) >= 0) { @@ -168,33 +174,13 @@ int main (int argc, char* argv[]) { goto new_loop_end; } - for (i = 1, c = 'A'; i <= 4; i++, c++) { - fdata_clear (&ffd[i]); - ffd[i].key = random (); - ffd[i].pid = fork (); - if (ffd[i].pid < 0) { - fprintf (stderr, "Cannot fork: %s\n", strerror (errno)); - break; - } else if (ffd[i].pid == 0) { - char* plname = xstrcat ("player_", pl[i - 1], NULL); - char* plthis = xgetres (plname); - char* plkey = xsprintf ("%ld", ffd[i].key); - char plid[2] = { c, '\0' }; - execl (plthis, plname, judgename, plid, plkey, (char*)NULL); - fprintf (stderr, "Cannot execl `%s\': %s\n", - plthis, strerror (errno)); - _exit (127); - } - } - - if (i <= 4 && ffd[i].pid) { - for (int j = 1; j < i; j++) { - kill (ffd[i].pid, SIGKILL); - } - goto new_loop_end; - } + char trash_buf[512]; + xfaddfl (ffd[0].fd, O_NONBLOCK); + while (read (ffd[0].fd, trash_buf, 512) > 0); + xfdelfl (ffd[0].fd, O_NONBLOCK); for (int t = 0; t < 20; t++) { + char lastmsg[20]; int lastlen; @@ -203,11 +189,33 @@ int main (int argc, char* argv[]) { lastmsg[lastlen - 1] = '\0'; comp135_log (comp, "Previous round: %s", lastmsg); lastmsg[lastlen - 1] = '\n'; + comp135_log (comp, "This is round %d", t + 1); for (i = 1, c = 'A'; i <= 4; i++, c++) { if (t) { write (ffd[i].fd, lastmsg, lastlen); + } else { + fdata_clear (&ffd[i]); + ffd[i].key = random (); + ffd[i].pid = fork (); + if (ffd[i].pid < 0) { + fprintf (stderr, "Cannot fork: %s\n", strerror (errno)); + for (int j = 1; j < i; j++) { + kill (ffd[i].pid, SIGKILL); + } + goto new_loop_end; + } else if (ffd[i].pid == 0) { + char* plname = xstrcat ("player_", pl[i - 1], NULL); + char* plthis = xgetres (plname); + char* plkey = xsprintf ("%ld", ffd[i].key); + char plid[2] = { c, '\0' }; + execl (plthis, plname, judgename, plid, plkey, (char*)NULL); + fprintf (stderr, "Cannot execl `%s\': %s\n", + plthis, strerror (errno)); + _exit (127); + } + comp135_log (comp, "Player %c has PID %u", c, ffd[i].pid); } if (ffd[i].ignore) { @@ -344,8 +352,8 @@ int main (int argc, char* argv[]) { for (int j = 0; j < 4; j++) { comp135_log (comp, "Send %s %d to big_judge", - pl[j], ffd[rank[j]].rank); - printf ("%s %d\n", pl[j], ffd[rank[j]].rank); + pl[rank[j] - 1], ffd[rank[j]].rank); + printf ("%s %d\n", pl[rank[j] - 1], ffd[rank[j]].rank); } fflush (stdout); diff --git a/hw2/logger.c b/hw2/logger.c index e8c2cbf..53e6a40 100644 --- a/hw2/logger.c +++ b/hw2/logger.c @@ -74,7 +74,7 @@ void comp135_init (Comp135* comp, const char* static_name, bool no_init) { return; } - setvbuf (fp, NULL, _IONBF, 0); + setvbuf (fp, NULL, _IOLBF, 0); comp->log = xstrdup (comp135_logfile); comp->log_fd = fd; comp->log_file = fp; |