Date: Sat, 8 Jan 2011 00:03:19 +0000 (UTC) From: Jilles Tjoelker <jilles@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r217133 - head/usr.bin/sed Message-ID: <201101080003.p0803J1S070169@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101080003.p0803J1S070169>