Created
July 17, 2015 19:25
-
-
Save isoboroff/bca2aee7877567cf781b to your computer and use it in GitHub Desktop.
Sometimes you mistakenly unpack tens of thousands of files into a single directory and maybe your OS/filesystem is unhappy about deleting it. This is recursive rm(1) in pure C.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/types.h> | |
#include <dirent.h> | |
/** | |
* Usage: rm_all <dir-name> | |
* From lkml... | |
*/ | |
#define u32 unsigned int | |
#ifndef COMBSORT | |
#define COMBSORT(size, i, j, COMPARE, EXCHANGE) { \ | |
unsigned gap = size, more, i; \ | |
if (size) do { \ | |
if (gap > 1) gap = gap*10/13; \ | |
if (gap - 9 < 2) gap = 11; \ | |
for (i = size - 1, more = gap > 1; i >= gap; i--) { \ | |
int j = i - gap; \ | |
if (COMPARE) { EXCHANGE; more = 1; } } \ | |
} while (more); } | |
#endif | |
#ifndef exchange | |
#define exchange(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) | |
#endif | |
int main (int argc, char *argv[]) | |
{ | |
char *dirname = argv[1]; | |
unsigned dirnamelen = strlen(dirname); | |
unsigned maxmap = 50000, namesize = 20 * maxmap, count, i, more = 1; | |
struct { char *name; u32 ino; } map[maxmap], *mp; | |
char names[namesize], *namep; | |
struct dirent *de; | |
DIR *dir; | |
dir = opendir(dirname); | |
readdir(dir); | |
readdir(dir); | |
more: | |
for (mp = map, namep = names; mp < map + maxmap; mp++) | |
{ | |
int len; | |
if (!(de = readdir(dir))) | |
{ | |
more = 0; | |
break; | |
} | |
len = strlen(de->d_name); | |
if (namep + len + 1 > names + namesize) break; | |
mp->ino = de->d_ino; | |
mp->name = namep; | |
*namep++ = len; | |
memcpy(namep, de->d_name, len); | |
namep += len; | |
} | |
count = mp - map, i = 0; | |
COMBSORT(count, i, j, map[i].ino < map[j].ino, exchange(map[i], map[j])); | |
for (mp = map; i < count; i++, mp++) | |
{ | |
char name[50], *p = name; | |
memcpy (p, dirname, dirnamelen); | |
p += dirnamelen; | |
*p++ = '/'; | |
memcpy (p, mp->name + 1, *mp->name); | |
p += *mp->name; | |
*p = 0; | |
unlink(name); | |
} | |
if (more) goto more; | |
closedir(dir); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment