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
This commit is contained in:
Jilles Tjoelker 2011-01-08 00:03:18 +00:00
parent 462e3e88b3
commit 919e14f01e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=217133

View File

@ -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;