Browse Source

read_write_all: don't rely on write to pipe blocking in tests.

Instead, directly control write().
Rusty Russell 15 years ago
parent
commit
57d7208e55
1 changed files with 42 additions and 44 deletions
  1. 42 44
      ccan/read_write_all/test/run-write_all.c

+ 42 - 44
ccan/read_write_all/test/run-write_all.c

@@ -1,7 +1,4 @@
-/* FIXME: Do something tricky to ensure we really do loop in write_all. */
-
 #include <ccan/read_write_all/read_write_all.h>
-#include <ccan/read_write_all/read_write_all.c>
 #include <ccan/tap/tap.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -13,57 +10,58 @@
 #include <string.h>
 #include <stdio.h>
 
-static volatile int sigcount;
-static void got_signal(int sig)
+static ssize_t test_write(int fd, const void *buf, size_t count);
+#define write test_write
+#include <ccan/read_write_all/read_write_all.c>
+#undef write
+
+static ssize_t write_return;
+
+static ssize_t test_write(int fd, const void *buf, size_t count)
 {
-	sigcount++;
+	if (write_return == 0) {
+		errno = ENOSPC;
+		return 0;
+	}
+
+	if (write_return < 0) {
+		errno = -write_return;
+		/* Don't return EINTR more than once! */
+		if (errno == EINTR)
+			write_return = count;
+		return -1;
+	}
+
+	if (write_return < count)
+		return write_return;
+	return count;
 }
 
-/* < PIPE_BUF *will* be atomic.  But > PIPE_BUF only *might* be non-atomic. */
-#define BUFSZ (1024*1024)
+#define BUFSZ 1024
 
 int main(int argc, char *argv[])
 {
 	char *buffer;
-	int p2c[2];
-	int status;
-	pid_t child;
 
-	buffer = calloc(BUFSZ, 1);
-	plan_tests(4);
+	buffer = malloc(BUFSZ);
+	plan_tests(8);
 
-	/* We fork and torture parent. */
-	if (pipe(p2c) != 0)
-		err(1, "pipe");
-	child = fork();
+	write_return = -ENOSPC;
+	ok1(!write_all(100, buffer, BUFSZ));
+	ok1(errno == ENOSPC);
 
-	if (!child) {
-		close(p2c[1]);
-		/* Make sure they started writing. */
-		if (read(p2c[0], buffer, 1) != 1)
-			exit(1);
-		if (kill(getppid(), SIGUSR1) != 0)
-			exit(2);
-		if (!read_all(p2c[0], buffer+1, BUFSZ-1))
-			exit(3);
-		if (memchr(buffer, 0, BUFSZ)) {
-			fprintf(stderr, "buffer has 0 at offset %ti\n",
-				memchr(buffer, 0, BUFSZ) - (void *)buffer);
-			exit(4);
-		}
-		exit(0);
-	}
-	if (child == -1)
-		err(1, "forking");
+	write_return = -EINTR;
+	ok1(write_all(100, buffer, BUFSZ));
+	ok1(errno == EINTR);
+
+	write_return = 1;
+	errno = 0;
+	ok1(write_all(100, buffer, BUFSZ));
+	ok1(errno == 0);
+
+	write_return = BUFSZ;
+	ok1(write_all(100, buffer, BUFSZ));
+	ok1(errno == 0);
 
-	close(p2c[0]);
-	memset(buffer, 0xff, BUFSZ);
-	signal(SIGUSR1, got_signal);
-	ok1(write_all(p2c[1], buffer, BUFSZ));
-	ok1(sigcount == 1);
-	ok1(wait(&status) == child);
-	ok(WIFEXITED(status) && WEXITSTATUS(status) == 0,
-	   "WIFEXITED(status) = %u, WEXITSTATUS(status) = %u",
-	   WIFEXITED(status), WEXITSTATUS(status));
 	return exit_status();
 }