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

Reply via email to