diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2009-06-19 10:27:38 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2009-06-19 10:27:38 +0000 |
commit | ecd073bd7054c9e13516041e3ef930e39270c8df (patch) | |
tree | bb36abf9662bec5c5027363f6d0d902d00f40815 /lib/fuse_lowlevel.c | |
parent | 17d1cf6956d08de9aa79b4a7691fb50a2446fa18 (diff) | |
download | libfuse-ecd073bd7054c9e13516041e3ef930e39270c8df.tar.gz |
Add fuse_getgroups (high level lib) and fuse_req_getgroups (low
level lib) functions to query the supplementary group IDs for the
current request. Currently this is implemented on Linux by
reading from the /proc filesystem.
Diffstat (limited to 'lib/fuse_lowlevel.c')
-rw-r--r-- | lib/fuse_lowlevel.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index a60c5b8..89e8f2f 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -1575,6 +1575,74 @@ struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, return fuse_lowlevel_new_common(args, op, op_size, userdata); } +#ifdef linux +int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]) +{ + char *buf; + size_t bufsize = 1024; + char path[128]; + int ret; + int fd; + unsigned long pid = req->ctx.pid; + char *s; + + sprintf(path, "/proc/%lu/task/%lu/status", pid, pid); + +retry: + buf = malloc(bufsize); + if (buf == NULL) + return -ENOMEM; + + ret = -EIO; + fd = open(path, O_RDONLY); + if (fd == -1) + goto out_free; + + ret = read(fd, buf, bufsize); + close(fd); + if (ret == -1) { + ret = -EIO; + goto out_free; + } + + if (ret == bufsize) { + free(buf); + bufsize *= 4; + goto retry; + } + + ret = -EIO; + s = strstr(buf, "\nGroups:"); + if (s == NULL) + goto out_free; + + s += 8; + ret = 0; + while (1) { + char *end; + unsigned long val = strtoul(s, &end, 0); + if (end == s) + break; + + s = end; + if (ret < size) + list[ret] = val; + ret++; + } + +out_free: + free(buf); + return ret; +} +#else /* linux */ +/* + * This is currently not implemented on other than Linux... + */ +int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]); +{ + return -ENOSYS; +} +#endif #ifndef __FreeBSD__ |