backport upstream patch
1.maint-avoid-new-warning-about-deprecated-security_co.patch 2.maint-update-obsolete-constructs-in-configure.ac.patch 3.sed-avoid-potential-double-fclose.patch 4.sed-fix-temp-file-cleanup.patch 5.adapt sed-c-flag.patch Signed-off-by: laotan2 <tanjinghui1@huawei.com> (cherry picked from commit 805226fb095690044748f410acf3df9778c94069)
This commit is contained in:
parent
e478270972
commit
3bf271807e
@ -0,0 +1,37 @@
|
|||||||
|
From 9cfcd061737955b7732585bbd5e4bf2c934dd52f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jim Meyering <meyering@fb.com>
|
||||||
|
Date: Sat, 10 Jul 2021 12:55:38 -0700
|
||||||
|
Subject: [PATCH 08/44] maint: avoid new warning about deprecated
|
||||||
|
security_context_t
|
||||||
|
|
||||||
|
* sed/execute.c (open_next_file): Use char * in place of
|
||||||
|
deprecated security_context_t.
|
||||||
|
---
|
||||||
|
sed/execute.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sed/execute.c b/sed/execute.c
|
||||||
|
index 10b7296..4862e52 100644
|
||||||
|
--- a/sed/execute.c
|
||||||
|
+++ b/sed/execute.c
|
||||||
|
@@ -572,7 +572,7 @@ open_next_file (const char *name, struct input *input)
|
||||||
|
{
|
||||||
|
int input_fd;
|
||||||
|
char *tmpdir, *p;
|
||||||
|
- security_context_t old_fscreatecon;
|
||||||
|
+ char *old_fscreatecon;
|
||||||
|
int reset_fscreatecon = 0;
|
||||||
|
memset (&old_fscreatecon, 0, sizeof (old_fscreatecon));
|
||||||
|
|
||||||
|
@@ -593,7 +593,7 @@ open_next_file (const char *name, struct input *input)
|
||||||
|
|
||||||
|
if (is_selinux_enabled () > 0)
|
||||||
|
{
|
||||||
|
- security_context_t con;
|
||||||
|
+ char *con;
|
||||||
|
if (lgetfilecon (input->in_file_name, &con) != -1)
|
||||||
|
{
|
||||||
|
/* Save and restore the old context for the sake of w and W
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
From f3239cca6ef6ed5f48e92cbc5f6525097a633779 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jim Meyering <meyering@fb.com>
|
||||||
|
Date: Sat, 10 Jul 2021 13:28:30 -0700
|
||||||
|
Subject: [PATCH 09/44] maint: update obsolete constructs in configure.ac
|
||||||
|
|
||||||
|
* configure.ac: Avoid autoconf warnings:
|
||||||
|
Switch from obsolete AM_CONFIG_HEADER to AC_CONFIG_HEADERS, and quote.
|
||||||
|
Use AC_PROG_CC_STDC, not AC_PROG_CC.
|
||||||
|
Convert from obsolete AC_TRY_RUN to AC_RUN_IFELSE.
|
||||||
|
---
|
||||||
|
configure.ac | 19 +++++++++++--------
|
||||||
|
1 file changed, 11 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index 4c701c1..8fc927f 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -19,14 +19,14 @@ AC_INIT([GNU sed],
|
||||||
|
[bug-sed@gnu.org])
|
||||||
|
AC_CONFIG_AUX_DIR(build-aux)
|
||||||
|
AC_CONFIG_SRCDIR([sed/sed.c])
|
||||||
|
-AM_CONFIG_HEADER(config.h:config_h.in)
|
||||||
|
+AC_CONFIG_HEADERS([config.h:config_h.in])
|
||||||
|
AC_PREREQ([2.64])
|
||||||
|
AM_INIT_AUTOMAKE([1.11.1 dist-xz color-tests parallel-tests
|
||||||
|
subdir-objects])
|
||||||
|
AM_SILENT_RULES([yes]) # make --enable-silent-rules the default.
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
|
-AC_PROG_CC_STDC
|
||||||
|
+AC_PROG_CC
|
||||||
|
AM_PROG_CC_C_O
|
||||||
|
gl_EARLY
|
||||||
|
gl_INIT
|
||||||
|
@@ -62,7 +62,8 @@ AC_DEFUN([gl_GCC_VERSION_IFELSE],
|
||||||
|
)
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether "rt" can be used with fopen], [sed_cv_fopen_rt], [
|
||||||
|
-AC_TRY_RUN([
|
||||||
|
+AC_RUN_IFELSE(
|
||||||
|
+ [AC_LANG_SOURCE([[
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
@@ -74,7 +75,7 @@ int main()
|
||||||
|
fp = fopen ("conftest.c", "rt");
|
||||||
|
if (fp) fclose (fp);
|
||||||
|
return fp ? 0 : 1;
|
||||||
|
-}], [sed_cv_fopen_rt=yes],
|
||||||
|
+}]])], [sed_cv_fopen_rt=yes],
|
||||||
|
[sed_cv_fopen_rt=no],
|
||||||
|
[case $host in
|
||||||
|
*cygwin* | *mingw*) sed_cv_fopen_rt=yes ;;
|
||||||
|
@@ -86,7 +87,8 @@ if test "$sed_cv_fopen_rt" = yes; then
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether -lcP is needed], [sed_cv_libcp_needed], [
|
||||||
|
-AC_TRY_RUN([
|
||||||
|
+AC_RUN_IFELSE(
|
||||||
|
+ [AC_LANG_SOURCE([[
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
@@ -100,7 +102,7 @@ int main()
|
||||||
|
result = fflush (fp) == EOF && errno == 0;
|
||||||
|
fclose (fp);
|
||||||
|
return result;
|
||||||
|
-}], [sed_cv_libcp_needed=no],
|
||||||
|
+}]])], [sed_cv_libcp_needed=no],
|
||||||
|
[sed_cv_libcp_needed=yes],
|
||||||
|
[sed_cv_libcp_needed="assuming no"])
|
||||||
|
])
|
||||||
|
@@ -143,7 +145,8 @@ fi
|
||||||
|
# have a couple of platforms where these tests pass. Right now, only
|
||||||
|
# Windows and HP/UX do not support the tests.
|
||||||
|
AC_MSG_CHECKING([whether UTF-8 case folding tests should pass])
|
||||||
|
-AC_TRY_RUN([
|
||||||
|
+AC_RUN_IFELSE(
|
||||||
|
+ [AC_LANG_SOURCE([[
|
||||||
|
#include <locale.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
@@ -204,7 +207,7 @@ int main()
|
||||||
|
setlocale (LC_CTYPE, old);
|
||||||
|
exit (!test ());
|
||||||
|
}
|
||||||
|
-], [AC_MSG_RESULT([yes]); XFAIL_TESTS=],
|
||||||
|
+]])], [AC_MSG_RESULT([yes]); XFAIL_TESTS=],
|
||||||
|
[AC_MSG_RESULT([no]); XFAIL_TESTS='testsuite/utf8-1 testsuite/utf8-2 \
|
||||||
|
testsuite/utf8-3 testsuite/utf8-4'],
|
||||||
|
[AC_MSG_RESULT([don't care (cross compiling)]); XFAIL_TESTS=])
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
87
backport-sed-avoid-potential-double-fclose.patch
Normal file
87
backport-sed-avoid-potential-double-fclose.patch
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
From 6568d364f4d21df69027319f55bcc903bfb32e0a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jim Meyering <meyering@fb.com>
|
||||||
|
Date: Sat, 10 Jul 2021 17:34:39 -0700
|
||||||
|
Subject: [PATCH 10/44] sed: avoid potential double-fclose
|
||||||
|
|
||||||
|
Upon a failed temp file fclose, do_ck_fclose would call panic,
|
||||||
|
which would then attempt to fclose and unlink that same pointer.
|
||||||
|
Caught by gcc's new -Wanalyzer-double-fclose.
|
||||||
|
* sed/utils.c (struct open_file) [fclose_failed]: New member.
|
||||||
|
(panic): Don't double-close.
|
||||||
|
(register_open_file): Clear new member.
|
||||||
|
(mark_as_fclose_failed): Use new member to avoid double fclose.
|
||||||
|
(do_ck_fclose): Call mark_as_fclose_failed upon fclose failure.
|
||||||
|
---
|
||||||
|
sed/utils.c | 28 ++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 26 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sed/utils.c b/sed/utils.c
|
||||||
|
index 699fd85..98b6333 100644
|
||||||
|
--- a/sed/utils.c
|
||||||
|
+++ b/sed/utils.c
|
||||||
|
@@ -47,6 +47,7 @@ struct open_file
|
||||||
|
char *name;
|
||||||
|
struct open_file *link;
|
||||||
|
unsigned temp : 1;
|
||||||
|
+ unsigned fclose_failed : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct open_file *open_files = NULL;
|
||||||
|
@@ -70,7 +71,8 @@ panic (const char *str, ...)
|
||||||
|
{
|
||||||
|
if (open_files->temp)
|
||||||
|
{
|
||||||
|
- fclose (open_files->fp);
|
||||||
|
+ if (!open_files->fclose_failed)
|
||||||
|
+ fclose (open_files->fp);
|
||||||
|
errno = 0;
|
||||||
|
unlink (open_files->name);
|
||||||
|
if (errno != 0)
|
||||||
|
@@ -131,6 +133,7 @@ register_open_file (FILE *fp, const char *name)
|
||||||
|
p->name = xstrdup (name);
|
||||||
|
p->fp = fp;
|
||||||
|
p->temp = false;
|
||||||
|
+ p->fclose_failed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Panic on failing fopen */
|
||||||
|
@@ -252,6 +255,21 @@ ck_fflush (FILE *stream)
|
||||||
|
panic ("couldn't flush %s: %s", utils_fp_name (stream), strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* If we've failed to close a file in open_files whose "fp" member
|
||||||
|
+ is the same as FP, mark its entry as fclose_failed. */
|
||||||
|
+static void
|
||||||
|
+mark_as_fclose_failed (FILE *fp)
|
||||||
|
+{
|
||||||
|
+ for (struct open_file *p = open_files; p; p = p->link)
|
||||||
|
+ {
|
||||||
|
+ if (p->fp == fp)
|
||||||
|
+ {
|
||||||
|
+ p->fclose_failed = true;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Panic on failing fclose */
|
||||||
|
void
|
||||||
|
ck_fclose (FILE *stream)
|
||||||
|
@@ -293,7 +311,13 @@ do_ck_fclose (FILE *fp)
|
||||||
|
clearerr (fp);
|
||||||
|
|
||||||
|
if (fclose (fp) == EOF)
|
||||||
|
- panic ("couldn't close %s: %s", utils_fp_name (fp), strerror (errno));
|
||||||
|
+ {
|
||||||
|
+ /* Mark as already fclose-failed, so we don't attempt to fclose it
|
||||||
|
+ a second time via panic. */
|
||||||
|
+ mark_as_fclose_failed (fp);
|
||||||
|
+
|
||||||
|
+ panic ("couldn't close %s: %s", utils_fp_name (fp), strerror (errno));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Follow symlink and panic if something fails. Return the ultimate
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
@ -19,26 +19,26 @@ index c5f07cc..4e5f5b3 100644
|
|||||||
if (strcmp (in_place_extension, "*") != 0)
|
if (strcmp (in_place_extension, "*") != 0)
|
||||||
{
|
{
|
||||||
char *backup_file_name = get_backup_file_name (target_name);
|
char *backup_file_name = get_backup_file_name (target_name);
|
||||||
- ck_rename (target_name, backup_file_name, input->out_file_name);
|
- ck_rename (target_name, backup_file_name);
|
||||||
+ if (copy_instead_of_rename)
|
+ if (copy_instead_of_rename)
|
||||||
+ {
|
+ {
|
||||||
+ ck_fccopy (target_name, backup_file_name, input->out_file_name);
|
+ ck_fccopy (target_name, backup_file_name, input->out_file_name);
|
||||||
+ }
|
+ }
|
||||||
+ else
|
+ else
|
||||||
+ {
|
+ {
|
||||||
+ ck_rename (target_name, backup_file_name, input->out_file_name);
|
+ ck_rename (target_name, backup_file_name);
|
||||||
+ }
|
+ }
|
||||||
free (backup_file_name);
|
free (backup_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
- ck_rename (input->out_file_name, target_name, input->out_file_name);
|
- ck_rename (input->out_file_name, target_name);
|
||||||
+ if (copy_instead_of_rename)
|
+ if (copy_instead_of_rename)
|
||||||
+ {
|
+ {
|
||||||
+ ck_fcmove (input->out_file_name, target_name, input->out_file_name);
|
+ ck_fcmove (input->out_file_name, target_name, input->out_file_name);
|
||||||
+ }
|
+ }
|
||||||
+ else
|
+ else
|
||||||
+ {
|
+ {
|
||||||
+ ck_rename (input->out_file_name, target_name, input->out_file_name);
|
+ ck_rename (input->out_file_name, target_name);
|
||||||
+ }
|
+ }
|
||||||
cancel_cleanup ();
|
cancel_cleanup ();
|
||||||
free (input->out_file_name);
|
free (input->out_file_name);
|
||||||
@ -236,7 +236,7 @@ index 47a029e..0aba107 100644
|
|||||||
@@ -40,6 +40,8 @@ size_t ck_getdelim (char **text, size_t *buflen, char buffer_delimiter,
|
@@ -40,6 +40,8 @@ size_t ck_getdelim (char **text, size_t *buflen, char buffer_delimiter,
|
||||||
FILE * ck_mkstemp (char **p_filename, const char *tmpdir, const char *base,
|
FILE * ck_mkstemp (char **p_filename, const char *tmpdir, const char *base,
|
||||||
const char *mode) _GL_ARG_NONNULL ((1, 2, 3, 4));
|
const char *mode) _GL_ARG_NONNULL ((1, 2, 3, 4));
|
||||||
void ck_rename (const char *from, const char *to, const char *unlink_if_fail);
|
void ck_rename (const char *from, const char *to);
|
||||||
+void ck_fccopy (const char *from, const char *to, const char *unlink_if_fail);
|
+void ck_fccopy (const char *from, const char *to, const char *unlink_if_fail);
|
||||||
+void ck_fcmove (const char *from, const char *to, const char *unlink_if_fail);
|
+void ck_fcmove (const char *from, const char *to, const char *unlink_if_fail);
|
||||||
|
|
||||||
|
|||||||
434
backport-sed-fix-temp-file-cleanup.patch
Normal file
434
backport-sed-fix-temp-file-cleanup.patch
Normal file
@ -0,0 +1,434 @@
|
|||||||
|
From 1bc68cb4d5ea80c2d8f626e059a57c2280d9d663 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||||
|
Date: Sat, 2 Jul 2022 16:18:07 -0500
|
||||||
|
Subject: [PATCH 32/44] sed: fix temp file cleanup
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Without this fix, the code would sometimes use FP after calling
|
||||||
|
fclose (FP), which has undefined behavior in C.
|
||||||
|
Problem found with --enable-gcc-warnings and GCC 12.
|
||||||
|
* sed/execute.c (open_next_file): Do not register here,
|
||||||
|
as it’s too late and this can cause the file to not
|
||||||
|
be cleaned up.
|
||||||
|
* sed/sed.c (G_file_to_unlink, register_cleanup_file, cancel_cleanup):
|
||||||
|
Move from here to utils.c.
|
||||||
|
(cleanup): Call remove_cleanup_file instead of doing it by hand.
|
||||||
|
* sed/utils.c (struct open_file): Remove member temp
|
||||||
|
(which was always false) and fclose_failed (which was
|
||||||
|
not enough to prevent calling fclose with a bad pointer).
|
||||||
|
All uses changed.
|
||||||
|
(register_open_file): Do not access p->fp after it’s fclosed,
|
||||||
|
as that has undefined behavior in C.
|
||||||
|
Use xmalloc instead of xcalloc, since we initialize all members.
|
||||||
|
(G_file_to_unlink, register_cleanup_file, cancel_cleanup):
|
||||||
|
Move from utils.c to here.
|
||||||
|
(remove_cleanup_file): New function.
|
||||||
|
(ck_mkstemp): Fix a screwup when mkostemp succeeded but
|
||||||
|
set_binary_mode or fdopen failed: we might misuse a null pointer,
|
||||||
|
or forget to clean up the newly-created temp file.
|
||||||
|
(ck_getdelim): Rename local to avoid confusion with global.
|
||||||
|
(mark_as_fclose_failed): Remove. All uses removed.
|
||||||
|
(ck_fclose): Remove entry from open_files before attempting
|
||||||
|
to fclose it, so that panicking doesn’t try to fclose it again.
|
||||||
|
(do_ck_fclose): New arg NAME so that there’s no need to
|
||||||
|
call mark_as_fclose_failed, which inspected FP after fclosing
|
||||||
|
it, which is undefined behavior.
|
||||||
|
(ck_rename): Omit arg UNLINK_IF_FAIL. All callers changed.
|
||||||
|
The cleanup handler removes this file now, as needed.
|
||||||
|
---
|
||||||
|
NEWS | 3 +
|
||||||
|
sed/execute.c | 7 +--
|
||||||
|
sed/sed.c | 23 +-------
|
||||||
|
sed/sed.h | 2 -
|
||||||
|
sed/utils.c | 158 ++++++++++++++++++++------------------------------
|
||||||
|
sed/utils.h | 5 +-
|
||||||
|
6 files changed, 75 insertions(+), 123 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sed/execute.c b/sed/execute.c
|
||||||
|
index 127f67d..485bca7 100644
|
||||||
|
--- a/sed/execute.c
|
||||||
|
+++ b/sed/execute.c
|
||||||
|
@@ -104,7 +104,7 @@ struct input {
|
||||||
|
/* Have we done any replacements lately? This is used by the `t' command. */
|
||||||
|
static bool replaced = false;
|
||||||
|
|
||||||
|
-/* The current output file (stdout if -i is not being used. */
|
||||||
|
+/* The current output file (stdout if -i is not being used). */
|
||||||
|
static struct output output_file;
|
||||||
|
|
||||||
|
/* The `current' input line. */
|
||||||
|
@@ -620,7 +620,6 @@ open_next_file (const char *name, struct input *input)
|
||||||
|
|
||||||
|
output_file.fp = ck_mkstemp (&input->out_file_name, tmpdir, "sed",
|
||||||
|
write_mode);
|
||||||
|
- register_cleanup_file (input->out_file_name);
|
||||||
|
output_file.missing_newline = false;
|
||||||
|
free (tmpdir);
|
||||||
|
|
||||||
|
@@ -674,11 +673,11 @@ closedown (struct input *input)
|
||||||
|
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);
|
||||||
|
+ ck_rename (target_name, backup_file_name);
|
||||||
|
free (backup_file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
- ck_rename (input->out_file_name, target_name, input->out_file_name);
|
||||||
|
+ ck_rename (input->out_file_name, target_name);
|
||||||
|
cancel_cleanup ();
|
||||||
|
free (input->out_file_name);
|
||||||
|
}
|
||||||
|
diff --git a/sed/sed.c b/sed/sed.c
|
||||||
|
index 1678254..42c6a1f 100644
|
||||||
|
--- a/sed/sed.c
|
||||||
|
+++ b/sed/sed.c
|
||||||
|
@@ -85,12 +85,6 @@ countT lcmd_out_line_len = 70;
|
||||||
|
/* The complete compiled SED program that we are going to run: */
|
||||||
|
static struct vector *the_program = NULL;
|
||||||
|
|
||||||
|
-/* When we've created a temporary for an in-place update,
|
||||||
|
- we may have to exit before the rename. This is the name
|
||||||
|
- of the temporary that we'll have to unlink via an atexit-
|
||||||
|
- registered cleanup function. */
|
||||||
|
-static char const *G_file_to_unlink;
|
||||||
|
-
|
||||||
|
struct localeinfo localeinfo;
|
||||||
|
|
||||||
|
/* When exiting between temporary file creation and the rename
|
||||||
|
@@ -99,22 +93,7 @@ static void
|
||||||
|
cleanup (void)
|
||||||
|
{
|
||||||
|
IF_LINT (free (in_place_extension));
|
||||||
|
- if (G_file_to_unlink)
|
||||||
|
- unlink (G_file_to_unlink);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-/* Note that FILE must be removed upon exit. */
|
||||||
|
-void
|
||||||
|
-register_cleanup_file (char const *file)
|
||||||
|
-{
|
||||||
|
- G_file_to_unlink = file;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-/* Clear the global file-to-unlink global. */
|
||||||
|
-void
|
||||||
|
-cancel_cleanup (void)
|
||||||
|
-{
|
||||||
|
- G_file_to_unlink = NULL;
|
||||||
|
+ remove_cleanup_file ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
diff --git a/sed/sed.h b/sed/sed.h
|
||||||
|
index f1b0156..1c96bc5 100644
|
||||||
|
--- a/sed/sed.h
|
||||||
|
+++ b/sed/sed.h
|
||||||
|
@@ -279,8 +279,6 @@ extern bool debug;
|
||||||
|
|
||||||
|
extern int is_mb_char (int ch, mbstate_t *ps);
|
||||||
|
extern void initialize_mbcs (void);
|
||||||
|
-extern void register_cleanup_file (char const *file);
|
||||||
|
-extern void cancel_cleanup (void);
|
||||||
|
|
||||||
|
/* Use this to suppress gcc's '...may be used before initialized' warnings. */
|
||||||
|
#ifdef lint
|
||||||
|
diff --git a/sed/utils.c b/sed/utils.c
|
||||||
|
index 5765dc3..823de8d 100644
|
||||||
|
--- a/sed/utils.c
|
||||||
|
+++ b/sed/utils.c
|
||||||
|
@@ -46,12 +46,10 @@ struct open_file
|
||||||
|
FILE *fp;
|
||||||
|
char *name;
|
||||||
|
struct open_file *link;
|
||||||
|
- unsigned temp : 1;
|
||||||
|
- unsigned fclose_failed : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct open_file *open_files = NULL;
|
||||||
|
-static void do_ck_fclose (FILE *fp);
|
||||||
|
+static void do_ck_fclose (FILE *, char const *);
|
||||||
|
|
||||||
|
/* Print an error message and exit */
|
||||||
|
|
||||||
|
@@ -66,29 +64,15 @@ panic (const char *str, ...)
|
||||||
|
va_end (ap);
|
||||||
|
putc ('\n', stderr);
|
||||||
|
|
||||||
|
- /* Unlink the temporary files. */
|
||||||
|
+#ifdef lint
|
||||||
|
while (open_files)
|
||||||
|
{
|
||||||
|
- if (open_files->temp)
|
||||||
|
- {
|
||||||
|
- if (!open_files->fclose_failed)
|
||||||
|
- fclose (open_files->fp);
|
||||||
|
- errno = 0;
|
||||||
|
- unlink (open_files->name);
|
||||||
|
- if (errno != 0)
|
||||||
|
- fprintf (stderr, _("cannot remove %s: %s"), open_files->name,
|
||||||
|
- strerror (errno));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-#ifdef lint
|
||||||
|
struct open_file *next = open_files->link;
|
||||||
|
free (open_files->name);
|
||||||
|
free (open_files);
|
||||||
|
open_files = next;
|
||||||
|
-#else
|
||||||
|
- open_files = open_files->link;
|
||||||
|
-#endif
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
exit (EXIT_PANIC);
|
||||||
|
}
|
||||||
|
@@ -116,24 +100,11 @@ static void
|
||||||
|
register_open_file (FILE *fp, const char *name)
|
||||||
|
{
|
||||||
|
struct open_file *p;
|
||||||
|
- for (p=open_files; p; p=p->link)
|
||||||
|
- {
|
||||||
|
- if (fp == p->fp)
|
||||||
|
- {
|
||||||
|
- free (p->name);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if (!p)
|
||||||
|
- {
|
||||||
|
- p = XCALLOC (1, struct open_file);
|
||||||
|
- p->link = open_files;
|
||||||
|
- open_files = p;
|
||||||
|
- }
|
||||||
|
+ p = xmalloc (sizeof *p);
|
||||||
|
+ p->link = open_files;
|
||||||
|
+ open_files = p;
|
||||||
|
p->name = xstrdup (name);
|
||||||
|
p->fp = fp;
|
||||||
|
- p->temp = false;
|
||||||
|
- p->fclose_failed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Panic on failing fopen */
|
||||||
|
@@ -174,6 +145,33 @@ ck_fdopen ( int fd, const char *name, const char *mode, int fail)
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* When we've created a temporary for an in-place update,
|
||||||
|
+ we may have to exit before the rename. This is the name
|
||||||
|
+ of the temporary that we'll have to unlink via an atexit-
|
||||||
|
+ registered cleanup function. */
|
||||||
|
+static char const *G_file_to_unlink;
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+remove_cleanup_file (void)
|
||||||
|
+{
|
||||||
|
+ if (G_file_to_unlink)
|
||||||
|
+ unlink (G_file_to_unlink);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Note that FILE must be removed upon exit. */
|
||||||
|
+static void
|
||||||
|
+register_cleanup_file (char const *file)
|
||||||
|
+{
|
||||||
|
+ G_file_to_unlink = file;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Clear the global file-to-unlink global. */
|
||||||
|
+void
|
||||||
|
+cancel_cleanup (void)
|
||||||
|
+{
|
||||||
|
+ G_file_to_unlink = NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
FILE *
|
||||||
|
ck_mkstemp (char **p_filename, const char *tmpdir,
|
||||||
|
const char *base, const char *mode)
|
||||||
|
@@ -186,17 +184,28 @@ ck_mkstemp (char **p_filename, const char *tmpdir,
|
||||||
|
mkstemp forces O_BINARY on cygwin, so use mkostemp instead. */
|
||||||
|
mode_t save_umask = umask (0077);
|
||||||
|
int fd = mkostemp (template, 0);
|
||||||
|
+ int err = errno;
|
||||||
|
umask (save_umask);
|
||||||
|
- if (fd == -1)
|
||||||
|
- panic (_("couldn't open temporary file %s: %s"), template,
|
||||||
|
- strerror (errno));
|
||||||
|
+ FILE *fp = NULL;
|
||||||
|
+
|
||||||
|
+ if (0 <= fd)
|
||||||
|
+ {
|
||||||
|
+ *p_filename = template;
|
||||||
|
+ register_cleanup_file (template);
|
||||||
|
+
|
||||||
|
#if O_BINARY
|
||||||
|
- if (binary_mode && (set_binary_mode ( fd, O_BINARY) == -1))
|
||||||
|
- panic (_("failed to set binary mode on '%s'"), template);
|
||||||
|
+ if (binary_mode && set_binary_mode (fd, O_BINARY) == -1)
|
||||||
|
+ panic (_("failed to set binary mode on '%s'"), template);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- *p_filename = template;
|
||||||
|
- FILE *fp = fdopen (fd, mode);
|
||||||
|
+ fp = fdopen (fd, mode);
|
||||||
|
+ err = errno;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!fp)
|
||||||
|
+ panic (_("couldn't open temporary file %s: %s"), template,
|
||||||
|
+ strerror (err));
|
||||||
|
+
|
||||||
|
register_open_file (fp, template);
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
@@ -225,7 +234,7 @@ ck_fread (void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
-ck_getdelim (char **text, size_t *buflen, char buffer_delimiter, FILE *stream)
|
||||||
|
+ck_getdelim (char **text, size_t *buflen, char delim, FILE *stream)
|
||||||
|
{
|
||||||
|
ssize_t result;
|
||||||
|
bool error;
|
||||||
|
@@ -233,7 +242,7 @@ ck_getdelim (char **text, size_t *buflen, char buffer_delimiter, FILE *stream)
|
||||||
|
error = ferror (stream);
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
- result = getdelim (text, buflen, buffer_delimiter, stream);
|
||||||
|
+ result = getdelim (text, buflen, delim, stream);
|
||||||
|
error = ferror (stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -255,69 +264,44 @@ ck_fflush (FILE *stream)
|
||||||
|
panic ("couldn't flush %s: %s", utils_fp_name (stream), strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* If we've failed to close a file in open_files whose "fp" member
|
||||||
|
- is the same as FP, mark its entry as fclose_failed. */
|
||||||
|
-static void
|
||||||
|
-mark_as_fclose_failed (FILE *fp)
|
||||||
|
-{
|
||||||
|
- for (struct open_file *p = open_files; p; p = p->link)
|
||||||
|
- {
|
||||||
|
- if (p->fp == fp)
|
||||||
|
- {
|
||||||
|
- p->fclose_failed = true;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/* Panic on failing fclose */
|
||||||
|
void
|
||||||
|
ck_fclose (FILE *stream)
|
||||||
|
{
|
||||||
|
- struct open_file r;
|
||||||
|
- struct open_file *prev;
|
||||||
|
+ struct open_file **prev = &open_files;
|
||||||
|
struct open_file *cur;
|
||||||
|
|
||||||
|
/* a NULL stream means to close all files */
|
||||||
|
- r.link = open_files;
|
||||||
|
- prev = &r;
|
||||||
|
- while ( (cur = prev->link) )
|
||||||
|
+ while ((cur = *prev))
|
||||||
|
{
|
||||||
|
if (!stream || stream == cur->fp)
|
||||||
|
{
|
||||||
|
- do_ck_fclose (cur->fp);
|
||||||
|
- prev->link = cur->link;
|
||||||
|
+ FILE *fp = cur->fp;
|
||||||
|
+ *prev = cur->link;
|
||||||
|
+ do_ck_fclose (fp, cur->name);
|
||||||
|
free (cur->name);
|
||||||
|
free (cur);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- prev = cur;
|
||||||
|
+ prev = &cur->link;
|
||||||
|
}
|
||||||
|
|
||||||
|
- open_files = r.link;
|
||||||
|
-
|
||||||
|
/* Also care about stdout, because if it is redirected the
|
||||||
|
last output operations might fail and it is important
|
||||||
|
to signal this as an error (perhaps to make). */
|
||||||
|
if (!stream)
|
||||||
|
- do_ck_fclose (stdout);
|
||||||
|
+ do_ck_fclose (stdout, "stdout");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close a single file. */
|
||||||
|
-void
|
||||||
|
-do_ck_fclose (FILE *fp)
|
||||||
|
+static void
|
||||||
|
+do_ck_fclose (FILE *fp, char const *name)
|
||||||
|
{
|
||||||
|
ck_fflush (fp);
|
||||||
|
clearerr (fp);
|
||||||
|
|
||||||
|
if (fclose (fp) == EOF)
|
||||||
|
- {
|
||||||
|
- /* Mark as already fclose-failed, so we don't attempt to fclose it
|
||||||
|
- a second time via panic. */
|
||||||
|
- mark_as_fclose_failed (fp);
|
||||||
|
-
|
||||||
|
- panic ("couldn't close %s: %s", utils_fp_name (fp), strerror (errno));
|
||||||
|
- }
|
||||||
|
+ panic ("couldn't close %s: %s", name, strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Follow symlink and panic if something fails. Return the ultimate
|
||||||
|
@@ -401,26 +385,12 @@ follow_symlink (const char *fname)
|
||||||
|
|
||||||
|
/* Panic on failing rename */
|
||||||
|
void
|
||||||
|
-ck_rename (const char *from, const char *to, const char *unlink_if_fail)
|
||||||
|
+ck_rename (const char *from, const char *to)
|
||||||
|
{
|
||||||
|
int rd = rename (from, to);
|
||||||
|
if (rd != -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- if (unlink_if_fail)
|
||||||
|
- {
|
||||||
|
- int save_errno = errno;
|
||||||
|
- errno = 0;
|
||||||
|
- unlink (unlink_if_fail);
|
||||||
|
-
|
||||||
|
- /* Failure to remove the temporary file is more severe,
|
||||||
|
- so trigger it first. */
|
||||||
|
- if (errno != 0)
|
||||||
|
- panic (_("cannot remove %s: %s"), unlink_if_fail, strerror (errno));
|
||||||
|
-
|
||||||
|
- errno = save_errno;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
panic (_("cannot rename %s: %s"), from, strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/sed/utils.h b/sed/utils.h
|
||||||
|
index e3a8532..cac8a05 100644
|
||||||
|
--- a/sed/utils.h
|
||||||
|
+++ b/sed/utils.h
|
||||||
|
@@ -40,11 +40,14 @@ size_t ck_getdelim (char **text, size_t *buflen, char buffer_delimiter,
|
||||||
|
FILE *stream);
|
||||||
|
FILE * ck_mkstemp (char **p_filename, const char *tmpdir, const char *base,
|
||||||
|
const char *mode) _GL_ARG_NONNULL ((1, 2, 3, 4));
|
||||||
|
-void ck_rename (const char *from, const char *to, const char *unlink_if_fail);
|
||||||
|
+void ck_rename (const char *from, const char *to);
|
||||||
|
|
||||||
|
void *ck_malloc (size_t size);
|
||||||
|
void *ck_realloc (void *ptr, size_t size);
|
||||||
|
|
||||||
|
+void cancel_cleanup (void);
|
||||||
|
+void remove_cleanup_file (void);
|
||||||
|
+
|
||||||
|
struct buffer *init_buffer (void);
|
||||||
|
char *get_buffer (struct buffer const *b) _GL_ATTRIBUTE_PURE;
|
||||||
|
size_t size_buffer (struct buffer const *b) _GL_ATTRIBUTE_PURE;
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
18
sed.spec
18
sed.spec
@ -1,15 +1,19 @@
|
|||||||
Name: sed
|
Name: sed
|
||||||
Version: 4.8
|
Version: 4.8
|
||||||
Release: 3
|
Release: 4
|
||||||
Summary: non-interactive command-line text editor
|
Summary: non-interactive command-line text editor
|
||||||
|
|
||||||
License: GPLv3+
|
License: GPLv3+
|
||||||
URL: https://www.gnu.org/software/sed/
|
URL: https://www.gnu.org/software/sed/
|
||||||
Source0: http://ftp.gnu.org/gnu/sed/%{name}-%{version}.tar.xz
|
Source0: http://ftp.gnu.org/gnu/sed/%{name}-%{version}.tar.xz
|
||||||
|
|
||||||
Patch1: backport-sed-c-flag.patch
|
Patch1: backport-sed-handle-very-long-execution-lines-tiny-change.patch
|
||||||
Patch2: backport-sed-handle-very-long-execution-lines-tiny-change.patch
|
Patch2: backport-sed-handle-very-long-input-lines-with-R-tiny-change.patch
|
||||||
Patch3: backport-sed-handle-very-long-input-lines-with-R-tiny-change.patch
|
Patch3: backport-maint-avoid-new-warning-about-deprecated-security_co.patch
|
||||||
|
Patch4: backport-maint-update-obsolete-constructs-in-configure.ac.patch
|
||||||
|
Patch5: backport-sed-avoid-potential-double-fclose.patch
|
||||||
|
Patch6: backport-sed-fix-temp-file-cleanup.patch
|
||||||
|
Patch7: backport-sed-c-flag.patch
|
||||||
|
|
||||||
BuildRequires: gzip automake autoconf gcc
|
BuildRequires: gzip automake autoconf gcc
|
||||||
BuildRequires: glibc-devel libselinux-devel libacl-devel perl-Getopt-Long
|
BuildRequires: glibc-devel libselinux-devel libacl-devel perl-Getopt-Long
|
||||||
@ -51,6 +55,12 @@ make %{?_smp_mflags}
|
|||||||
%{_mandir}/man1/*.1.gz
|
%{_mandir}/man1/*.1.gz
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Oct 18 2022 laotan2<tanjinghui1@huawei.com> - 4.8-4
|
||||||
|
- Type:bugfix
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:backport upsteam patch
|
||||||
|
|
||||||
* Wed Apr 27 2022 zhangruifang2020<zhangruifang1@h-partners.com> - 4.8-3
|
* Wed Apr 27 2022 zhangruifang2020<zhangruifang1@h-partners.com> - 4.8-3
|
||||||
- Type:enhancement
|
- Type:enhancement
|
||||||
- ID:NA
|
- ID:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user