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
cb(const char * fname,const struct stat * st,int flag)11 cb (const char *fname, const struct stat *st, int flag)
12 {
13   printf ("%s %d\n", fname, flag);
14   cb_called = 1;
15   return 0;
16 }
17 
18 int
main(void)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 ("this test needs to be run by ordinary user");
31       exit (0);
32     }
33 
34   dname = mkdtemp (tmp);
35   if (dname == NULL)
36     {
37       printf ("mkdtemp: %m\n");
38       exit (1);
39     }
40 
41   memcpy (tmp2, tmp, strlen (tmp));
42   dname2 = mkdtemp (tmp2);
43   if (dname2 == NULL)
44     {
45       printf ("mkdtemp: %m\n");
46       rmdir (dname);
47       exit (1);
48     }
49 
50   if (chmod (dname, S_IWUSR|S_IWGRP|S_IWOTH) != 0)
51     {
52       printf ("chmod: %m\n");
53       rmdir (dname);
54       exit (1);
55     }
56 
57   r = ftw (dname2, cb, 10);
58   e = errno;
59   printf ("r = %d", r);
60   if (r != 0)
61     printf (", errno = %d", errno);
62   puts ("");
63 
64   chmod (dname, S_IRWXU|S_IRWXG|S_IRWXO);
65   rmdir (dname2);
66   rmdir (dname);
67 
68   return (r != -1 && e == EACCES) || cb_called;
69 }
70