mattd updated this revision to Diff 158144. mattd added a comment. - Added a test that creates a directory via __llvm_profile_recursive_mkdir and verifies the mode. - I intend to only commit one of the two tests, but wanted to provide a more specific/detailed test. - I don't know if we really want such a specific test, but it's a potential start at one. - We can definitely ignore windows here (since there is no mode passed to its equivalent to mkdir). - I don't know if there are other systems we need to ignore, e.g., android? - I'm still hesitant to adding the more specific test, it feels very os specific. - I didn't see an alternative to FileCheck's (deprecated) %T, so I wrote a simple 'dirname' routine that is not dependent on libgen. - I hope that is sufficient for this test case.
https://reviews.llvm.org/D49953 Files: lib/profile/InstrProfilingUtil.c lib/profile/InstrProfilingUtil.h test/profile/instrprof-set-dir-mode.c test/profile/instrprof-set-dir-mode2.c
Index: test/profile/instrprof-set-dir-mode2.c =================================================================== --- /dev/null +++ test/profile/instrprof-set-dir-mode2.c @@ -0,0 +1,73 @@ +// UNSUPPORTED: windows +// RUN: %clang_pgogen -o %t %s -DTESTPATH=\"%t\" +// RUN: %run %t + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +void __llvm_profile_set_dir_mode(uint32_t Mode); +unsigned __llvm_profile_get_dir_mode(void); +void __llvm_profile_recursive_mkdir(char *Path); + +/* Drop characters starting from the last '/'. */ +static char *dirname(const char *Filename) { + const char *End; + if (!(End = strrchr(Filename, '/'))) + return NULL; + char *D = strdup(Filename); + if ((intptr_t)End - (intptr_t)Filename - 1 < 0) + return NULL; + D[End - Filename - 1] = '\0'; + return D; +} + +static char *join(const char *Dir, const char *Subdir) { + char *Joined = malloc(strlen(Dir) + strlen(Subdir) + 2); + if (!Joined) + return NULL; + sprintf(Joined, "%s/%s", Dir, Subdir); + return Joined; +} + +static int test(uint32_t Mode, const char *Subdir) { + int Ret = 0; + char *Base, *Dir; + + /* Truncate the path removing the filename and adding Subdir. */ + if (!(Base = dirname(TESTPATH))) + return -1; + if (!(Dir = join(Base, Subdir))) + return -1; + + /* Create a dir and set the mode accordingly. */ + __llvm_profile_set_dir_mode(Mode); + __llvm_profile_recursive_mkdir(Dir); + + if (Mode != __llvm_profile_get_dir_mode()) + Ret = -1; + else { + const uint32_t Expected = ~umask(0) & Mode; + struct stat DirSt; + if (stat(Dir, &DirSt) == -1) + Ret = -1; + else if (DirSt.st_mode != Expected) { + printf("Modes do not match: Expected %o but found %o (%s)\n", Expected, + DirSt.st_mode, Dir); + Ret = -1; + } + } + + free(Base); + free(Dir); + return Ret; +} + +int main(int argc, const char *argv[]) { + if (test(S_IFDIR | 0777, "/foo/bar/baz/") || + test(S_IFDIR | 0666, "/foo/bar/qux/")) + return -1; + return 0; +} Index: test/profile/instrprof-set-dir-mode.c =================================================================== --- /dev/null +++ test/profile/instrprof-set-dir-mode.c @@ -0,0 +1,17 @@ +// RUN: %clang_pgogen -o %t %s +// RUN: %run %t + +void __llvm_profile_set_dir_mode(unsigned Mode); +unsigned __llvm_profile_get_dir_mode(void); + +int main(void) { + __llvm_profile_set_dir_mode(0777); + if (__llvm_profile_get_dir_mode() != 0777) + return -1; + + __llvm_profile_set_dir_mode(0666); + if (__llvm_profile_get_dir_mode() != 0666) + return -1; + + return 0; +} Index: lib/profile/InstrProfilingUtil.h =================================================================== --- lib/profile/InstrProfilingUtil.h +++ lib/profile/InstrProfilingUtil.h @@ -16,6 +16,12 @@ /*! \brief Create a directory tree. */ void __llvm_profile_recursive_mkdir(char *Pathname); +/*! Set the mode used when creating profile directories. */ +void __llvm_profile_set_dir_mode(unsigned Mode); + +/*! Return the directory creation mode. */ +unsigned __llvm_profile_get_dir_mode(void); + int lprofLockFd(int fd); int lprofUnlockFd(int fd); Index: lib/profile/InstrProfilingUtil.c =================================================================== --- lib/profile/InstrProfilingUtil.c +++ lib/profile/InstrProfilingUtil.c @@ -35,6 +35,8 @@ #include "InstrProfiling.h" #include "InstrProfilingUtil.h" +COMPILER_RT_WEAK unsigned lprofDirMode = 0755; + COMPILER_RT_VISIBILITY void __llvm_profile_recursive_mkdir(char *path) { int i; @@ -47,12 +49,19 @@ #ifdef _WIN32 _mkdir(path); #else - mkdir(path, 0755); /* Some of these will fail, ignore it. */ + /* Some of these will fail, ignore it. */ + mkdir(path, __llvm_profile_get_dir_mode()); #endif path[i] = save; } } +COMPILER_RT_VISIBILITY +void __llvm_profile_set_dir_mode(unsigned Mode) { lprofDirMode = Mode; } + +COMPILER_RT_VISIBILITY +unsigned __llvm_profile_get_dir_mode(void) { return lprofDirMode; } + #if COMPILER_RT_HAS_ATOMICS != 1 COMPILER_RT_VISIBILITY uint32_t lprofBoolCmpXchg(void **Ptr, void *OldV, void *NewV) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits