-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.cpp
74 lines (68 loc) · 1.41 KB
/
util.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/* This file is part of the Casa Mia Datastore Project at UBC.It is distributed under the terms of
* version 2 of the GNU GPL. See the file LICENSE for details. */
#define _ATFILE_SOURCE
#include <dirent.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "openat.h"
#include "util.h"
int util::rm_r(int dfd, const char * path)
{
DIR * dir;
struct stat64 st;
struct dirent * ent;
int fd, copy, r = fstatat64(dfd, path, &st, AT_SYMLINK_NOFOLLOW);
if(r < 0)
return r;
if(!S_ISDIR(st.st_mode))
return unlinkat(dfd, path, 0);
fd = openat(dfd, path, O_RDONLY);
if(fd < 0)
return fd;
copy = dup(fd);
if(copy < 0)
{
close(fd);
return copy;
}
dir = fdopendir(copy);
if(!dir)
{
close(copy);
close(fd);
return -1;
}
while((ent = readdir(dir)))
{
if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
continue;
r = rm_r(fd, ent->d_name);
if(r < 0)
break;
}
closedir(dir);
close(fd);
if(r < 0)
return r;
return unlinkat(dfd, path, AT_REMOVEDIR);
}
istr util::tilde_home(const istr & path)
{
size_t length;
const char * home = getenv("HOME");
if(!home)
return path;
length = strlen(home);
if(!length)
return path;
if(home[length - 1] == '/')
if(!--length)
return path;
if(strncmp(path, home, length))
return path;
if(path[length] != '/')
return path[length] ? path : "~";
char result[path.length() - length + 2];
sprintf(result, "~%s", &path[length]);
return result;
}