1 // XFAIL: aix
2 // UNSUPPORTED: windows
3 // RUN: %clang_pgogen -o %t.bin %s -DTESTPATH=\"%t.dir\"
4 // RUN: rm -rf %t.dir
5 // RUN: %run %t.bin
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/stat.h>
11
12 void __llvm_profile_set_dir_mode(unsigned Mode);
13 unsigned __llvm_profile_get_dir_mode(void);
14 void __llvm_profile_recursive_mkdir(char *Path);
15
test(unsigned Mode,const char * TestDir)16 static int test(unsigned Mode, const char *TestDir) {
17 int Ret = 0;
18
19 /* Create a dir and set the mode accordingly. */
20 char *Dir = strdup(TestDir);
21 if (!Dir)
22 return -1;
23 __llvm_profile_set_dir_mode(Mode);
24 __llvm_profile_recursive_mkdir(Dir);
25
26 if (Mode != __llvm_profile_get_dir_mode())
27 Ret = -1;
28 else {
29 // From 'man mkdir':
30 // "If the parent directory has the set-group-ID bit set, then so will the
31 // newly created directory." So we mask off S_ISGID below; this test cannot
32 // control its parent directory.
33 const unsigned Expected = ~umask(0) & Mode;
34 struct stat DirSt;
35 if (stat(Dir, &DirSt) == -1)
36 Ret = -1;
37 // AIX has some extended definition of high order bits for st_mode, avoid trying to comparing those by masking them off.
38 else if (((DirSt.st_mode & ~S_ISGID) & 0xFFFF) != Expected) {
39 printf("Modes do not match: Expected %o but found %o (%s)\n", Expected,
40 DirSt.st_mode, Dir);
41 Ret = -1;
42 }
43 }
44
45 free(Dir);
46 return Ret;
47 }
48
main(void)49 int main(void) {
50 if (test(S_IFDIR | 0777, TESTPATH "/foo/bar/baz/") ||
51 test(S_IFDIR | 0666, TESTPATH "/foo/bar/qux/"))
52 return -1;
53 return 0;
54 }
55