gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master a05dafe: Checks on the output's directory


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master a05dafe: Checks on the output's directory
Date: Fri, 1 Sep 2017 18:16:10 -0400 (EDT)

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

    Checks on the output's directory
    
    Until now, if the input to the old `gal_checkset_check_remove_file' didn't
    exist (the file, not necessarily the directory) no error was
    reported. However, when the user doen't have write permissions in the
    directory or it doesn't exist, later errors (usually CFITSIO) may not be
    clear enough. So if the file doesn't exist, this file now checks its
    directory also and aborts if it is not suitable. Also, the name of the
    function was changed to `gal_checkset_writable_remove'.
    
    This process actually started by noticing that in the Fits program, we were
    mistakenly feeding this function with the input filename, not the output
    filename! So this tiny bug is also corrected with this commit.
---
 bin/arithmetic/ui.c              |   4 +-
 bin/convertt/eps.c               |   4 +-
 bin/convertt/ui.c                |   2 +-
 bin/convolve/ui.c                |   8 +-
 bin/crop/onecrop.c               |   4 +-
 bin/fits/fits.c                  |   2 +-
 bin/fits/ui.c                    |   2 +-
 bin/mknoise/ui.c                 |   2 +-
 bin/mkprof/mkprof.c              |   2 +-
 bin/mkprof/ui.c                  |   4 +-
 bin/noisechisel/clumps.c         |   2 +-
 bin/noisechisel/ui.c             |   2 +-
 bin/warp/ui.c                    |   2 +-
 lib/checkset.c                   | 164 +++++++++++++++++++--------------------
 lib/fits.c                       |   2 +-
 lib/gnuastro-internal/checkset.h |  14 ++--
 lib/options.c                    |   2 +-
 lib/txt.c                        |   2 +-
 18 files changed, 112 insertions(+), 112 deletions(-)

diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index e3cbac3..8e591df 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -256,8 +256,8 @@ ui_check_options_and_arguments(struct arithmeticparams *p)
           if(output_checked==0)
             {
               if(p->cp.output)
-                gal_checkset_check_remove_file(p->cp.output, 0,
-                                               p->cp.dontdelete);
+                gal_checkset_writable_remove(p->cp.output, 0,
+                                             p->cp.dontdelete);
               else
                 p->cp.output=gal_checkset_automatic_output(&p->cp, token->v,
                                                            "_arith.fits");
diff --git a/bin/convertt/eps.c b/bin/convertt/eps.c
index 3b3d06f..efa3e33 100644
--- a/bin/convertt/eps.c
+++ b/bin/convertt/eps.c
@@ -390,11 +390,11 @@ eps_write_eps_or_pdf(struct converttparams *p)
   if(p->outformat==OUT_FORMAT_EPS)
     {
       epsfilename=p->cp.output;
-      gal_checkset_check_remove_file(epsfilename, 0, p->cp.dontdelete);
+      gal_checkset_writable_remove(epsfilename, 0, p->cp.dontdelete);
     }
   else if (p->outformat==OUT_FORMAT_PDF)
     {
-      gal_checkset_check_remove_file(p->cp.output, 0, p->cp.dontdelete);
+      gal_checkset_writable_remove(p->cp.output, 0, p->cp.dontdelete);
       epsfilename=gal_checkset_automatic_output(&p->cp, p->cp.output, ".ps");
     }
   else
diff --git a/bin/convertt/ui.c b/bin/convertt/ui.c
index 5979925..2f9f4d2 100644
--- a/bin/convertt/ui.c
+++ b/bin/convertt/ui.c
@@ -726,7 +726,7 @@ ui_set_output(struct converttparams *p)
     }
 
   /* Check if the output already exists. */
-  gal_checkset_check_remove_file(cp->output, 0, cp->dontdelete);
+  gal_checkset_writable_remove(cp->output, 0, cp->dontdelete);
 }
 
 
diff --git a/bin/convolve/ui.c b/bin/convolve/ui.c
index 0df6486..3fbb912 100644
--- a/bin/convolve/ui.c
+++ b/bin/convolve/ui.c
@@ -334,19 +334,19 @@ ui_preparations(struct convolveparams *p)
   /* Set the output name if the user hasn't set it. */
   if(cp->output==NULL)
     cp->output=gal_checkset_automatic_output(cp, p->filename, outsuffix);
-  gal_checkset_check_remove_file(cp->output, 0, cp->dontdelete);
+  gal_checkset_writable_remove(cp->output, 0, cp->dontdelete);
   if(p->checkfreqsteps)
     {
       p->freqstepsname=gal_checkset_automatic_output(cp, p->filename,
                                                      "_freqsteps.fits");
-      gal_checkset_check_remove_file(p->freqstepsname, 0, cp->dontdelete);
+      gal_checkset_writable_remove(p->freqstepsname, 0, cp->dontdelete);
     }
   if(cp->tl.checktiles)
     {
       cp->tl.tilecheckname=gal_checkset_automatic_output(cp, p->filename,
                                                          "_tiled.fits");
-      gal_checkset_check_remove_file(cp->tl.tilecheckname, 0,
-                                     cp->dontdelete);
+      gal_checkset_writable_remove(cp->tl.tilecheckname, 0,
+                                   cp->dontdelete);
     }
 
 
diff --git a/bin/crop/onecrop.c b/bin/crop/onecrop.c
index f09dbc6..282046a 100644
--- a/bin/crop/onecrop.c
+++ b/bin/crop/onecrop.c
@@ -457,7 +457,7 @@ onecrop_name(struct onecropparams *crp)
                  p->suffix);
 
       /* Make sure the file doesn't exist. */
-      gal_checkset_check_remove_file(crp->name, 0, cp->dontdelete);
+      gal_checkset_writable_remove(crp->name, 0, cp->dontdelete);
     }
   else
     {
@@ -465,7 +465,7 @@ onecrop_name(struct onecropparams *crp)
       if(p->outnameisfile)            /* An output file was specified. */
         {
           crp->name=cp->output;
-          gal_checkset_check_remove_file(crp->name, 0, cp->dontdelete);
+          gal_checkset_writable_remove(crp->name, 0, cp->dontdelete);
         }
       else          /* The output was a directory, use automatic output. */
         crp->name=gal_checkset_automatic_output(cp,
diff --git a/bin/fits/fits.c b/bin/fits/fits.c
index 60db9f6..e96e45d 100644
--- a/bin/fits/fits.c
+++ b/bin/fits/fits.c
@@ -313,7 +313,7 @@ fits_hdu_copy(struct fitsparams *p, int cut1_copy0, int *r)
 int
 fits(struct fitsparams *p)
 {
-  int r=EXIT_SUCCESS, printhduinfo=1;;
+  int r=EXIT_SUCCESS, printhduinfo=1;
 
   switch(p->mode)
     {
diff --git a/bin/fits/ui.c b/bin/fits/ui.c
index a359994..6f1388e 100644
--- a/bin/fits/ui.c
+++ b/bin/fits/ui.c
@@ -257,7 +257,7 @@ ui_read_check_only_options(struct fitsparams *p)
 
       /* Make sure the output name is set. */
       if(p->cp.output)
-        gal_checkset_check_remove_file(p->filename, 1, p->cp.dontdelete);
+        gal_checkset_writable_remove(p->cp.output, 1, p->cp.dontdelete);
       else
         p->cp.output=gal_checkset_automatic_output(&p->cp, p->filename,
                                                    "_ext.fits");
diff --git a/bin/mknoise/ui.c b/bin/mknoise/ui.c
index 79ab5a0..7388979 100644
--- a/bin/mknoise/ui.c
+++ b/bin/mknoise/ui.c
@@ -297,7 +297,7 @@ ui_preparations(struct mknoiseparams *p)
 
   /* Set the output name: */
   if(p->cp.output)
-    gal_checkset_check_remove_file(p->cp.output, 0, p->cp.dontdelete);
+    gal_checkset_writable_remove(p->cp.output, 0, p->cp.dontdelete);
   else
     p->cp.output=gal_checkset_automatic_output(&p->cp, p->inputname,
                                                "_noised.fits");
diff --git a/bin/mkprof/mkprof.c b/bin/mkprof/mkprof.c
index ea1f6ab..3a73cdc 100644
--- a/bin/mkprof/mkprof.c
+++ b/bin/mkprof/mkprof.c
@@ -139,7 +139,7 @@ saveindividual(struct mkonthread *mkp)
   else
     {
       asprintf(&filename, "%s%zu_%s", outdir, ibq->id, p->basename);
-      gal_checkset_check_remove_file(filename, 0, p->cp.dontdelete);
+      gal_checkset_writable_remove(filename, 0, p->cp.dontdelete);
     }
 
 
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index ee15b3a..33c25bf 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -630,8 +630,8 @@ ui_check_options_and_arguments(struct mkprofparams *p)
   /* If a merged image is requested (or `--kernel' the option is called),
      then delete the final filename if it exists. */
   if(p->nomerged==0 && p->kernel)
-    gal_checkset_check_remove_file(p->mergedimgname, p->cp.keep,
-                                   p->cp.dontdelete);
+    gal_checkset_writable_remove(p->mergedimgname, p->cp.keep,
+                                 p->cp.dontdelete);
 }
 
 
diff --git a/bin/noisechisel/clumps.c b/bin/noisechisel/clumps.c
index 3fa2464..fcc7524 100644
--- a/bin/noisechisel/clumps.c
+++ b/bin/noisechisel/clumps.c
@@ -91,7 +91,7 @@ clumps_oversegment(struct clumps_thread_params *cltprm)
                                   GAL_TYPE_INVALID, 2, checkdsize,
                                   NULL, 0, 0, NULL, NULL, NULL);
   tile->block=p->conv;
-  gal_checkset_check_remove_file(filename, 0, 0);
+  gal_checkset_writable_remove(filename, 0, 0);
   if(p->cp.numthreads!=1)
     error(EXIT_FAILURE, 0, "in the debugging mode of `clumps_oversegment' "
           "only one thread must be used");
diff --git a/bin/noisechisel/ui.c b/bin/noisechisel/ui.c
index c09bc49..960eaac 100644
--- a/bin/noisechisel/ui.c
+++ b/bin/noisechisel/ui.c
@@ -323,7 +323,7 @@ ui_set_output_names(struct noisechiselparams *p)
   if(output)
     {
       /* Delete the file if it already exists. */
-      gal_checkset_check_remove_file(p->cp.output, 0, p->cp.dontdelete);
+      gal_checkset_writable_remove(p->cp.output, 0, p->cp.dontdelete);
 
       /* When the output name is given (possibly with directory
          information), the check images will also be put in that same
diff --git a/bin/warp/ui.c b/bin/warp/ui.c
index 94f5662..041d02b 100644
--- a/bin/warp/ui.c
+++ b/bin/warp/ui.c
@@ -867,7 +867,7 @@ ui_preparations(struct warpparams *p)
      which we will need to determine the suffix if no output name is
      specified. */
   if(p->cp.output)
-    gal_checkset_check_remove_file(p->cp.output, 0, p->cp.dontdelete);
+    gal_checkset_writable_remove(p->cp.output, 0, p->cp.dontdelete);
   else
     p->cp.output=gal_checkset_automatic_output(&p->cp, p->inputname,
                                                ui_set_suffix(p));
diff --git a/lib/checkset.c b/lib/checkset.c
index 7a8ac5d..4096a07 100644
--- a/lib/checkset.c
+++ b/lib/checkset.c
@@ -151,6 +151,67 @@ gal_checkset_allocate_copy_set(char *arg, char **copy, int 
*set)
 /**************************************************************/
 /********** Set file names and check if they exist ************/
 /**************************************************************/
+/* Given a filename, this function will separate its directory name
+   part. */
+char *
+gal_checkset_dir_part(char *filename)
+{
+  char *out;
+  size_t i, l=strlen(filename);
+
+  /* Find the first slash from the end. */
+  for(i=l;i!=0;--i)
+    if(filename[i]=='/')
+      break;
+
+  /* If there was no slash, then the current directory should be
+     given: */
+  if(i==0 && filename[0]!='/')
+    gal_checkset_allocate_copy("./", &out);
+  else
+    {
+      gal_checkset_allocate_copy(filename, &out);
+      out[i+1]='\0';
+    }
+
+  return out;
+}
+
+
+
+
+
+/* Given a file name, keep the non-directory part. Note that if there
+   is no forward slash in the input name, the full input name is
+   considered to be the notdir output.*/
+char *
+gal_checkset_not_dir_part(char *filename)
+{
+  size_t i, l;
+  char *out, *tmp=filename;
+
+  /* Find the first `/' to identify the directory */
+  l=strlen(filename);
+  for(i=l;i!=0;--i)
+    if(filename[i]=='/')
+      { tmp=&filename[i+1]; break; }
+
+  /* Get the length of the notdir name: */
+  l=strlen(tmp);
+  errno=0;
+  out=malloc((l+1)*sizeof *out);
+  if(out==NULL)
+    error(EXIT_FAILURE, errno, "%s: %zu bytes for notdir", __func__,
+          (l+1)*sizeof *out);
+
+  strcpy(out, tmp);
+  return out;
+}
+
+
+
+
+
 /* Check if a file exists and report if it doesn't: */
 void
 gal_checkset_check_file(char *filename)
@@ -200,8 +261,9 @@ gal_checkset_check_file_report(char *filename)
    won't be deleted, but the program will abort with an error, informing
    the user that the output can't be made. */
 void
-gal_checkset_check_remove_file(char *filename, int keep, int dontdelete)
+gal_checkset_writable_remove(char *filename, int keep, int dontdelete)
 {
+  char *dir;
   FILE *tmpfile;
 
   /* If the filename is `NULL' everything is ok (it doesn't exist)! In some
@@ -237,11 +299,23 @@ gal_checkset_check_remove_file(char *filename, int keep, 
int dontdelete)
             error(EXIT_FAILURE, errno, "%s", filename);
         }
     }
-  /* If the file doesn't exist, there is no problem, we wanted to
-     remove it any way! Any other kind of error should not be
-     tolerated! */
-  else if(errno!=ENOENT)
-    error(EXIT_FAILURE, errno, "%s", filename);
+
+  /* If the file doesn't exist, we just need to make sure if we have write
+     permissions to its host directory. */
+  else
+    {
+      /* Separate the directory part of the filename. */
+      dir=gal_checkset_dir_part(filename);
+
+      /* Make sure this directory is writable by this user. */
+      errno=0;
+      if( access(dir, W_OK) )
+        error(EXIT_FAILURE, errno, "cannot create any file(s) in the "
+              "directory `%s'", dir);
+
+      /* Clean up. */
+      free(dir);
+    }
 }
 
 
@@ -292,7 +366,7 @@ gal_checkset_dir_0_file_1(char *name, int dontdelete)
     return 0;
   else if (S_ISREG(nameinfo.st_mode))  /* It is a file, GOOD. */
     {
-      gal_checkset_check_remove_file(name, 0, dontdelete);
+      gal_checkset_writable_remove(name, 0, dontdelete);
       return 1;
     }
   else                                 /* Not a file or a dir, ABORT */
@@ -378,7 +452,7 @@ gal_checkset_automatic_output(struct 
gal_options_common_params *cp,
     }
 
   /* Remove the created filename if it already exits. */
-  gal_checkset_check_remove_file(out, cp->keep, cp->dontdelete);
+  gal_checkset_writable_remove(out, cp->keep, cp->dontdelete);
 
   /* Return the resulting filename. */
   return out;
@@ -388,80 +462,6 @@ gal_checkset_automatic_output(struct 
gal_options_common_params *cp,
 
 
 
-/* Given a filename, this function will separate its directory name
-   part. */
-char *
-gal_checkset_dir_part(char *input)
-{
-  char *out;
-  size_t i, l;
-
-  /* Find the first slash. */
-  l=strlen(input);
-  for(i=l;i!=0;--i)
-    if(input[i]=='/')
-      break;
-
-  /* If there was no slash, then the current directory should be
-     given: */
-  if(i==0)
-    {
-      errno=0;
-      out=malloc(3*sizeof *out);
-      if(out==NULL)
-        error(EXIT_FAILURE, errno, "%s: %zu bytes for current directory name",
-              __func__, 3*sizeof *out);
-      strcpy(out, "./");
-    }
-  else
-    {
-      errno=0;
-      out=malloc((l+1)*sizeof *out);
-      if(out==NULL)
-        error(EXIT_FAILURE, errno, "%s: %zu bytes for `out'", __func__,
-              (l+1)*sizeof *out);
-      strcpy(out, input);
-      out[i+1]='\0';
-    }
-
-  return out;
-}
-
-
-
-
-
-/* Given a file name, keep the non-directory part. Note that if there
-   is no forward slash in the input name, the full input name is
-   considered to be the notdir output.*/
-char *
-gal_checkset_not_dir_part(char *input)
-{
-  size_t i, l;
-  char *out, *tmp=input;
-
-  /* Find the first `/' to identify the directory */
-  l=strlen(input);
-  for(i=l;i!=0;--i)
-    if(input[i]=='/')
-      { tmp=&input[i+1]; break; }
-
-  /* Get the length of the notdir name: */
-  l=strlen(tmp);
-  errno=0;
-  out=malloc((l+1)*sizeof *out);
-  if(out==NULL)
-    error(EXIT_FAILURE, errno, "%s: %zu bytes for notdir", __func__,
-          (l+1)*sizeof *out);
-
-  strcpy(out, tmp);
-  return out;
-}
-
-
-
-
-
 /* 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 */
diff --git a/lib/fits.c b/lib/fits.c
index 691fadb..9df4228 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -2617,7 +2617,7 @@ gal_fits_tab_write(gal_data_t *cols, gal_list_str_t 
*comments,
 
 
   /* Remove the output if it already exists. */
-  gal_checkset_check_remove_file(filename, 0, dontdelete);
+  gal_checkset_writable_remove(filename, 0, dontdelete);
 
 
   /* Create the FITS file */
diff --git a/lib/gnuastro-internal/checkset.h b/lib/gnuastro-internal/checkset.h
index 43a6ed6..2bf63a3 100644
--- a/lib/gnuastro-internal/checkset.h
+++ b/lib/gnuastro-internal/checkset.h
@@ -85,6 +85,12 @@ gal_checkset_allocate_copy_set(char *arg, char **copy, int 
*set);
 /**************************************************************/
 /********** Set file names and check if they exist ************/
 /**************************************************************/
+char *
+gal_checkset_dir_part(char *filename);
+
+char *
+gal_checkset_not_dir_part(char *filename);
+
 void
 gal_checkset_check_file(char *filename);
 
@@ -92,7 +98,7 @@ int
 gal_checkset_check_file_report(char *filename);
 
 void
-gal_checkset_check_remove_file(char *filename, int keep, int dontdelete);
+gal_checkset_writable_remove(char *filename, int keep, int dontdelete);
 
 int
 gal_checkset_dir_0_file_1(char *name, int dontdelete);
@@ -101,12 +107,6 @@ char *
 gal_checkset_automatic_output(struct gal_options_common_params *cp,
                               char *inname, char *suffix);
 
-char *
-gal_checkset_dir_part(char *input);
-
-char *
-gal_checkset_not_dir_part(char *input);
-
 void
 gal_checkset_check_dir_write_add_slash(char **dirname);
 
diff --git a/lib/options.c b/lib/options.c
index c67c52b..6b0b202 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -1890,7 +1890,7 @@ options_print_all(struct gal_options_common_params *cp, 
char *dirname,
       asprintf(&filename, "%s/%s.conf", dirname, cp->program_exec);
 
       /* Remove the file if it already exists. */
-      gal_checkset_check_remove_file(filename, 0, 0);
+      gal_checkset_writable_remove(filename, 0, 0);
 
       /* Open the file for writing */
       errno=0;
diff --git a/lib/txt.c b/lib/txt.c
index 32f9578..5e0ecf0 100644
--- a/lib/txt.c
+++ b/lib/txt.c
@@ -1155,7 +1155,7 @@ txt_open_file_write_info(gal_data_t *datall, char **fmts,
 
 
   /* Check the file and open it. */
-  gal_checkset_check_remove_file(filename, 0, dontdelete);
+  gal_checkset_writable_remove(filename, 0, dontdelete);
   errno=0;
   fp=fopen(filename, "w");
   if(fp==NULL)



reply via email to

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