sed/sed-4.1.5-copy.patch

224 lines
6.9 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff -Burp sed-4.1.5/doc/sed.1 sed-4.1.5-f+c/doc/sed.1
--- sed-4.1.5/doc/sed.1 2006-02-03 10:27:35.000000000 +0100
+++ sed-4.1.5-f+c/doc/sed.1 2006-12-08 16:42:59.000000000 +0100
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.28.
-.TH SED "1" "February 2006" "sed version 4.1.4" "User Commands"
+.TH SED "1" "June 2006" "sed version 4.1.5" "User Commands"
.SH NAME
sed \- stream editor for filtering and transforming text
.SH SYNOPSIS
@@ -36,6 +36,11 @@ add the contents of script-file to the c
.IP
edit files in place (makes backup if extension supplied)
.HP
+\fB\-c\fR, \fB\-\-copy\fR
+.IP
+use copy instead of rename when shuffling files in \fB\-i\fR mode
+(avoids change of input file ownership)
+.HP
\fB\-l\fR N, \fB\-\-line\-length\fR=\fIN\fR
.IP
specify the desired line-wrap length for the `l' command
diff -Burp sed-4.1.5/lib/utils.c sed-4.1.5-f+c/lib/utils.c
--- sed-4.1.5/lib/utils.c 2006-12-08 16:41:41.000000000 +0100
+++ sed-4.1.5-f+c/lib/utils.c 2006-12-08 16:42:59.000000000 +0100
@@ -405,6 +406,55 @@ _unlink_if_fail (rd, unlink_if_fail)
return rd != -1;
}
+/* Copy contents between files. */
+static int
+_copy (from, to)
+ const char *from, *to;
+{
+ static size_t bufsize = 1024;
+ FILE *infile, *outfile;
+ int retval = 0;
+ char * buf;
+
+ errno = 0;
+
+ infile = fopen (from, "r");
+ if (infile == NULL)
+ return -1;
+
+ outfile = fopen (to, "w");
+ if (outfile == NULL)
+ {
+ fclose (infile);
+ return -1;
+ }
+
+ buf = alloca (bufsize);
+ while (1)
+ {
+ size_t bytes_in = fread (buf, 1, bufsize, infile);
+ size_t bytes_out;
+ if (bytes_in == 0)
+ {
+ if (ferror (infile))
+ retval = -1;
+ break;
+ }
+
+ bytes_out = fwrite (buf, 1, bytes_in, outfile);
+ if (bytes_out != bytes_in)
+ {
+ retval = -1;
+ break;
+ }
+ }
+
+ fclose (outfile);
+ fclose (infile);
+
+ return retval;
+}
+
/* Panic on failing rename */
void
ck_rename (from, to, unlink_if_fail)
@@ -415,6 +465,26 @@ ck_rename (from, to, unlink_if_fail)
panic (_("cannot rename %s: %s"), from, strerror (errno));
}
+/* Attempt to copy file contents between the files. */
+void
+ck_fcmove (from, to, unlink_if_fail)
+ const char *from, *to;
+ const char *unlink_if_fail;
+{
+ if (!_unlink_if_fail (_copy (from, to), unlink_if_fail))
+ panic (_("cannot copy %s to %s: %s"), from, to, strerror (errno));
+}
+
+/* Copy contents between files, and then unlink the source. */
+void
+ck_fcopy (from, to, unlink_if_fail)
+ const char *from, *to;
+ const char *unlink_if_fail;
+{
+ ck_fcmove (from, to, unlink_if_fail);
+ ck_unlink (from);
+}
+
/* Panic on failing malloc */
diff -Burp sed-4.1.5/lib/utils.h sed-4.1.5-f+c/lib/utils.h
--- sed-4.1.5/lib/utils.h 2006-12-08 16:41:41.000000000 +0100
+++ sed-4.1.5-f+c/lib/utils.h 2006-12-08 16:42:59.000000000 +0100
@@ -31,6 +31,8 @@ size_t ck_getline P_((char **text, size_
FILE * ck_mkstemp P_((char **p_filename, char *tmpdir, char *base));
const char* ck_follow_symlink P_((const char * fname));
void ck_rename P_((const char *from, const char *to, const char *unlink_if_fail));
+void ck_fcopy P_((const char *from, const char *to, const char *unlink_if_fail));
+void ck_fcmove P_((const char *from, const char *to, const char *unlink_if_fail));
VOID *ck_malloc P_((size_t size));
VOID *xmalloc P_((size_t size));
diff -Burp sed-4.1.5/sed/execute.c sed-4.1.5-f+c/sed/execute.c
--- sed-4.1.5/sed/execute.c 2006-12-08 16:41:41.000000000 +0100
+++ sed-4.1.5-f+c/sed/execute.c 2006-12-08 16:42:59.000000000 +0100
@@ -716,12 +716,14 @@ closedown(input)
ck_fclose (output_file.fp);
if (strcmp(in_place_extension, "*") != 0)
{
- char *backup_file_name = get_backup_file_name(target_name);
- ck_rename (target_name, backup_file_name, input->out_file_name);
+ char *backup_file_name = get_backup_file_name(target_name);
+ (copy_instead_of_rename?ck_fcmove:ck_rename)
+ (target_name, backup_file_name, input->out_file_name);
free (backup_file_name);
}
- ck_rename (input->out_file_name, target_name, input->out_file_name);
+ (copy_instead_of_rename?ck_fcopy:ck_rename)
+ (input->out_file_name, target_name, input->out_file_name);
free (input->out_file_name);
free (target_name);
}
diff -Burp sed-4.1.5/sed/sed.c sed-4.1.5-f+c/sed/sed.c
--- sed-4.1.5/sed/sed.c 2005-06-21 16:09:47.000000000 +0200
+++ sed-4.1.5-f+c/sed/sed.c 2006-12-08 16:42:59.000000000 +0100
@@ -73,6 +73,10 @@ bool separate_files = false;
/* How do we edit files in-place? (we don't if NULL) */
char *in_place_extension = NULL;
+/* Do we use copy or rename when in in-place edit mode? (boolean
+ value, non-zero for copy, zero for rename).*/
+int copy_instead_of_rename = 0;
+
/* Do we need to be pedantically POSIX compliant? */
enum posixicity_types posixicity;
@@ -107,6 +111,9 @@ Usage: %s [OPTION]... {script-only-if-no
add the contents of script-file to the commands to be executed\n"));
fprintf(out, _(" -i[SUFFIX], --in-place[=SUFFIX]\n\
edit files in place (makes backup if extension supplied)\n"));
+ fprintf(out, _(" -c, --copy\n\
+ use copy instead of rename when shuffling files in -i mode\n\
+ (avoids change of input file ownership)\n"));
fprintf(out, _(" -l N, --line-length=N\n\
specify the desired line-wrap length for the `l' command\n"));
fprintf(out, _(" --posix\n\
@@ -142,9 +149,9 @@ main(argc, argv)
char **argv;
{
#ifdef REG_PERL
-#define SHORTOPTS "snrRue:f:l:i::V:"
+#define SHORTOPTS "csnrRue:f:l:i::V:"
#else
-#define SHORTOPTS "snrue:f:l:i::V:"
+#define SHORTOPTS "csnrue:f:l:i::V:"
#endif
static struct option longopts[] = {
@@ -155,6 +162,7 @@ main(argc, argv)
{"expression", 1, NULL, 'e'},
{"file", 1, NULL, 'f'},
{"in-place", 2, NULL, 'i'},
+ {"copy", 0, NULL, 'c'},
{"line-length", 1, NULL, 'l'},
{"quiet", 0, NULL, 'n'},
{"posix", 0, NULL, 'p'},
@@ -215,6 +223,10 @@ main(argc, argv)
the_program = compile_file(the_program, optarg);
break;
+ case 'c':
+ copy_instead_of_rename = true;
+ break;
+
case 'i':
separate_files = true;
if (optarg == NULL)
@@ -284,6 +296,12 @@ to the extent permitted by law.\n\
}
}
+ if (copy_instead_of_rename && in_place_extension == NULL)
+ {
+ fprintf (stderr, _("Error: -c used without -i.\n"));
+ usage(4);
+ }
+
if (!the_program)
{
if (optind < argc)
diff -Burp sed-4.1.5/sed/sed.h sed-4.1.5-f+c/sed/sed.h
--- sed-4.1.5/sed/sed.h 2006-12-08 16:41:41.000000000 +0100
+++ sed-4.1.5-f+c/sed/sed.h 2006-12-08 16:42:59.000000000 +0100
@@ -228,6 +228,10 @@ extern countT lcmd_out_line_len;
/* How do we edit files in-place? (we don't if NULL) */
extern char *in_place_extension;
+/* Do we use copy or rename when in in-place edit mode? (boolean
+ value, non-zero for copy, zero for rename).*/
+extern int copy_instead_of_rename;
+
/* Should we use EREs? */
extern bool use_extended_syntax_p;