summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2013-11-16 15:23:40 +0800
committerLAN-TW <lantw44@gmail.com>2013-11-16 15:23:40 +0800
commit69ac4b3704e5360c7e67903dbfa9e0780bffa040 (patch)
treef8f3aa32ce96c739c46d621a29c92a4dab9ee319
parente6d786a403a36b98e4f6082ee9848473825db8e8 (diff)
downloadsp2013-69ac4b3704e5360c7e67903dbfa9e0780bffa040.tar.gz
sp2013-69ac4b3704e5360c7e67903dbfa9e0780bffa040.tar.zst
sp2013-69ac4b3704e5360c7e67903dbfa9e0780bffa040.zip
HW2: 修正 judge 使第一輪可以正常執行、修正輸出結果、處理 zombie child
-rw-r--r--hw2/judge.c74
-rw-r--r--hw2/logger.c2
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;