-/* FIXME: Do something tricky to ensure we really do loop in write_all. */
-
-#include "read_write_all/read_write_all.h"
-#include "read_write_all/read_write_all.c"
-#include "tap/tap.h"
+#include <ccan/read_write_all/read_write_all.h>
+#include <ccan/tap/tap.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#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[BUFSZ*2] = { 0 };
- int p2c[2];
- int status;
- pid_t child;
+ char *buffer;
- 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, sizeof(buffer)-1))
- exit(3);
- if (memchr(buffer, 0, sizeof(buffer))) {
- fprintf(stderr, "buffer has 0 at offset %ti\n",
- memchr(buffer, 0, sizeof(buffer)) - (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);
+ free(buffer);
- close(p2c[0]);
- memset(buffer, 0xff, sizeof(buffer));
- signal(SIGUSR1, got_signal);
- ok1(write_all(p2c[1], buffer, sizeof(buffer)));
- 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();
}