1*2f6439bcSPaul Robinson // UNSUPPORTED: target={{.*windows.*}}
289e8af6dSMatt Davis // RUN: %clang_pgogen -o %t.bin %s -DTESTPATH=\"%t.dir\"
389e8af6dSMatt Davis // RUN: rm -rf %t.dir
489e8af6dSMatt Davis // RUN: %run %t.bin
589e8af6dSMatt Davis
689e8af6dSMatt Davis #include <stdio.h>
789e8af6dSMatt Davis #include <stdlib.h>
889e8af6dSMatt Davis #include <string.h>
989e8af6dSMatt Davis #include <sys/stat.h>
1089e8af6dSMatt Davis
1189e8af6dSMatt Davis void __llvm_profile_set_dir_mode(unsigned Mode);
1289e8af6dSMatt Davis unsigned __llvm_profile_get_dir_mode(void);
1389e8af6dSMatt Davis void __llvm_profile_recursive_mkdir(char *Path);
1489e8af6dSMatt Davis
test(unsigned Mode,const char * TestDir)1589e8af6dSMatt Davis static int test(unsigned Mode, const char *TestDir) {
1689e8af6dSMatt Davis int Ret = 0;
1789e8af6dSMatt Davis
1889e8af6dSMatt Davis /* Create a dir and set the mode accordingly. */
1989e8af6dSMatt Davis char *Dir = strdup(TestDir);
2089e8af6dSMatt Davis if (!Dir)
2189e8af6dSMatt Davis return -1;
2289e8af6dSMatt Davis __llvm_profile_set_dir_mode(Mode);
2389e8af6dSMatt Davis __llvm_profile_recursive_mkdir(Dir);
2489e8af6dSMatt Davis
2589e8af6dSMatt Davis if (Mode != __llvm_profile_get_dir_mode())
2689e8af6dSMatt Davis Ret = -1;
2789e8af6dSMatt Davis else {
2860a8816cSMatt Davis // From 'man mkdir':
2960a8816cSMatt Davis // "If the parent directory has the set-group-ID bit set, then so will the
3060a8816cSMatt Davis // newly created directory." So we mask off S_ISGID below; this test cannot
3160a8816cSMatt Davis // control its parent directory.
3289e8af6dSMatt Davis const unsigned Expected = ~umask(0) & Mode;
3389e8af6dSMatt Davis struct stat DirSt;
3489e8af6dSMatt Davis if (stat(Dir, &DirSt) == -1)
3589e8af6dSMatt Davis Ret = -1;
36666accf2SJinsong Ji // AIX has some extended definition of high order bits for st_mode, avoid trying to comparing those by masking them off.
37666accf2SJinsong Ji else if (((DirSt.st_mode & ~S_ISGID) & 0xFFFF) != Expected) {
3889e8af6dSMatt Davis printf("Modes do not match: Expected %o but found %o (%s)\n", Expected,
3989e8af6dSMatt Davis DirSt.st_mode, Dir);
4089e8af6dSMatt Davis Ret = -1;
4189e8af6dSMatt Davis }
4289e8af6dSMatt Davis }
4389e8af6dSMatt Davis
4489e8af6dSMatt Davis free(Dir);
4589e8af6dSMatt Davis return Ret;
4689e8af6dSMatt Davis }
4789e8af6dSMatt Davis
main(void)4889e8af6dSMatt Davis int main(void) {
4989e8af6dSMatt Davis if (test(S_IFDIR | 0777, TESTPATH "/foo/bar/baz/") ||
5089e8af6dSMatt Davis test(S_IFDIR | 0666, TESTPATH "/foo/bar/qux/"))
5189e8af6dSMatt Davis return -1;
5289e8af6dSMatt Davis return 0;
5389e8af6dSMatt Davis }
54