diff options
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | Makefile | 24 | ||||
-rw-r--r-- | limit.c | 42 | ||||
-rw-r--r-- | measure.c | 2 | ||||
-rw-r--r-- | yes.c | 13 |
6 files changed, 66 insertions, 24 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea677b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*\#* +*~ +*.o +*.su +/yes +/limit +/measure @@ -1,6 +1,6 @@ ISC License -© 2017 Mattias Andrée <maandree@kth.se> +© 2017, 2021 Mattias Andrée <maandree@kth.se> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1841767 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +.POSIX: + +CC = cc + +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE +CFLAGS = -std=c99 -Wall -O2 +LDFLAGS = -s + +BIN = yes limit measure + + +all: $(BIN) + +.o: + $(CC) -o $@ $< $(LDFLAGS) + +.c.o: + $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + +clean: + rm -f -- *.o *.su $(BIN) + +.SUFFIXES: +.SUFFIXES: .c .o @@ -1,6 +1,5 @@ /* See LICENSE file for copyright and license details. */ - -#define _GNU_SOURCE +#include <errno.h> #include <fcntl.h> #include <limits.h> #include <stdio.h> @@ -15,38 +14,53 @@ int -main(int argc, char *argv[]) +main(int argc, const char *argv[]) { static char buf[1 << 16]; - int rw1[2], rw2[2], n = 0, m; + int rw1[2], rw2[2], n = 0; ssize_t r, p, w; size_t sum = 0, totsum = 0; struct timespec start, end; double rate; + int capacity, flags; if (!argc) *argv = "limit"; - if (pipe(rw1) || fcntl(*rw1, F_SETPIPE_SZ, CAPACITY) != CAPACITY) + dprintf(STDERR_FILENO, "Requested capacity: %i\n", CAPACITY); + if (pipe(rw1) || pipe(rw2)) goto fail; - if (pipe(rw2) || fcntl(*rw2, F_SETPIPE_SZ, CAPACITY) != CAPACITY) + capacity = fcntl(*rw1, F_SETPIPE_SZ, CAPACITY); + if (capacity < 0 || fcntl(*rw2, F_SETPIPE_SZ, capacity) != capacity) goto fail; + dprintf(STDERR_FILENO, "Configured capacity: %i\n", capacity); - for (n = CAPACITY; n; n -= (int)r) - if ((r = write(rw1[1], buf, n)) < 0) - goto fail; + flags = fcntl(rw1[1], F_GETFL); + if (flags < 0 || fcntl(rw1[1], F_SETFL, flags |= O_NONBLOCK) < 0) + goto fail; + for (n = capacity, capacity = 0; n; n -= (int)r, capacity += (int)r) { + if ((r = write(rw1[1], buf, (size_t)n)) < 0) { + if (errno != EAGAIN) + goto fail; + n -= 1; + r = 0; + } + } + dprintf(STDERR_FILENO, "Supported capacity: %i\n", capacity); + if (fcntl(rw1[1], F_SETFL, flags ^= O_NONBLOCK) < 0) + goto fail; if (clock_gettime(CLOCK_MONOTONIC, &start)) goto fail; for (;;) { - r = splice(rw1[0], NULL, rw2[1], NULL, CAPACITY, 0); + r = splice(rw1[0], NULL, rw2[1], NULL, (size_t)capacity, 0); if (r <= 0) { if (r < 0) goto fail; goto done; } for (p = 0; p < r; p += w) { - w = splice(rw2[0], NULL, rw1[1], NULL, r - p, 0); + w = splice(rw2[0], NULL, rw1[1], NULL, (size_t)(r - p), 0); if (w <= 0) { if (w < 0) goto fail; @@ -61,10 +75,10 @@ main(int argc, char *argv[]) start.tv_sec = end.tv_sec - start.tv_sec; start.tv_nsec = end.tv_nsec - start.tv_nsec; rate = (double)start.tv_nsec; - rate /= 1000000000.; - rate += start.tv_sec; + rate /= (double)1000000000.f; + rate += (double)start.tv_sec; rate = (double)sum / rate; - rate /= 1000000000.; + rate /= (double)1000000000.f; totsum += sum; sum = 0; dprintf(STDERR_FILENO, " %lf GB/s\033[K\n\033[A", rate); @@ -1,6 +1,4 @@ /* See LICENSE file for copyright and license details. */ - -#define _GNU_SOURCE #include <fcntl.h> #include <limits.h> #include <stdio.h> @@ -1,6 +1,4 @@ /* See LICENSE file for copyright and license details. */ - -#define _GNU_SOURCE #include <sys/ioctl.h> #include <sys/uio.h> #include <alloca.h> @@ -17,7 +15,7 @@ #endif -static char *argv0; +static const char *argv0; static void (*writeall)(char *, size_t); @@ -55,8 +53,9 @@ writeall_vmsplice(char *buf, size_t n) #endif int -main(int argc, char *argv[]) +main(int argc, const char **argv) { + const char *argvbuf[3] = {NULL, "y", NULL}; size_t n, len, m = 0, p, cap = 0; char *buf, *b; int i, sz, fds[2], flags; @@ -67,7 +66,8 @@ main(int argc, char *argv[]) argv0 = argv[0] ? argv[0] : "yes"; if (argc == 1) { argc = 2; - argv = (char *[]){argv0, "y"}; + argvbuf[0] = argv0; + argv = argvbuf; } n = (size_t)(argc - 1); @@ -141,10 +141,9 @@ main(int argc, char *argv[]) } fallback: - for (p = 0;; p = (p + (size_t)r) % len) { + for (p = 0;; p = (p + (size_t)r) % len) if ((r = write(STDOUT_FILENO, buf + p, len - p)) < 0) goto fail; - } return 0; |