diff --git a/2search/2grep b/2search/2grep index 6e568db..47ad4c9 100755 --- a/2search/2grep +++ b/2search/2grep @@ -281,7 +281,7 @@ To solve this sort the input with B. =head1 REPORTING BUGS B<2search> and B<2grep> are part of tangetools. Report bugs on -https://gitlab.com/ole.tange/tangetools/-/issues +https://git.data.coop/tange/tangetools/issues =head1 AUTHOR @@ -870,7 +870,7 @@ sub die_bug { my $bugid = shift; print STDERR ("$Global::progname: This should not happen. You have found a bug.\n", - "Please submit a bug at https://gitlab.com/ole.tange/tangetools/-/issues\n", + "Please submit a bug at https://git.data.coop/tange/tangetools/issues\n", "and include:\n", "* The version number: $Global::version\n", "* The bugid: $bugid\n", @@ -891,7 +891,7 @@ sub version { "This is free software: you are free to change and redistribute it.", "$Global::progname comes with no warranty.", "", - "Web site: https://gitlab.com/ole.tange/tangetools/\n", + "Web site: https://git.data.coop/tange/tangetools/\n", ); } diff --git a/2search/2search b/2search/2search index 6e568db..47ad4c9 100755 --- a/2search/2search +++ b/2search/2search @@ -281,7 +281,7 @@ To solve this sort the input with B. =head1 REPORTING BUGS B<2search> and B<2grep> are part of tangetools. Report bugs on -https://gitlab.com/ole.tange/tangetools/-/issues +https://git.data.coop/tange/tangetools/issues =head1 AUTHOR @@ -870,7 +870,7 @@ sub die_bug { my $bugid = shift; print STDERR ("$Global::progname: This should not happen. You have found a bug.\n", - "Please submit a bug at https://gitlab.com/ole.tange/tangetools/-/issues\n", + "Please submit a bug at https://git.data.coop/tange/tangetools/issues\n", "and include:\n", "* The version number: $Global::version\n", "* The bugid: $bugid\n", @@ -891,7 +891,7 @@ sub version { "This is free software: you are free to change and redistribute it.", "$Global::progname comes with no warranty.", "", - "Web site: https://gitlab.com/ole.tange/tangetools/\n", + "Web site: https://git.data.coop/tange/tangetools/\n", ); } diff --git a/fanspeed/fanspeed b/fanspeed/fanspeed index 63b2b85..154c2f0 100755 --- a/fanspeed/fanspeed +++ b/fanspeed/fanspeed @@ -67,7 +67,7 @@ above 60C, let BIOS control fans. =head1 REPORTING BUGS -Report bugs: https://gitlab.com/ole.tange/tangetools/-/issues +Report bugs: https://git.data.coop/tange/tangetools/issues =head1 AUTHOR diff --git a/find-first-fail/find-first-fail b/find-first-fail/find-first-fail index 21ef58e..db93b21 100755 --- a/find-first-fail/find-first-fail +++ b/find-first-fail/find-first-fail @@ -178,7 +178,7 @@ however, minimize the one it finds. =head1 REPORTING BUGS -Report bugs: https://gitlab.com/ole.tange/tangetools/-/issues +Report bugs: https://git.data.coop/tange/tangetools/issues =head1 AUTHOR @@ -410,7 +410,7 @@ License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. find-first-fail comes with no warranty. -Web site: https://gitlab.com/ole.tange/tangetools/-/tree/master/find-first-fail +Web site: https://git.data.coop/tange/tangetools/src/branch/master/find-first-fail EOF } diff --git a/iothrottle/Makefile b/iothrottle/Makefile index 1404437..04498e3 100644 --- a/iothrottle/Makefile +++ b/iothrottle/Makefile @@ -1,8 +1,8 @@ all: iothrottle true -iothrottle: iothrottle.hex iothrottle.in - perl -pe 's/hex=.*/"hex=".`cat iothrottle.hex`/e' iothrottle.in > iothrottle +iothrottle: iothrottle.hex iothrottle.sh + perl -pe 's/hex=.*/"hex=".`cat iothrottle.hex`/e' iothrottle.sh > iothrottle chmod +x iothrottle iothrottle.so: iothrottle.c @@ -15,7 +15,10 @@ iothrottle.hex: iothrottle.so md5sum iothrottle.so iothrottle.bin test: iothrottle - seq 10000000 | cat | pv > big + ./iothrottle --io 1M ssh localhost seq 1000000 | pv >/dev/null + ./iothrottle --io 3M curl -q https://ftp.nluug.nl/ftp/pub/os/Linux/distr/archlinux/pool/packages/dtkwidget-5.7.2-1-x86_64.pkg.tar.zst >/dev/null + ./iothrottle --io 1M wget -qO- https://ftp.nluug.nl/ftp/pub/os/Linux/distr/archlinux/pool/packages/dtkwidget-5.7.2-1-x86_64.pkg.tar.zst | pv >/dev/null + ./iothrottle -o 20000K seq 10000000 | pv > big ./iothrottle cat big | pv > /dev/null ./iothrottle -i 20M cat big | pv > /dev/null ./iothrottle -o 20000K cat big | pv > /dev/null diff --git a/iothrottle/iothrottle.c b/iothrottle/iothrottle.c index e136316..3c63926 100644 --- a/iothrottle/iothrottle.c +++ b/iothrottle/iothrottle.c @@ -9,12 +9,48 @@ #include #include #include +#include +#include +#include // Function pointers for original read and write and other relevant calls + +// Function pointers for standard I/O functions +int (*original_putchar_unlocked)(int); +int (*original_putc)(int, FILE *); +int (*original_putc_unlocked)(int, FILE *); +size_t (*original_fread)(void *, size_t, size_t, FILE *); +size_t (*original_fread_unlocked)(void *, size_t, size_t, FILE *); +int (*original_fgetc)(FILE *); +char *(*original_fgets)(char *, int, FILE *); +int (*original_getc)(FILE *); +int (*original_getc_unlocked)(FILE *); + +// Function pointers for socket functions +ssize_t (*original_recv)(int, void *, size_t, int); +ssize_t (*original_recvfrom)(int, void *, size_t, int, struct sockaddr *, socklen_t *); +ssize_t (*original_recvmsg)(int, struct msghdr *, int); + +// Function pointers for formatted input functions +int (*original_scanf)(const char *, ...); +int (*original_fscanf)(FILE *, const char *, ...); + +// Additional low-level function pointers +ssize_t (*original_pread)(int fd, void *buf, size_t count, off_t offset); +ssize_t (*original_pwrite)(int fd, const void *buf, size_t count, off_t offset); +ssize_t (*original_readv)(int fd, const struct iovec *iov, int iovcnt); +ssize_t (*original_writev)(int fd, const struct iovec *iov, int iovcnt); + + ssize_t (*original_read)(int fd, void *buf, size_t count); ssize_t (*original_write)(int fd, const void *buf, size_t count); size_t (*original_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t (*original_fwrite_unlocked)(const void *ptr, size_t size, size_t nmemb, FILE *stream); int (*original_fflush)(FILE *stream); +int (*original_fputs)(const char *str, FILE *stream); +int (*original_fputs_unlocked)(const char *str, FILE *stream); +int (*original_putchar)(int c); +int (*original_dprintf)(int fd, const char *format, ...); ssize_t (*original_pread)(int fd, void *buf, size_t count, off_t offset); ssize_t (*original_pwrite)(int fd, const void *buf, size_t count, off_t offset); ssize_t (*original_readv)(int fd, const struct iovec *iov, int iovcnt); @@ -23,6 +59,20 @@ off_t (*original_sendfile)(int out_fd, int in_fd, off_t *offset, size_t count); ssize_t (*original_splice)(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags); ssize_t (*original_copy_file_range)(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags); +// Function pointer for original functions +ssize_t (*original_send)(int sockfd, const void *buf, size_t len, int flags); +ssize_t (*original_sendto)(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen); +ssize_t (*original_sendmsg)(int sockfd, const struct msghdr *msg, int flags); +ssize_t (*original_vmsplice)(int fd, const struct iovec *iov, unsigned long nr_segs, + unsigned int flags); +ssize_t (*original_process_vm_readv)(pid_t pid, const struct iovec *local_iov, + int local_iovcnt, const struct iovec *remote_iov, + int remote_iovcnt, unsigned long flags); +ssize_t (*original_process_vm_writev)(pid_t pid, const struct iovec *local_iov, + int local_iovcnt, const struct iovec *remote_iov, + int remote_iovcnt, unsigned long flags); + // Rate limits in bytes per second static size_t read_limit = 0; // 0 = no limit static size_t write_limit = 0; @@ -42,17 +92,19 @@ void throttle(size_t *bytes, size_t limit, struct timespec *start) { clock_gettime(CLOCK_MONOTONIC, &now); double elapsed = (now.tv_sec - start->tv_sec) + (now.tv_nsec - start->tv_nsec) / 1e9; - + // If it is > 1 second since last write: + // treat as if it is only 1 second + elapsed = elapsed > 1 ? 1 : elapsed; double allowed_bytes = limit * elapsed; if (debug_mode) fprintf(stderr, "allowed: %ld written: %ld\n", - (long)allowed_bytes, *bytes); + (long)allowed_bytes, *bytes); if (*bytes > allowed_bytes) { - *bytes -= allowed_bytes; - double sleep_time = *bytes / (double)limit; + *bytes -= allowed_bytes; + double sleep_time = *bytes / (double)limit; - if (debug_mode) fprintf(stderr, "sleep: %f\n", sleep_time); - usleep((useconds_t)(sleep_time * 1e6)); - *start = now; + if (debug_mode) fprintf(stderr, "sleep: %f\n", sleep_time); + usleep((useconds_t)(sleep_time * 1e6)); + *start = now; } } @@ -75,6 +127,105 @@ size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { return result; } +#undef fwrite_unlocked +size_t fwrite_unlocked(const void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (!original_fwrite_unlocked) { + original_fwrite_unlocked = dlsym(RTLD_NEXT, "fwrite_unlocked"); + if (!original_fwrite_unlocked) { + if (debug_mode) fprintf(stderr, "Error loading original fwrite_unlocked: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + size_t total_bytes = size * nmemb; + throttle(&write_bytes, write_limit, &write_start); + + size_t result = original_fwrite_unlocked(ptr, size, nmemb, stream); + if (result > 0) { + write_bytes += total_bytes; + } + return result; +} + +int fputs(const char *str, FILE *stream) { + if (!original_fputs) { + original_fputs = dlsym(RTLD_NEXT, "fputs"); + if (!original_fputs) { + if (debug_mode) fprintf(stderr, "Error loading original fputs: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + size_t total_bytes = strlen(str); + throttle(&write_bytes, write_limit, &write_start); + + int result = original_fputs(str, stream); + if (result >= 0) { + write_bytes += total_bytes; + } + return result; +} + +int fputs_unlocked(const char *str, FILE *stream) { + if (!original_fputs_unlocked) { + original_fputs_unlocked = dlsym(RTLD_NEXT, "fputs_unlocked"); + if (!original_fputs_unlocked) { + if (debug_mode) fprintf(stderr, "Error loading original fputs_unlocked: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + size_t total_bytes = strlen(str); + throttle(&write_bytes, write_limit, &write_start); + + int result = original_fputs_unlocked(str, stream); + if (result >= 0) { + write_bytes += total_bytes; + } + return result; +} + +int putchar(int c) { + if (!original_putchar) { + original_putchar = dlsym(RTLD_NEXT, "putchar"); + if (!original_putchar) { + if (debug_mode) fprintf(stderr, "Error loading original putchar: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + throttle(&write_bytes, write_limit, &write_start); + + int result = original_putchar(c); + if (result != EOF) { + write_bytes += 1; + } + return result; +} + +int dprintf(int fd, const char *format, ...) { + if (!original_dprintf) { + original_dprintf = dlsym(RTLD_NEXT, "dprintf"); + if (!original_dprintf) { + if (debug_mode) fprintf(stderr, "Error loading original dprintf: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + va_list args; + va_start(args, format); + char buffer[1024]; + int len = vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + + if (len > 0) { + throttle(&write_bytes, write_limit, &write_start); + write_bytes += len; + } + + return original_dprintf(fd, "%s", buffer); +} + int fflush(FILE *stream) { if (!original_fflush) { original_fflush = dlsym(RTLD_NEXT, "fflush"); @@ -257,6 +408,368 @@ ssize_t copy_file_range(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, return result; } +int putchar_unlocked(int c) { + if (!original_putchar_unlocked) { + original_putchar_unlocked = dlsym(RTLD_NEXT, "putchar_unlocked"); + if (!original_putchar_unlocked) { + fprintf(stderr, "Error loading original putchar_unlocked: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&write_bytes, write_limit, &write_start); + int result = original_putchar_unlocked(c); + if (result != EOF) { + write_bytes += 1; + } + return result; +} + +ssize_t recv(int sockfd, void *buf, size_t len, int flags) { + if (!original_recv) { + original_recv = dlsym(RTLD_NEXT, "recv"); + if (!original_recv) { + fprintf(stderr, "Error loading original recv: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + ssize_t result = original_recv(sockfd, buf, len, flags); + if (result > 0) { + read_bytes += result; + } + return result; +} + +ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) { + if (!original_recvfrom) { + original_recvfrom = dlsym(RTLD_NEXT, "recvfrom"); + if (!original_recvfrom) { + fprintf(stderr, "Error loading original recvfrom: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + ssize_t result = original_recvfrom(sockfd, buf, len, flags, src_addr, addrlen); + if (result > 0) { + read_bytes += result; + } + return result; +} + +ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) { + if (!original_recvmsg) { + original_recvmsg = dlsym(RTLD_NEXT, "recvmsg"); + if (!original_recvmsg) { + fprintf(stderr, "Error loading original recvmsg: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + ssize_t result = original_recvmsg(sockfd, msg, flags); + if (result > 0) { + read_bytes += result; + } + return result; +} + +int putc(int c, FILE *stream) { + if (!original_putc) { + original_putc = dlsym(RTLD_NEXT, "putc"); + if (!original_putc) { + fprintf(stderr, "Error loading original putc: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&write_bytes, write_limit, &write_start); + int result = original_putc(c, stream); + if (result != EOF) { + write_bytes += 1; + } + return result; +} + +int putc_unlocked(int c, FILE *stream) { + if (!original_putc_unlocked) { + original_putc_unlocked = dlsym(RTLD_NEXT, "putc_unlocked"); + if (!original_putc_unlocked) { + fprintf(stderr, "Error loading original putc_unlocked: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&write_bytes, write_limit, &write_start); + int result = original_putc_unlocked(c, stream); + if (result != EOF) { + write_bytes += 1; + } + return result; +} + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (!original_fread) { + original_fread = dlsym(RTLD_NEXT, "fread"); + if (!original_fread) { + fprintf(stderr, "Error loading original fread: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + size_t result = original_fread(ptr, size, nmemb, stream); + if (result > 0) { + read_bytes += result * size; + } + return result; +} + +size_t fread_unlocked(void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (!original_fread_unlocked) { + original_fread_unlocked = dlsym(RTLD_NEXT, "fread_unlocked"); + if (!original_fread_unlocked) { + fprintf(stderr, "Error loading original fread_unlocked: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + size_t result = original_fread_unlocked(ptr, size, nmemb, stream); + if (result > 0) { + read_bytes += result * size; + } + return result; +} + +int fgetc(FILE *stream) { + if (!original_fgetc) { + original_fgetc = dlsym(RTLD_NEXT, "fgetc"); + if (!original_fgetc) { + fprintf(stderr, "Error loading original fgetc: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + int result = original_fgetc(stream); + if (result != EOF) { + read_bytes += 1; + } + return result; +} + +char *fgets(char *s, int size, FILE *stream) { + if (!original_fgets) { + original_fgets = dlsym(RTLD_NEXT, "fgets"); + if (!original_fgets) { + fprintf(stderr, "Error loading original fgets: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + char *result = original_fgets(s, size, stream); + if (result != NULL) { + read_bytes += strlen(result); + } + return result; +} + +int getc(FILE *stream) { + if (!original_getc) { + original_getc = dlsym(RTLD_NEXT, "getc"); + if (!original_getc) { + fprintf(stderr, "Error loading original getc: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + int result = original_getc(stream); + if (result != EOF) { + read_bytes += 1; + } + return result; +} + +int getc_unlocked(FILE *stream) { + if (!original_getc_unlocked) { + original_getc_unlocked = dlsym(RTLD_NEXT, "getc_unlocked"); + if (!original_getc_unlocked) { + fprintf(stderr, "Error loading original getc_unlocked: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + int result = original_getc_unlocked(stream); + if (result != EOF) { + read_bytes += 1; + } + return result; +} + +int scanf(const char *format, ...) { + if (!original_scanf) { + original_scanf = dlsym(RTLD_NEXT, "scanf"); + if (!original_scanf) { + fprintf(stderr, "Error loading original scanf: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); // Throttle before reading + va_list args; + va_start(args, format); + int result = vscanf(format, args); + va_end(args); + if (result > 0) { + // Note: Accurate byte count for scanf is difficult; this is an estimate + read_bytes += result; + } + return result; +} + +int fscanf(FILE *stream, const char *format, ...) { + if (!original_fscanf) { + original_fscanf = dlsym(RTLD_NEXT, "fscanf"); + if (!original_fscanf) { + fprintf(stderr, "Error loading original fscanf: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + throttle(&read_bytes, read_limit, &read_start); + va_list args; + va_start(args, format); + int result = vfscanf(stream, format, args); + va_end(args); + if (result > 0) { + read_bytes += result; + } + return result; +} + +ssize_t send(int sockfd, const void *buf, size_t len, int flags) { + if (!original_send) { + original_send = dlsym(RTLD_NEXT, "send"); + if (!original_send) { + fprintf(stderr, "Error loading original send: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + throttle(&write_bytes, write_limit, &write_start); + ssize_t result = original_send(sockfd, buf, len, flags); + if (result > 0) { + write_bytes += result; + } + return result; +} + +ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) { + if (!original_sendto) { + original_sendto = dlsym(RTLD_NEXT, "sendto"); + if (!original_sendto) { + fprintf(stderr, "Error loading original sendto: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + throttle(&write_bytes, write_limit, &write_start); + ssize_t result = original_sendto(sockfd, buf, len, flags, dest_addr, addrlen); + if (result > 0) { + write_bytes += result; + } + return result; +} + +ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) { + if (!original_sendmsg) { + original_sendmsg = dlsym(RTLD_NEXT, "sendmsg"); + if (!original_sendmsg) { + fprintf(stderr, "Error loading original sendmsg: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + size_t total_bytes = 0; + for (int i = 0; i < msg->msg_iovlen; i++) { + total_bytes += msg->msg_iov[i].iov_len; + } + + throttle(&write_bytes, write_limit, &write_start); + ssize_t result = original_sendmsg(sockfd, msg, flags); + if (result > 0) { + write_bytes += total_bytes; + } + return result; +} + +ssize_t vmsplice(int fd, const struct iovec *iov, unsigned long nr_segs, + unsigned int flags) { + if (!original_vmsplice) { + original_vmsplice = dlsym(RTLD_NEXT, "vmsplice"); + if (!original_vmsplice) { + fprintf(stderr, "Error loading original vmsplice: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + size_t total_bytes = 0; + for (unsigned long i = 0; i < nr_segs; i++) { + total_bytes += iov[i].iov_len; + } + + throttle(&write_bytes, write_limit, &write_start); + ssize_t result = original_vmsplice(fd, iov, nr_segs, flags); + if (result > 0) { + write_bytes += total_bytes; + } + return result; +} + +ssize_t process_vm_readv(pid_t pid, const struct iovec *local_iov, int local_iovcnt, + const struct iovec *remote_iov, int remote_iovcnt, + unsigned long flags) { + if (!original_process_vm_readv) { + original_process_vm_readv = dlsym(RTLD_NEXT, "process_vm_readv"); + if (!original_process_vm_readv) { + fprintf(stderr, "Error loading original process_vm_readv: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + size_t total_bytes = 0; + for (int i = 0; i < local_iovcnt; i++) { + total_bytes += local_iov[i].iov_len; + } + + throttle(&read_bytes, read_limit, &read_start); + ssize_t result = original_process_vm_readv(pid, local_iov, local_iovcnt, + remote_iov, remote_iovcnt, flags); + if (result > 0) { + read_bytes += total_bytes; + } + return result; +} + +ssize_t process_vm_writev(pid_t pid, const struct iovec *local_iov, int local_iovcnt, + const struct iovec *remote_iov, int remote_iovcnt, + unsigned long flags) { + if (!original_process_vm_writev) { + original_process_vm_writev = dlsym(RTLD_NEXT, "process_vm_writev"); + if (!original_process_vm_writev) { + fprintf(stderr, "Error loading original process_vm_writev: %s\n", dlerror()); + exit(EXIT_FAILURE); + } + } + + size_t total_bytes = 0; + for (int i = 0; i < local_iovcnt; i++) { + total_bytes += local_iov[i].iov_len; + } + + throttle(&write_bytes, write_limit, &write_start); + ssize_t result = original_process_vm_writev(pid, local_iov, local_iovcnt, + remote_iov, remote_iovcnt, flags); + if (result > 0) { + write_bytes += total_bytes; + } + return result; +} + __attribute__((constructor)) void init() { clock_gettime(CLOCK_MONOTONIC, &read_start); diff --git a/iothrottle/iothrottle.in b/iothrottle/iothrottle.sh similarity index 86% rename from iothrottle/iothrottle.in rename to iothrottle/iothrottle.sh index 6ad58d0..ee6f4db 100755 --- a/iothrottle/iothrottle.in +++ b/iothrottle/iothrottle.sh @@ -1,5 +1,7 @@ #!/bin/bash +# Edit iothrottle.sh - not iothrottle + : <<=cut =pod @@ -30,6 +32,11 @@ To I you can append k, K, m, M, g, G to multiply by 1000, 1024, 1000000, 1048576 respectively. +=item B<--io> I + +Shorthand for B<-i> I B<-o> I + + =item B<-o> I Throttle B(2) to I bytes per second. @@ -55,13 +62,19 @@ speed can go over the limit for a single call. Thus if the limit is 400 bytes/sec, but the call moves 4096 bytes, there will be a pause of 10 secs. -Not all program use B(2) and B(2) for I/O. +If the program spawns processes, each child will get the limit. In +other words: two children each with a limit of 1M may produce 2MB/s. -These all use other methods: cp (to same filesystem), seq +Not all programs use B(2) and B(2) for I/O, so +B tries to intercept other relevant calls, too. + +Tested: curl, wget, ssh, ffmpeg, cat, cp + +These programs use other methods: cp (to same filesystem) Statically linked programs will also not work. -File a bug report when you find other programs. +File a bug report when you find programs that fail. =head1 BUGS @@ -148,6 +161,11 @@ while [[ $# -gt 0 ]]; do OUTPUT_LIMIT="$2" shift 2 ;; + --io) + INPUT_LIMIT="$2" + OUTPUT_LIMIT="$2" + shift 2 + ;; *) break ;; diff --git a/plotpipe/README b/plotpipe/README index 9fb3c2b..963b77c 100644 --- a/plotpipe/README +++ b/plotpipe/README @@ -4,7 +4,7 @@ - plot data from a pipe - -URL: https://gitlab.com/ole.tange/tangetools/-/tree/master/plotpipe +URL: https://git.data.coop/tange/tangetools/src/branch/master/plotpipe We have all been there: You have a bunch of data from a pipe that you would like to get a better understanding of. diff --git a/plotpipe/plotpipe b/plotpipe/plotpipe index ecd191b..b2fab74 100755 --- a/plotpipe/plotpipe +++ b/plotpipe/plotpipe @@ -235,7 +235,7 @@ sub version() { "This is free software: you are free to change and redistribute it.", "$Global::progname comes with no warranty.", "", - "Web site: https://gitlab.com/ole.tange/tangetools/-/tree/master/${Global::progname}\n", + "Web site: https://git.data.coop/tange/tangetools/src/branch/master/${Global::progname}\n", "", ); } diff --git a/seekmaniac/seekmaniac b/seekmaniac/seekmaniac index 2d66eae..b0c1e89 100755 --- a/seekmaniac/seekmaniac +++ b/seekmaniac/seekmaniac @@ -110,7 +110,7 @@ sub die_bug($) { my $bugid = shift; print STDERR ("$Global::progname: This should not happen. You have found a bug.\n", - "Please file a bugreport https://gitlab.com/ole.tange/tangetools/issues\n", + "Please file a bugreport https://git.data.coop/tange/tangetools/issues\n", "\n", "Include this in the report:\n", "* The version number: $Global::version\n", diff --git a/teetime/teetime b/teetime/teetime index 419319e..3ae75e5 100755 --- a/teetime/teetime +++ b/teetime/teetime @@ -269,7 +269,7 @@ sub version() { "This is free software: you are free to change and redistribute it.", "GNU $Global::progname comes with no warranty.", "", - "Web site: https://gitlab.com/ole.tange/tangetools/-/tree/master/${Global::progname}\n", + "Web site: https://git.data.coop/tange/tangetools/src/branch/master/${Global::progname}\n", ); } diff --git a/tracefile/tracefile b/tracefile/tracefile index fa0c165..831583b 100755 --- a/tracefile/tracefile +++ b/tracefile/tracefile @@ -540,7 +540,7 @@ sub version() { "This is free software: you are free to change and redistribute it.", "$Global::progname comes with no warranty.", "", - "Web site: https://gitlab.com/ole.tange/tangetools/-/tree/master/${Global::progname}\n", + "Web site: https://git.data.coop/tange/tangetools/src/branch/master/${Global::progname}\n", ); } diff --git a/transpose/transpose b/transpose/transpose index d5052b9..a096517 100755 --- a/transpose/transpose +++ b/transpose/transpose @@ -108,7 +108,7 @@ cleaned up, if B is stopped abnormally (e.g. killed). =head1 REPORTING BUGS -Report bugs: https://gitlab.com/ole.tange/tangetools/-/issues +Report bugs: https://git.data.coop/tange/tangetools/issues =head1 AUTHOR @@ -495,7 +495,7 @@ License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. transpose comes with no warranty. -Web site: https://gitlab.com/ole.tange/tangetools/-/tree/master/transpose +Web site: https://git.data.coop/tange/tangetools/src/branch/master/transpose EOF } diff --git a/wastebasket/dotlocal/share/vlc/lua/extensions/WasteBasket.lua b/wastebasket/dotlocal/share/vlc/lua/extensions/WasteBasket.lua index 432ad53..aad1254 100644 --- a/wastebasket/dotlocal/share/vlc/lua/extensions/WasteBasket.lua +++ b/wastebasket/dotlocal/share/vlc/lua/extensions/WasteBasket.lua @@ -24,7 +24,7 @@ function descriptor() .. "
This will NOT change your playlist, it will move the file itself. " .. "
Wastebasket will search for a dir called .waste " .. "in the dir of the file and all parent dirs of that."; - url = "https://gitlab.com/ole.tange/tangetools/tree/master/wastebasket" + url = "https://git.data.coop/tange/tangetools/src/branch/master/wastebasket" } end