X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=grading%2Ffilesys%2Ffslib.c;h=78e168a96af36cadc723c326fd711b21922949b4;hb=c59a378430c0c26a9ae2c6b65d46d28607d264fe;hp=36f67f8efcaee0ed06d6ada5dcb3bb1ac82b12a8;hpb=ff076af15fa93292b8843e76bd6bab7ac5421095;p=pintos-anon diff --git a/grading/filesys/fslib.c b/grading/filesys/fslib.c index 36f67f8..78e168a 100644 --- a/grading/filesys/fslib.c +++ b/grading/filesys/fslib.c @@ -4,21 +4,23 @@ #include #include #include -#include "../lib/arc4.h" bool quiet = false; static void -vmsg (const char *format, va_list args, bool failure) +vmsg (const char *format, va_list args, const char *suffix) { - if (quiet && !failure) - return; - - printf ("(%s) ", test_name); - vprintf (format, args); - if (failure) - printf (": FAILED"); - printf ("\n"); + /* We go to some trouble to stuff the entire message into a + single buffer and output it in a single system call, because + that'll (typically) ensure that it gets sent to the console + atomically. Otherwise kernel messages like "foo: exit(0)" + can end up being interleaved if we're unlucky. */ + static char buf[1024]; + + snprintf (buf, sizeof buf, "(%s) ", test_name); + vsnprintf (buf + strlen (buf), sizeof buf - strlen (buf), format, args); + strlcpy (buf + strlen (buf), suffix, sizeof buf - strlen (buf)); + write (STDOUT_FILENO, buf, strlen (buf)); } void @@ -26,8 +28,10 @@ msg (const char *format, ...) { va_list args; + if (quiet) + return; va_start (args, format); - vmsg (format, args, false); + vmsg (format, args, "\n"); va_end (args); } @@ -36,49 +40,24 @@ fail (const char *format, ...) { va_list args; - quiet = false; - va_start (args, format); - vmsg (format, args, true); + vmsg (format, args, ": FAILED\n"); va_end (args); exit (1); } -void -check (bool success, const char *format, ...) -{ - va_list args; - - va_start (args, format); - if (success) - { - if (!quiet) - vmsg (format, args, false); - } - else - { - vmsg (format, args, true); - exit (1); - } - va_end (args); -} - void -seq_test (const char *filename, void *buf, size_t size, - size_t initial_size, int seed, +seq_test (const char *filename, void *buf, size_t size, size_t initial_size, size_t (*block_size_func) (void), void (*check_func) (int fd, long ofs)) { - static struct arc4 arc4; size_t ofs; int fd; - arc4_init (&arc4, &seed, sizeof seed); - arc4_crypt (&arc4, buf, size); - - check (create (filename, initial_size), "create \"%s\"", filename); - check ((fd = open (filename)) > 1, "open \"%s\"", filename); + random_bytes (buf, size); + CHECK (create (filename, initial_size), "create \"%s\"", filename); + CHECK ((fd = open (filename)) > 1, "open \"%s\"", filename); ofs = 0; msg ("writing \"%s\"", filename); @@ -137,7 +116,7 @@ check_file (const char *filename, const void *buf_, size_t size) char block[512]; int fd; - check ((fd = open (filename)) > 1, "open \"%s\" for verification", filename); + CHECK ((fd = open (filename)) > 1, "open \"%s\" for verification", filename); ofs = 0; while (ofs < size) @@ -150,22 +129,74 @@ check_file (const char *filename, const void *buf_, size_t size) fail ("read %zu bytes at offset %zu in \"%s\" failed", block_size, ofs, filename); - if (memcmp (buf + ofs, block, block_size)) - { - if (block_size <= 512) - { - printf ("Expected data:\n"); - hex_dump (ofs, buf + ofs, block_size, false); - printf ("Actually read data:\n"); - hex_dump (ofs, block, block_size, false); - } - fail ("%zu bytes at offset %zu differed from expected", - block_size, ofs); - } - + compare_bytes (block, buf + ofs, block_size, ofs, filename); ofs += block_size; } msg ("close \"%s\"", filename); close (fd); } + +void +compare_bytes (const void *read_data_, const void *expected_data_, size_t size, + size_t ofs, const char *filename) +{ + const uint8_t *read_data = read_data_; + const uint8_t *expected_data = expected_data_; + size_t i, j; + size_t show_cnt; + + if (!memcmp (read_data, expected_data, size)) + return; + + for (i = 0; i < size; i++) + if (read_data[i] != expected_data[i]) + break; + for (j = i + 1; j < size; j++) + if (read_data[j] == expected_data[j]) + break; + + quiet = false; + msg ("%zu bytes read starting at offset %zu in \"%s\" differ " + "from expected.", j - i, ofs + i, filename); + show_cnt = j - i; + if (j - i > 64) + { + show_cnt = 64; + msg ("Showing first differing %zu bytes.", show_cnt); + } + msg ("Data actually read:"); + hex_dump (ofs + i, read_data + i, show_cnt, true); + msg ("Expected data:"); + hex_dump (ofs + i, expected_data + i, show_cnt, true); + fail ("%zu bytes read starting at offset %zu in \"%s\" differ " + "from expected", j - i, ofs, filename); +} + +void +exec_children (const char *child_name, pid_t pids[], size_t child_cnt) +{ + size_t i; + + for (i = 0; i < child_cnt; i++) + { + char cmd_line[128]; + snprintf (cmd_line, sizeof cmd_line, "%s %zu", child_name, i); + CHECK ((pids[i] = exec (cmd_line)) != PID_ERROR, + "exec child %zu of %zu: \"%s\"", i + 1, child_cnt, cmd_line); + } +} + +void +join_children (pid_t pids[], size_t child_cnt) +{ + size_t i; + + for (i = 0; i < child_cnt; i++) + { + int status = join (pids[i]); + CHECK (status == (int) i, + "join child %zu of %zu returned %d (expected %d)", + i + 1, child_cnt, status, i); + } +}