Joe Orton <[EMAIL PROTECTED]> writes:
| shred in fileutils 4.0i will get stuck in a loop if executed with the -u
| option, if the directory the file is in is not writable:
|
| mkdir foo
| touch foo/bar
| chmod u-w foo
| shred -u foo/bar

Thanks.
I've fixed that bug for the next test release.
Here's the patch:

        * src/shred.c (wipename): When repeatedly renaming a file, making the
        name shorter and shorter, skip to the next shorter length length if a
        rename fails (e.g. due to permission denied).  Otherwise, this loop
        would iterate for so long that shred would appear to be stuck in an
        infinite loop for any but the shortest file names.

Index: src/shred.c
===================================================================
RCS file: /fetish/fileutils/src/shred.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- src/shred.c 1999/05/12 16:50:54     1.35
+++ src/shred.c 1999/12/18 16:00:49     1.36
@@ -1589,22 +1589,34 @@
       do
        {
          struct stat st;
-         if (lstat (newname, &st) < 0 && rename (oldname, newname) == 0)
+         if (lstat (newname, &st) < 0)
            {
-             if (dir_fd < 0
-                 || (fdatasync (dir_fd) < 0 && fsync (dir_fd) < 0))
-               sync ();        /* Force directory out */
-             if (flags->verbose)
+             if (rename (oldname, newname) == 0)
                {
-                 /*
-                  * People seem to understand this better than talking
-                  * about renaming oldname.  newname doesn't need
-                  * quoting because we picked it.
-                  */
-                 error (0, 0, _("%s: renamed to `%s'"), qoldname, newname);
+                 if (dir_fd < 0
+                     || (fdatasync (dir_fd) < 0 && fsync (dir_fd) < 0))
+                   sync ();    /* Force directory out */
+                 if (flags->verbose)
+                   {
+                     /*
+                      * People seem to understand this better than talking
+                      * about renaming oldname.  newname doesn't need
+                      * quoting because we picked it.
+                      */
+                     error (0, 0, _("%s: renamed to `%s'"), qoldname, newname);
+                   }
+                 memcpy (oldname + (base - newname), base, len + 1);
+                 break;
                }
-             memcpy (oldname + (base - newname), base, len + 1);
-             break;
+             else
+               {
+                 /* The rename failed: give up on this length.  */
+                 break;
+               }
+           }
+         else
+           {
+             /* newname exists, so increment BASE so we use another */
            }
        }
       while (!incname (base, len));

Reply via email to