浏览代码

Add a function to pull off the final component of a path

Nick Mathewson 13 年之前
父节点
当前提交
3b6cbf2534
共有 4 个文件被更改,包括 68 次插入0 次删除
  1. 34 0
      src/common/compat.c
  2. 2 0
      src/common/compat.h
  3. 2 0
      src/or/connection.c
  4. 30 0
      src/test/test_util.c

+ 34 - 0
src/common/compat.c

@@ -1467,6 +1467,40 @@ get_user_homedir(const char *username)
 }
 #endif
 
+/** Modify <b>fname</b> to contain the name of the directory */
+int
+get_parent_directory(char *fname)
+{
+  char *cp;
+  int at_end = 1;
+  tor_assert(fname);
+#ifdef MS_WINDOWS
+  /* If we start with, say, c:, then don't consider that the start of the path
+   */
+  if (fname[0] && fname[1] == ':') {
+    fname += 2;
+  }
+#endif
+  /* Now we want to remove the final character that */
+  cp = fname + strlen(fname);
+  at_end = 1;
+  while (--cp > fname) {
+    int is_sep = (*cp == '/'
+#ifdef MS_WINDOWS
+                  || *cp == '\\'
+#endif
+                  );
+    if (is_sep) {
+      *cp = '\0';
+      if (! at_end)
+        return 0;
+    } else {
+      at_end = 0;
+    }
+  }
+  return -1;
+}
+
 /** Set *addr to the IP address (in dotted-quad notation) stored in c.
  * Return 1 on success, 0 if c is badly formatted.  (Like inet_aton(c,addr),
  * but works on Windows and Solaris.)

+ 2 - 0
src/common/compat.h

@@ -552,6 +552,8 @@ int switch_id(const char *user);
 char *get_user_homedir(const char *username);
 #endif
 
+int get_parent_directory(char *fname);
+
 int spawn_func(void (*func)(void *), void *data);
 void spawn_exit(void) ATTR_NORETURN;
 

+ 2 - 0
src/or/connection.c

@@ -967,6 +967,8 @@ connection_create_listener(const struct sockaddr *listensockaddr,
       goto err;
     }
     if (get_options()->ControlSocketsGroupWritable) {
+      /* We need to use chmod; fchmod doesn't work on sockets on all
+       * platforms. */
       if (chmod(address, 0660) < 0) {
         log_warn(LD_FS,"Unable to make %s group-writable.", address);
         tor_close_socket(s);

+ 30 - 0
src/test/test_util.c

@@ -1195,6 +1195,35 @@ test_util_listdir(void *ptr)
   }
 }
 
+static void
+test_util_parent_dir(void *ptr)
+{
+  char *cp;
+  (void)ptr;
+
+#define T(input,expect_ok,output)               \
+  do {                                          \
+    int ok;                                     \
+    cp = tor_strdup(input);                     \
+    ok = get_parent_directory(cp);              \
+    tt_int_op(ok, ==, expect_ok);               \
+    if (ok==0)                                  \
+      tt_str_op(cp, ==, output);                \
+    tor_free(cp);                               \
+  } while (0);
+
+  T("/home/wombat/knish", 0, "/home/wombat");
+  T("/home/wombat/knish/", 0, "/home/wombat");
+  T("./home/wombat/knish/", 0, "./home/wombat");
+  T("./wombat", 0, ".");
+  T("", -1, "");
+  T("/", -1, "");
+  T("////", -1, "");
+
+ done:
+  tor_free(cp);
+}
+
 #ifdef MS_WINDOWS
 static void
 test_util_load_win_lib(void *ptr)
@@ -1286,6 +1315,7 @@ struct testcase_t util_tests[] = {
   UTIL_TEST(find_str_at_start_of_line, 0),
   UTIL_TEST(asprintf, 0),
   UTIL_TEST(listdir, 0),
+  UTIL_TEST(parent_dir, 0),
 #ifdef MS_WINDOWS
   UTIL_TEST(load_win_lib, 0),
 #endif