mktemp, sort, tac: don't use undefined after mkstemp failure
authorJim Meyering <meyering@redhat.com>
Wed, 13 Aug 2008 18:53:12 +0000 (20:53 +0200)
committerJim Meyering <meyering@redhat.com>
Thu, 14 Aug 2008 12:37:37 +0000 (14:37 +0200)
When mkstemp fails, the template buffer may have undefined
contents, so we must not print it.
* src/sort.c (create_temp_file): Use temp_dir, not "file"
when diagnosing failed mkstemp, because "file" may be undefined.
* tests/misc/sort-merge: Adjust for new expected output.
Jeph Cowan and Ralf Wildenhues reported the test failure:
http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14235/focus=14257
* src/tac.c (copy_to_temp): Don't use template buffer after
failed mkstemp call, since its contents may be undefined.
* tests/misc/tac (pipe-bad-tmpdir): New test for the above.
* src/mktemp.c (main): Save a copy of the template string,
solely for use in case mkstemp fails.
* tests/misc/mktemp (pipe-bad-tmpdir): New test for the above.

THANKS
src/mktemp.c
src/sort.c
src/tac.c
tests/misc/mktemp
tests/misc/sort-merge
tests/misc/tac

diff --git a/THANKS b/THANKS
index 5f3c5bd..021ff6a 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -250,6 +250,7 @@ Jeff Moore                          jbm@mordor.com
 Jeff Sheinberg                      jeff@bsrd.net
 Jens Elkner                         elkner@imsgroup.de
 Jens Schmidt                        jms@jsds.hamburg.com
+Jeph Cowan                          jeph@ucar.edu
 Jeremy Maitin-Shepard               jbms@cmu.edu
 Jerome Abela                        abela@hsc.fr
 Jérôme Zago                         bug-coreutils-ml@agt-the-walker.net
index 8a09231..d745e60 100644 (file)
@@ -242,20 +242,24 @@ main (int argc, char **argv)
                    quote (template));
         }
 
-      dest_name = file_name_concat (dest_dir, template, NULL);
+      template = file_name_concat (dest_dir, template, NULL);
     }
   else
     {
-      dest_name = xstrdup (template);
+      template = xstrdup (template);
     }
 
+  /* Make a copy to be used in case of diagnostic, since failing
+     mkstemp may leave the buffer in an undefined state.  */
+  dest_name = xstrdup (template);
+
   if (create_directory)
     {
       int err = mkdtemp_len (dest_name, x_count, dry_run);
       if (err != 0)
         {
           error (0, errno, _("failed to create directory via template %s"),
-                 quote (dest_name));
+                 quote (template));
           status = EXIT_FAILURE;
         }
     }
@@ -265,7 +269,7 @@ main (int argc, char **argv)
       if (fd < 0 || (!dry_run && close (fd) != 0))
         {
           error (0, errno, _("failed to create file via template %s"),
-                 quote (dest_name));
+                 quote (template));
           status = EXIT_FAILURE;
         }
     }
index b932a51..92f400a 100644 (file)
@@ -741,7 +741,8 @@ create_temp_file (int *pfd)
   errno = saved_errno;
 
   if (fd < 0)
-    die (_("cannot create temporary file"), file);
+    error (SORT_FAILURE, errno, _("cannot create temporary file in %s"),
+          quote (temp_dir));
 
   *pfd = fd;
   return node;
index 9cf6d60..c83986f 100644 (file)
--- a/src/tac.c
+++ b/src/tac.c
@@ -454,7 +454,8 @@ copy_to_temp (FILE **g_tmp, char **g_tempfile, int input_fd, char const *file)
   fd = mkstemp (template);
   if (fd < 0)
     {
-      error (0, errno, _("cannot create temporary file %s"), quote (tempfile));
+      error (0, errno, _("cannot create temporary file in %s"),
+            quote (tempdir));
       return false;
     }
 
index 616a9e4..3565582 100755 (executable)
@@ -49,6 +49,7 @@ sub check_tmp($$)
 # Turn off localization of executable's output.
 @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 my $prog = 'mktemp';
+my $bad_dir = 'no/such/dir';
 
 my @Tests =
     (
@@ -97,6 +98,12 @@ my @Tests =
       {POST => sub { my ($f) = @_; defined $f or return; chomp $f;
        check_tmp $f, 'F'; unlink $f; rmdir 'a' or die "rmdir a: $!\n" }}
      ],
+
+     ['pipe-bad-tmpdir',
+      {ENV => "TMPDIR=$bad_dir"},
+      {ERR_SUBST => "s,($bad_dir/)[^']+': .*,\$1...,"},
+      {ERR => "$prog: failed to create file via template `$bad_dir/...\n"},
+      {EXIT => 1}],
     );
 
 my $save_temps = $ENV{DEBUG};
index 985d7a4..6b81926 100755 (executable)
@@ -66,8 +66,9 @@ my @Tests =
      # this should fail since nmerge < # of input files, so
      # temp files are needed
      ['nmerge-no', "-m --batch-size=2 -T$badtmp", @inputs,
-        {ERR_SUBST=>"s|: $badtmp/sort.+||"},
-        {ERR=>"$prog: cannot create temporary file\n"}, {EXIT=>2}],
+        {ERR_SUBST=>"s|': .*|':|"},
+        {ERR=>"$prog: cannot create temporary file in `$badtmp':\n"},
+       {EXIT=>2}],
 
      # This used to fail because setting batch-size without also setting
      # buffer size would cause the buffer size to be set to the minimum.
index 2f9981d..9995357 100755 (executable)
@@ -22,6 +22,8 @@ my $prog = 'tac';
 # Turn off localization of executable's output.
 @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 
+my $bad_dir = 'no/such/dir';
+
 my @Tests =
 (
   ['segfault', '-r', {IN=>"a\n"}, {IN=>"b\n"}, {OUT=>"a\nb\n"}],
@@ -58,6 +60,13 @@ my @Tests =
   ['opt-br2', qw(-b -r -s '\._+'),
    {IN=>".__x.___y.____z._1._2.__3.___4"},
    {OUT=>".___4.__3._2._1.____z.___y.__x"}],
+
+  ['pipe-bad-tmpdir',
+   {ENV => "TMPDIR=$bad_dir"},
+   {IN_PIPE => "a\n"},
+   {ERR_SUBST => "s,`$bad_dir': .*,...,"},
+   {ERR => "$prog: cannot create temporary file in ...\n"},
+   {EXIT => 1}],
 );
 
 @Tests = triple_test \@Tests;