Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <dirent.h>
- #include <unistd.h>
- #include <string.h>
- #include <time.h>
- #include <stdlib.h>
- static int verbose = 1;
- static unsigned int dirc = 0, filec = 0, errc = 0;
- static time_t last_ts;
- /* RSS in kilobytes */
- static unsigned int
- get_rss()
- {
- char buf[1024];
- int bytes, i, nf = 1;
- int fd = open("/proc/self/stat", O_RDONLY);
- if (fd == -1)
- return 0;
- bytes = read(fd, buf, sizeof(buf) - 1);
- close(fd);
- if (bytes <= 0)
- return 0;
- buf[bytes] = 0;
- for (i = 0; i < bytes; i++) {
- switch (buf[i]) {
- case 0x20:
- nf++;
- if (nf == 24) /* RSS */
- return atoi(buf + i) << 2;
- break;
- case 0:
- return 0;
- }
- }
- return 0;
- }
- static void
- show_progress()
- {
- time_t now = time(NULL);
- if (now != last_ts) {
- last_ts = now;
- printf("\r%u items removed, %u errors, rss = %.2fM", dirc + filec, errc, get_rss() / 1024.0);
- fflush(stdout);
- }
- }
- static void
- dir_removed()
- {
- dirc++;
- if (verbose)
- show_progress();
- }
- static void
- file_removed()
- {
- filec++;
- if (verbose)
- show_progress();
- }
- static void
- error()
- {
- errc++;
- if (verbose)
- show_progress();
- }
- static int
- cleardir(int rootfd, const char *relpath)
- {
- DIR *dir;
- struct dirent *e;
- struct {
- struct dirent e;
- char path[256];
- } buf;
- int dfd = openat(rootfd, relpath, O_RDONLY | O_DIRECTORY);
- if (dfd == -1) {
- perror("openat");
- return -1;
- }
- dir = fdopendir(dfd);
- if (dir == NULL) {
- perror("fdopendir");
- close(dfd);
- return -1;
- }
- while (readdir_r(dir, &buf.e, &e) == 0) {
- if (e == NULL)
- break;
- if (strcmp(e->d_name, ".") == 0
- || strcmp(e->d_name, "..") == 0)
- continue;
- if (unlinkat(dfd, e->d_name, 0) == 0) {
- file_removed();
- continue;
- }
- switch (errno) {
- case EISDIR:
- /* try to unlink possible empty directory */
- if (unlinkat(dfd, e->d_name, AT_REMOVEDIR) == 0) {
- dir_removed();
- } else if (errno == ENOTEMPTY && cleardir(dfd, e->d_name) == 0) {
- if (unlinkat(dfd, e->d_name, AT_REMOVEDIR) == 0)
- dir_removed();
- else
- error();
- }
- break;
- default:
- perror("unlinkat");
- error();
- }
- }
- closedir(dir);
- return 0;
- }
- int main(int argc, char *argv[])
- {
- int i;
- last_ts = time(NULL);
- for (i = 1; i < argc; i++)
- cleardir(AT_FDCWD, argv[i]);
- last_ts = 0;
- show_progress();
- puts("");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement