char ***rl) {
FILE *f;
- char **m = 0;
+ char **m = NULL;
int r;
assert(fname);
/* Undoes C style string escaping */
- if (!(r = new(char, length+1)))
+ r = new(char, length+1);
+ if (!r)
return r;
for (f = s, t = r; f < s + length; f++) {
/* hexadecimal encoding */
int a, b;
- if ((a = unhexchar(f[1])) < 0 ||
- (b = unhexchar(f[2])) < 0) {
+ a = unhexchar(f[1]);
+ b = unhexchar(f[2]);
+
+ if (a < 0 || b < 0) {
/* Invalid escape code, let's take it literal then */
*(t++) = '\\';
*(t++) = 'x';
/* octal encoding */
int a, b, c;
- if ((a = unoctchar(f[0])) < 0 ||
- (b = unoctchar(f[1])) < 0 ||
- (c = unoctchar(f[2])) < 0) {
+ a = unoctchar(f[0]);
+ b = unoctchar(f[1]);
+ c = unoctchar(f[2]);
+
+ if (a < 0 || b < 0 || c < 0) {
/* Invalid escape code, let's take it literal then */
*(t++) = '\\';
*(t++) = f[0];
return 0;
}
+static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
+ unsigned i;
+
+ assert(n_fdset == 0 || fdset);
+
+ for (i = 0; i < n_fdset; i++)
+ if (fdset[i] == fd)
+ return true;
+
+ return false;
+}
+
int close_all_fds(const int except[], unsigned n_except) {
DIR *d;
struct dirent *de;
int r = 0;
- if (!(d = opendir("/proc/self/fd")))
- return -errno;
+ assert(n_except == 0 || except);
+
+ d = opendir("/proc/self/fd");
+ if (!d) {
+ int fd;
+ struct rlimit rl;
+
+ /* When /proc isn't available (for example in chroots)
+ * the fallback is brute forcing through the fd
+ * table */
+
+ assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
+ for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
+
+ if (fd_in_set(fd, except, n_except))
+ continue;
+
+ if (close_nointr(fd) < 0)
+ if (errno != EBADF && r == 0)
+ r = -errno;
+ }
+
+ return r;
+ }
while ((de = readdir(d))) {
int fd = -1;
if (fd == dirfd(d))
continue;
- if (except) {
- bool found;
- unsigned i;
-
- found = false;
- for (i = 0; i < n_except; i++)
- if (except[i] == fd) {
- found = true;
- break;
- }
-
- if (found)
- continue;
- }
+ if (fd_in_set(fd, except, n_except))
+ continue;
if (close_nointr(fd) < 0) {
/* Valgrind has its own FD and doesn't want to have it closed */
}
-void freeze(void) {
+_noreturn_ void freeze(void) {
/* Make sure nobody waits for us on a socket anymore */
close_all_fds(NULL, 0);
return 0;
}
+int in_group(const char *name) {
+ gid_t gid, *gids;
+ int ngroups_max, r, i;
+
+ r = get_group_creds(&name, &gid);
+ if (r < 0)
+ return r;
+
+ if (getgid() == gid)
+ return 1;
+
+ if (getegid() == gid)
+ return 1;
+
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ assert(ngroups_max > 0);
+
+ gids = alloca(sizeof(gid_t) * ngroups_max);
+
+ r = getgroups(ngroups_max, gids);
+ if (r < 0)
+ return -errno;
+
+ for (i = 0; i < r; i++)
+ if (gids[i] == gid)
+ return 1;
+
+ return 0;
+}
+
int glob_exists(const char *path) {
glob_t g;
int r, k;