gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master 4d87e0d: Internal Library: directory write per


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 4d87e0d: Internal Library: directory write permission checked with temp file
Date: Wed, 9 Oct 2019 22:01:51 -0400 (EDT)

branch: master
commit 4d87e0d6d78c43f2978b560431782fc76ce95796
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    Internal Library: directory write permission checked with temp file
    
    Until now, we were using the `faccessat' function for checking the
    permission flags to write in a library (in particular with the `AT_FDCWD'
    and `AT_EACCESS' macros). But these two macros recently caused a crash on
    macOS 10.9 (while trying to build for Conda).
    
    To fix this problem and have a more generic test, we now actually try to
    build a temporary file in the directory (and delete it afterwards). This
    totally removes the need for the `faccessat' library function and thus the
    need for those problematic macros on older machines.
    
    This fixes bug #56999.
---
 NEWS           |  1 +
 lib/checkset.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/NEWS b/NEWS
index c801b25..0aa6a97 100644
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,7 @@ See the end of the file for license conditions.
   bug #56736: CosmicCalculator crash when a single value given to --obsline.
   bug #56747: ConvertType's SLS colormap has black pixels which should be 
orange.
   bug #56754: Wrong sigma clipping output when many values are equal.
+  bug #56999: Compilation error on macOS 10.9 not recognizing AT_FDCWD.
 
 
 
diff --git a/lib/checkset.c b/lib/checkset.c
index 0cc2098..1464e1f 100644
--- a/lib/checkset.c
+++ b/lib/checkset.c
@@ -595,6 +595,49 @@ gal_checkset_automatic_output(struct 
gal_options_common_params *cp,
 
 
 
+/* Check write-ability by trying to make a temporary file. Return 0 if the
+   directory is writable, and `errno' if it isn't. We won't be using
+   `facccessat' because its not available on some systems (macOS 10.9 and
+   earlier, see https://github.com/conda-forge/staged-recipes/pull/9723
+   ). */
+static int
+checkset_directory_writable(char *dirname)
+{
+  int file_d;
+  int errnum=0;
+  char *tmpname;
+
+  /* Set the template for the temporary file (accounting for the possible
+     extra `/'). */
+  if(dirname[strlen(dirname)-1]=='/')
+    tmpname=gal_checkset_malloc_cat(dirname, "gnuastroXXXXXX");
+  else
+    tmpname=gal_checkset_malloc_cat(dirname, "/gnuastroXXXXXX");
+
+  /* Make the temporary file (with the temporary name) and open it. */
+  errno=0;
+  file_d=mkstemp(tmpname);
+
+  /* See if the file was opened (and thus created). */
+  if(file_d==-1) errnum=errno;
+  else
+    { /* The file was created, close the file. */
+      errno=0;
+      if( close(file_d) == -1 ) errnum=errno;
+      else
+        {/* The file was closed, delete it. */
+          errno=0;
+          if(unlink(tmpname)==-1) errnum=errno;
+        }
+    }
+
+  /* Return the final value. */
+  return errnum;
+}
+
+
+
+
 /* Check if dirname is actually a real directory and that we can
    actually write inside of it. To insure all conditions an actual
    file will be made */
@@ -645,26 +688,27 @@ gal_checkset_check_dir_write_add_slash(char **dirname)
 
 
 
-/* If the given directory exists and is writable, then nothing is done. If
-   it doesn't, it will be created. If it fails at creating the file, or the
-   file isn't writable it returns a non-zero value: the errno, which can be
-   directly used in `error'. */
+/* If the given directory exists and is writable, then nothing is done and
+   this function returns 0. If it doesn't, it will be created. If it fails
+   at creating the file, or the file isn't writable it returns a non-zero
+   value: the errno, which can be directly used in `error'. */
 int
 gal_checkset_mkdir(char *dirname)
 {
   int errnum=0;
   struct stat st={0};
+
+  /* See if the directory exists. */
   if( stat(dirname, &st) == -1 )
-    {
+    { /* The directory doesn't exist, try making it. */
       errno=0;
       if( mkdir(dirname, 0700) == -1 )
         errnum=errno;
     }
   else
-    {
-      errno=0;
-      if( faccessat(AT_FDCWD, dirname, W_OK, AT_EACCESS) == -1 )
-        errnum=errno;
-    }
+    /* The directory exists, see if its writable. */
+    errnum=checkset_directory_writable(dirname);
+
+  /* Return the final `errno'. */
   return errnum;
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]