Author: jilles
Date: Sat Jan  8 00:03:18 2011
New Revision: 217133
URL: http://svn.freebsd.org/changeset/base/217133

Log:
  sed: Try hard links to make -i target available continually.
  
  When creating a backup file, sed renamed the original before renaming the
  changed copy into place, leading to a short time when no file with the
  original name was present (usually only visible on SMP systems). Try
  creating the backup file using a hard link instead, avoiding this problem.
  If creating the hard link fails for any reason, fall back to the old rename
  method.
  
  When not creating a backup file, sed already renamed the changed copy onto
  the original. This remains unchanged.
  
  I am not adding the suppression of redundant fchown/fchmod to this commit,
  because FreeBSD appears to check this in the kernel (for msdosfs at least).
  
  PR:           bin/153261
  Submitted by: Pedro F. Giffuni
  Reviewed by:  dds (older version)
  Obtained from:        Illumos
  MFC after:    2 weeks

Modified:
  head/usr.bin/sed/main.c

Modified: head/usr.bin/sed/main.c
==============================================================================
--- head/usr.bin/sed/main.c     Fri Jan  7 23:39:41 2011        (r217132)
+++ head/usr.bin/sed/main.c     Sat Jan  8 00:03:18 2011        (r217133)
@@ -338,18 +338,35 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
                if (infile != NULL) {
                        fclose(infile);
                        if (*oldfname != '\0') {
-                               if (rename(fname, oldfname) != 0) {
+                               /* if there was a backup file, remove it */
+                               unlink(oldfname);
+                               /*
+                                * Backup the original.  Note that hard links
+                                * are not supported on all filesystems.
+                                */
+                               if ((link(fname, oldfname) != 0) &&
+                                  (rename(fname, oldfname) != 0)) {
                                        warn("rename()");
-                                       unlink(tmpfname);
+                                       if (*tmpfname)
+                                               unlink(tmpfname);
                                        exit(1);
                                }
                                *oldfname = '\0';
                        }
                        if (*tmpfname != '\0') {
                                if (outfile != NULL && outfile != stdout)
-                                       fclose(outfile);
+                                       if (fclose(outfile) != 0) {
+                                               warn("fclose()");
+                                               unlink(tmpfname);
+                                               exit(1);
+                                       }
                                outfile = NULL;
-                               rename(tmpfname, fname);
+                               if (rename(tmpfname, fname) != 0) {
+                                       /* this should not happen really! */
+                                       warn("rename()");
+                                       unlink(tmpfname);
+                                       exit(1);
+                               }
                                *tmpfname = '\0';
                        }
                        outfname = NULL;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to