[3/3] locale: Fix locale construct_output_path error handling

Message ID 20201014203707.2394289-3-adhemerval.zanella@linaro.org
State Superseded
Headers
Series [1/3] linux: Use INTERNAL_SYSCALL on fstatat{64} |

Commit Message

Adhemerval Zanella Netto Oct. 14, 2020, 8:37 p.m. UTC
  On following localedef code:

237   output_path  = construct_output_path (argv[remaining]);
238   if (output_path == NULL && ! no_archive)
239     error (4, errno, _("cannot create directory for output files"));
240   cannot_write_why = errno;

The 'cannot_write_why' will be set to a non 0 value on success if
euidaccess or mkdir (called by construct_output_path) change the errno
on a success call.

Instead o relying on the errno value regardless the previous libc
call fails or not, explicit set the erro code on failure at
construct_output_path.

Checked on x86_64-linux-gnu.
---
 locale/programs/localedef.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)
  

Patch

diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
index b048bd05b9..4b488d5c2e 100644
--- a/locale/programs/localedef.c
+++ b/locale/programs/localedef.c
@@ -180,7 +180,7 @@  static struct argp argp =
 
 /* Prototypes for local functions.  */
 static void error_print (void);
-static char *construct_output_path (char *path);
+static char *construct_output_path (char *path, int *cannot_write_why);
 static char *normalize_codeset (const char *codeset, size_t name_len);
 
 
@@ -234,10 +234,9 @@  main (int argc, char *argv[])
   /* The parameter describes the output path of the constructed files.
      If the described files cannot be written return a NULL pointer.
      We don't free output_path because we will exit.  */
-  output_path  = construct_output_path (argv[remaining]);
+  output_path  = construct_output_path (argv[remaining], &cannot_write_why);
   if (output_path == NULL && ! no_archive)
     error (4, errno, _("cannot create directory for output files"));
-  cannot_write_why = errno;
 
   /* Now that the parameters are processed we have to reset the local
      ctype locale.  (P1003.2 4.35.5.2)  */
@@ -478,7 +477,7 @@  error_print (void)
    '/' character it is a relative path.  Otherwise it names the locale this
    definition is for.   The returned path must be freed by the caller. */
 static char *
-construct_output_path (char *path)
+construct_output_path (char *path, int *cannot_write_why)
 {
   char *result;
 
@@ -533,6 +532,7 @@  construct_output_path (char *path)
     }
 
   errno = 0;
+  *cannot_write_why = 0;
 
   if (no_archive && euidaccess (result, W_OK) == -1)
     {
@@ -545,14 +545,18 @@  construct_output_path (char *path)
 	      record_verbose (stderr,
 			      _("cannot create output path \'%s\': %s"),
 			      result, strerror (errno));
+	      *cannot_write_why = errno;
 	      free (result);
-	      return NULL;
+	      result = NULL;
 	    }
 	}
       else
-	record_verbose (stderr,
-			_("no write permission to output path \'%s\': %s"),
-			result, strerror (errno));
+	{
+	  record_verbose (stderr,
+			  _("no write permission to output path \'%s\': %s"),
+			  result, strerror (errno));
+          *cannot_write_why = errno;
+	}
     }
 
   return result;