changeset 13261:12b93a567f6f

585 sed -i doesn't work on FAT filesystems Reviewed by: deano@cloudpixies.com Reviewed by: trisk@nexenta.com Approved by: trisk@nexenta.com
author Garrett D'Amore <garrett@nexenta.com>
date Wed, 29 Dec 2010 12:43:27 -0800
parents b7552a888d42
children 462cc62c3fc6
files usr/src/cmd/sed/main.c
diffstat 1 files changed, 25 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/sed/main.c	Mon Dec 27 21:47:11 2010 +0300
+++ b/usr/src/cmd/sed/main.c	Wed Dec 29 12:43:27 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) {