#define _GNU_SOURCE #define _XOPEN_SOURCE 600 #include #include #include #include #include #include #include #include #include #include #include static pid_t pid; static int finished = 0; static void child(char *buf, size_t size) { char c = 'b'; printf("child: Buf is %p\n", buf); while (1) { memset(buf, c, size); c++; sleep(1); } } void sig_handler(int sig) { kill(pid, SIGINT); finished = 1; printf("Caught signal\n"); } int main(int argc, char **argv) { char *obuf, *ibuf; size_t size = 1024 * 1024 * 1; int err; int fd; int status; sighandler_t handler; err = posix_memalign((void **)&ibuf, 4096, size); if (err) { fprintf(stderr, "Error allocating buf: %d\n", err); return 1; } obuf = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); if (obuf == MAP_FAILED) { free(obuf); fprintf(stderr, "Error allocating buf: %d\n", err); return 1; } pid = fork(); if (pid < 0) { fprintf(stderr, "Problem forking: %d\n", errno); return 1; } if (pid == 0) { child(obuf, size); return 0; } handler = signal(SIGINT, sig_handler); fd = open("testfile", O_RDWR|O_CREAT|O_DIRECT, 0644); if (fd < 0) { fprintf(stderr, "Error opening file: %d\n", errno); err = 1; goto out; } printf("obuf is %p\n", obuf); while (!finished) { ssize_t copied; memset(obuf, 'a', size); lseek(fd, 0, SEEK_SET); copied = write(fd, obuf, size); if (copied < 0) { fprintf(stderr, "Error writing: %d\n", errno); err = 1; break; } else if (copied < size) { fprintf(stderr, "Weird, short write: %d\n", copied); } lseek(fd, 0, SEEK_SET); copied = read(fd, ibuf, copied); if (copied < 0) { fprintf(stderr, "Read failed: %d\n", copied); err = 1; break; } } out: if (err) kill(pid, SIGINT); waitpid(pid, &status, 0); close(fd); munmap(obuf, 4096); free(ibuf); return err; }