diff options
author | Aaron Ball <nullspoon@oper.io> | 2022-10-31 17:53:04 -0600 |
---|---|---|
committer | Aaron Ball <nullspoon@oper.io> | 2022-10-31 17:53:04 -0600 |
commit | 0e0fb17e26612caeea11600e2f17a54cecf651db (patch) | |
tree | ce2a5ead628431fff689fef6398c3a77eb0c6c37 | |
parent | 2056e1a2ec447cc0e9378d33667a6f26685725a0 (diff) | |
download | leak-utils-0e0fb17e26612caeea11600e2f17a54cecf651db.tar.gz leak-utils-0e0fb17e26612caeea11600e2f17a54cecf651db.tar.xz |
Add fdleak tool
This tool opens the specified number of file descriptors and then
deletes the source file to create dead file descriptors.
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | src/fdleak.c | 108 |
2 files changed, 112 insertions, 1 deletions
@@ -1,10 +1,13 @@ all: memleak balloon clean: - rm -vf memleak balloon + rm -vf memleak balloon fdleak memleak: cc --std=gnu99 -O2 -Wall src/memleak.c -o memleak balloon: cc --std=gnu99 -O2 -Wall src/balloon.c -o balloon + +fdleak: + cc --std=gnu99 -O2 -Wall src/fdleak.c -o fdleak diff --git a/src/fdleak.c b/src/fdleak.c new file mode 100644 index 0000000..7264170 --- /dev/null +++ b/src/fdleak.c @@ -0,0 +1,108 @@ +/** + * FDleak leaks dead file descriptors (and cleans them up) + * Copyright (C) 2022 Aaron Ball, nullspoon@oper.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> // Provides unlink +#include <signal.h> +#include <string.h> +#include <errno.h> + +#include <sys/resource.h> + +FILE** FDS; + +void cleanup() { + long i = 0; + printf("Freeing leaked files\n"); + while(FDS[i] != NULL) { + printf("Closing leaked file %ld\n", i); + fclose(FDS[i]); + i++; + } + free(FDS); +} + +void handler(int sig) { + cleanup(); + exit(128); +} + +FILE* leakfd(char* path) { + FILE* fd = NULL; + fd = fopen(path, "w"); + if(!fd) + return NULL; + fprintf(fd, "Ohhai!\n"); + fflush(fd); + unlink(path); // Ahhhhhh + return fd; // Much logic, very sense +} + +int main(int argc, char* argv[]) { + long count = 0; + long i = 0; + char fdpath[256]; + signal(SIGINT, handler); + struct rlimit rl; + + // Set soft limit to max + getrlimit(RLIMIT_NOFILE, &rl); + rl.rlim_cur = rl.rlim_max; + + if(setrlimit(RLIMIT_NOFILE, &rl) != 0) { + printf("Error setting soft limit on open files\n"); + printf("%s\n", strerror(errno)); + return 1; + } + + if(argc == 1) { + printf("Desccriptor leak count required\n"); + return 1; + } + count = strtol(argv[1], NULL, 10); + + // Block at 3 less than max because stdin, stdout, and stderr + if(count > (rl.rlim_cur) - 3) { + printf("ERROR: Requested FD leaks exceeds allowed maximum of %ld\n", + rl.rlim_cur - 3); + return 1; + } + + // Allocate memory for descriptor array + FDS = malloc((sizeof(FILE*) * count) + 1); + memset(FDS, 0, count + 1); + + while(i < count) { + sprintf(fdpath, "/tmp/fdleak-%ld.txt", i); + printf("Leaking file %s\n", fdpath); + FDS[i] = leakfd(fdpath); + if(FDS[i] == NULL) { + cleanup(); + printf("ERROR opening file descriptor %ld, %s\n", i, fdpath); + printf("%s\n", strerror(errno)); + return 1; + } + i++; + } + + printf("Done. Press Enter to free memory.\n"); + fgetc(stdin); + cleanup(); + + return 0; +} |