Project

General

Profile

Bug #585

sed -i doesn't work on FAT filesystems

Added by Garrett D'Amore over 9 years ago. Updated over 9 years ago.

Status:
Resolved
Priority:
Normal
Category:
cmd - userland programs
Start date:
2010-12-29
Due date:
% Done:

100%

Estimated time:
Difficulty:
Tags:

Description

Because some filesystems (FAT) don't support hard links, sed won't work with it as it stands today.

At the same time, I noticed that fchown() fails on such systems, and always generates a warning message. We need a fix for this.

History

#1

Updated by Garrett D'Amore over 9 years ago

Here are my diffs:

Fix -i for use on FAT filesystems.

diff -r 8dc1138162bb -r 8f57c5740417 usr/src/cmd/sed/main.c
--- a/usr/src/cmd/sed/main.c    Thu Dec 16 09:43:44 2010 -0800
+++ b/usr/src/cmd/sed/main.c    Wed Dec 29 10:06:13 2010 -0800
@@ -303,7 +303,7 @@
 int
 mf_fgets(SPACE *sp, enum e_spflag spflag)
 {
-    struct stat sb;
+    struct stat sb, nsb;
     size_t len;
     char *p;
     int c;
@@ -338,9 +338,15 @@
             if (*oldfname != '\0') {
                 /* if there was a backup file, remove it */
                 (void) unlink(oldfname);
-                if (link(fname, oldfname) != 0) {
-                    warn("link()");
-                    (void) unlink(tmpfname);
+                /*
+                 * Backup the original.  Note that hard links
+                 * are not supported on all filesystems.
+                 */
+                if ((link(fname, oldfname) != 0) &&
+                   (rename(fname, oldfname) != 0)) {
+                    warn("rename()");
+                    if (*tmpfname)
+                        (void) unlink(tmpfname);
                     exit(1);
                 }
                 *oldfname = '\0';
@@ -398,9 +404,22 @@
             (void) unlink(tmpfname);
             if ((outfile = fopen(tmpfname, "w")) == NULL)
                 err(1, "%s", fname);
-            if (fchown(fileno(outfile), sb.st_uid, sb.st_gid) != 0)
+            /*
+             * Some file systems don't support chown or
+             * chmod fully.  On those, the owner/group and
+             * permissions will already be set to what
+             * they need to be.
+             */
+            if (fstat(fileno(outfile), &nsb) != 0) {
+                warn("fstat()");
+            }
+            if (((sb.st_uid != nsb.st_uid) ||
+                (sb.st_gid != nsb.st_gid)) &&
+                (fchown(fileno(outfile), sb.st_uid, sb.st_gid)
+                != 0))
                 warn("fchown()");
-            if (fchmod(fileno(outfile), sb.st_mode & 07777) != 0)
+            if ((sb.st_mode != nsb.st_mode) &&
+                (fchmod(fileno(outfile), sb.st_mode & 07777) != 0))
                 warn("fchmod()");
             outfname = tmpfname;
             if (!ispan) {
#2

Updated by Garrett D'Amore over 9 years ago

  • Status changed from New to Resolved
  • % Done changed from 0 to 100

Pushed in:

changeset: 13261:12b93a567f6f
tag: tip
user: Garrett D'Amore <>
date: Wed Dec 29 12:43:27 2010 -0800
description:
585 sed -i doesn't work on FAT filesystems
Reviewed by:
Reviewed by:
Approved by:

Also available in: Atom PDF