]> gitweb.michael.orlitzky.com - apply-default-acl.git/commitdiff
apply_default_acl_ex: avoid second call to safe_open() to speed things up.
authorMichael Orlitzky <michael@orlitzky.com>
Fri, 2 Mar 2018 02:08:51 +0000 (21:08 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Fri, 2 Mar 2018 02:08:51 +0000 (21:08 -0500)
src/libadacl.c

index 36812e8af3dd18a4dbfd96f7c7b769865d90298d..49628e75bdf2a1ff73104e059729efc962562096 100644 (file)
@@ -672,14 +672,19 @@ int apply_default_acl_ex(const char* path,
   /* The file descriptor for the directory containing "path" */
   int parent_fd = 0;
 
+  /* dirname() and basename() mangle their arguments, so we need
+     to make copies of "path" before using them. */
+  char* dirname_path_copy = NULL;
+  char* basename_path_copy = NULL;
+
   /* Get the parent directory of "path" with dirname(), which happens
    * to murder its argument and necessitates a path_copy. */
-  char* path_copy = strdup(path);
-  if (path_copy == NULL) {
+  dirname_path_copy = strdup(path);
+  if (dirname_path_copy == NULL) {
     perror("apply_default_acl_ex (strdup)");
     return ACL_ERROR;
   }
-  char* parent = dirname(path_copy);
+  char* parent = dirname(dirname_path_copy);
   parent_fd = safe_open(parent, O_DIRECTORY | O_NOFOLLOW);
   if (parent_fd == OPEN_ERROR) {
     if (errno == ELOOP || errno == ENOTDIR) {
@@ -702,7 +707,16 @@ int apply_default_acl_ex(const char* path,
     goto cleanup;
   }
 
-  fd = safe_open(path, O_NOFOLLOW);
+  /* We already obtained the parent fd safely, so if we use the
+     basename of path here instead of the full thing, then we can get
+     away with using openat() and spare ourselves the slowness of
+     another safe_open(). */
+  basename_path_copy = strdup(path);
+  if (basename_path_copy == NULL) {
+    perror("apply_default_acl_ex (strdup)");
+    return ACL_ERROR;
+  }
+  fd = openat(parent_fd, basename(basename_path_copy), O_NOFOLLOW);
   if (fd == OPEN_ERROR) {
     if (errno == ELOOP || errno == ENOTDIR) {
       /* We hit a symlink, either in the last path component (ELOOP)
@@ -890,7 +904,8 @@ int apply_default_acl_ex(const char* path,
   }
 
  cleanup:
-  free(path_copy);
+  free(dirname_path_copy);
+  free(basename_path_copy);
   if (new_acl != (acl_t)NULL) {
     acl_free(new_acl);
   }