Advertisement
Guest User

Untitled

a guest
May 31st, 2015
344
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.41 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <errno.h>
  4. #include <dirent.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #include <stdlib.h>
  9.  
  10. static int verbose = 1;
  11. static unsigned int dirc = 0, filec = 0, errc = 0;
  12. static time_t last_ts;
  13.  
  14. /* RSS in kilobytes */
  15. static unsigned int
  16. get_rss()
  17. {
  18.     char buf[1024];
  19.     int bytes, i, nf = 1;
  20.     int fd = open("/proc/self/stat", O_RDONLY);
  21.     if (fd == -1)
  22.         return 0;
  23.     bytes = read(fd, buf, sizeof(buf) - 1);
  24.     close(fd);
  25.     if (bytes <= 0)
  26.         return 0;
  27.     buf[bytes] = 0;
  28.     for (i = 0; i < bytes; i++) {
  29.         switch (buf[i]) {
  30.         case 0x20:
  31.             nf++;
  32.             if (nf == 24) /* RSS */
  33.                 return atoi(buf + i) << 2;
  34.             break;
  35.         case 0:
  36.             return 0;
  37.         }
  38.     }
  39.     return 0;
  40. }
  41.  
  42. static void
  43. show_progress()
  44. {
  45.     time_t now = time(NULL);
  46.     if (now != last_ts) {
  47.         last_ts = now;
  48.         printf("\r%u items removed, %u errors, rss = %.2fM", dirc + filec, errc, get_rss() / 1024.0);
  49.         fflush(stdout);
  50.     }
  51. }
  52.  
  53. static void
  54. dir_removed()
  55. {
  56.     dirc++;
  57.     if (verbose)
  58.         show_progress();
  59. }
  60.  
  61. static void
  62. file_removed()
  63. {
  64.     filec++;
  65.     if (verbose)
  66.         show_progress();
  67. }
  68.  
  69. static void
  70. error()
  71. {
  72.     errc++;
  73.     if (verbose)
  74.         show_progress();
  75. }
  76.  
  77. static int
  78. cleardir(int rootfd, const char *relpath)
  79. {
  80.     DIR *dir;
  81.     struct dirent *e;
  82.     struct {
  83.         struct dirent e;
  84.         char path[256];
  85.     } buf;
  86.     int dfd = openat(rootfd, relpath, O_RDONLY | O_DIRECTORY);
  87.     if (dfd == -1) {
  88.         perror("openat");
  89.         return -1;
  90.     }
  91.  
  92.     dir = fdopendir(dfd);
  93.     if (dir == NULL) {
  94.         perror("fdopendir");
  95.         close(dfd);
  96.         return -1;
  97.     }
  98.    
  99.     while (readdir_r(dir, &buf.e, &e) == 0) {
  100.         if (e == NULL)
  101.             break;
  102.         if (strcmp(e->d_name, ".") == 0
  103.                 || strcmp(e->d_name, "..") == 0)
  104.             continue;
  105.         if (unlinkat(dfd, e->d_name, 0) == 0) {
  106.             file_removed();
  107.             continue;
  108.         }
  109.         switch (errno) {
  110.         case EISDIR:
  111.             /* try to unlink possible empty directory */
  112.             if (unlinkat(dfd, e->d_name, AT_REMOVEDIR) == 0) {
  113.                 dir_removed();
  114.             } else if (errno == ENOTEMPTY && cleardir(dfd, e->d_name) == 0) {
  115.                 if (unlinkat(dfd, e->d_name, AT_REMOVEDIR) == 0)
  116.                     dir_removed();
  117.                 else
  118.                     error();
  119.             }
  120.             break;
  121.         default:
  122.             perror("unlinkat");
  123.             error();
  124.         }
  125.     }
  126.    
  127.     closedir(dir);
  128.     return 0;
  129. }
  130.  
  131. int main(int argc, char *argv[])
  132. {
  133.     int i;
  134.     last_ts = time(NULL);
  135.     for (i = 1; i < argc; i++)
  136.         cleardir(AT_FDCWD, argv[i]);
  137.     last_ts = 0;
  138.     show_progress();
  139.     puts("");
  140.     return 0;
  141. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement