1 | #include <errno.h> |
2 | #include <ftw.h> |
3 | #include <stdio.h> |
4 | #include <stdlib.h> |
5 | #include <string.h> |
6 | #include <unistd.h> |
7 | |
8 | static int cb_called; |
9 | |
10 | static int |
11 | cb (const char *fname, const struct stat *st, int flag) |
12 | { |
13 | printf (format: "%s %d\n" , fname, flag); |
14 | cb_called = 1; |
15 | return 0; |
16 | } |
17 | |
18 | int |
19 | main (void) |
20 | { |
21 | char tmp[] = "/tmp/ftwXXXXXX" ; |
22 | char tmp2[] = "/tmp/ftwXXXXXX/ftwXXXXXX" ; |
23 | char *dname; |
24 | char *dname2; |
25 | int r; |
26 | int e; |
27 | |
28 | if (getuid () == 0) |
29 | { |
30 | puts (s: "this test needs to be run by ordinary user" ); |
31 | exit (0); |
32 | } |
33 | |
34 | dname = mkdtemp (template: tmp); |
35 | if (dname == NULL) |
36 | { |
37 | printf (format: "mkdtemp: %m\n" ); |
38 | exit (1); |
39 | } |
40 | |
41 | memcpy (tmp2, tmp, strlen (tmp)); |
42 | dname2 = mkdtemp (template: tmp2); |
43 | if (dname2 == NULL) |
44 | { |
45 | printf (format: "mkdtemp: %m\n" ); |
46 | rmdir (path: dname); |
47 | exit (1); |
48 | } |
49 | |
50 | if (chmod (file: dname, S_IWUSR|S_IWGRP|S_IWOTH) != 0) |
51 | { |
52 | printf (format: "chmod: %m\n" ); |
53 | rmdir (path: dname); |
54 | exit (1); |
55 | } |
56 | |
57 | r = ftw (dir: dname2, func: cb, descriptors: 10); |
58 | e = errno; |
59 | printf (format: "r = %d" , r); |
60 | if (r != 0) |
61 | printf (format: ", errno = %d" , errno); |
62 | puts (s: "" ); |
63 | |
64 | chmod (file: dname, S_IRWXU|S_IRWXG|S_IRWXO); |
65 | rmdir (path: dname2); |
66 | rmdir (path: dname); |
67 | |
68 | return (r != -1 && e == EACCES) || cb_called; |
69 | } |
70 | |