xref: /llvm-project/compiler-rt/test/profile/instrprof-set-dir-mode.c (revision 2f6439bcf9bda13a80adb4b7f6c587d2d44fbb2e)
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