]>
Commit | Line | Data |
---|---|---|
6482a961 GK |
1 | /* |
2 | * 9p utilities | |
3 | * | |
4 | * Copyright IBM, Corp. 2017 | |
5 | * | |
6 | * Authors: | |
7 | * Greg Kurz <[email protected]> | |
8 | * | |
9 | * This work is licensed under the terms of the GNU GPL, version 2 or later. | |
10 | * See the COPYING file in the top-level directory. | |
11 | */ | |
12 | ||
13 | #include "qemu/osdep.h" | |
56ad3e54 | 14 | #include "qemu/xattr.h" |
6482a961 GK |
15 | #include "9p-util.h" |
16 | ||
17 | int relative_openat_nofollow(int dirfd, const char *path, int flags, | |
18 | mode_t mode) | |
19 | { | |
20 | int fd; | |
21 | ||
22 | fd = dup(dirfd); | |
23 | if (fd == -1) { | |
24 | return -1; | |
25 | } | |
26 | ||
27 | while (*path) { | |
28 | const char *c; | |
29 | int next_fd; | |
30 | char *head; | |
31 | ||
32 | /* Only relative paths without consecutive slashes */ | |
33 | assert(path[0] != '/'); | |
34 | ||
35 | head = g_strdup(path); | |
36 | c = strchr(path, '/'); | |
37 | if (c) { | |
38 | head[c - path] = 0; | |
39 | next_fd = openat_dir(fd, head); | |
40 | } else { | |
41 | next_fd = openat_file(fd, head, flags, mode); | |
42 | } | |
43 | g_free(head); | |
44 | if (next_fd == -1) { | |
45 | close_preserve_errno(fd); | |
46 | return -1; | |
47 | } | |
48 | close(fd); | |
49 | fd = next_fd; | |
50 | ||
51 | if (!c) { | |
52 | break; | |
53 | } | |
54 | path = c + 1; | |
55 | } | |
56 | ||
57 | return fd; | |
58 | } | |
56ad3e54 GK |
59 | |
60 | ssize_t fgetxattrat_nofollow(int dirfd, const char *filename, const char *name, | |
61 | void *value, size_t size) | |
62 | { | |
63 | char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename); | |
64 | int ret; | |
65 | ||
66 | ret = lgetxattr(proc_path, name, value, size); | |
67 | g_free(proc_path); | |
68 | return ret; | |
69 | } |