# HG changeset patch # User Bram Moolenaar # Date 1683840604 -7200 # Node ID c0b3e3c7786ce3275899e5a6a570aa25fd788fc8 # Parent 620f8739968720d86b0ad5ee37d00f4e75569e08 patch 9.0.1544: recent glibc marks sigset() as a deprecated Commit: https://github.com/vim/vim/commit/378447fc183b589039a5bf257923a86d439b0a91 Author: ichizok Date: Thu May 11 22:25:42 2023 +0100 patch 9.0.1544: recent glibc marks sigset() as a deprecated Problem: Recent glibc marks sigset() as a deprecated. Solution: Use sigaction() in mch_signal() if possible. (Ozaki Kiichi, closes #12373) diff --git a/src/gui_haiku.cc b/src/gui_haiku.cc --- a/src/gui_haiku.cc +++ b/src/gui_haiku.cc @@ -785,8 +785,8 @@ VimApp::ReadyToRun() * Apparently signals are inherited by the created thread - * disable the most annoying ones. */ - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); + mch_signal(SIGINT, SIG_IGN); + mch_signal(SIGQUIT, SIG_IGN); } void @@ -1067,8 +1067,8 @@ VimFormView::AllAttached() * Apparently signals are inherited by the created thread - * disable the most annoying ones. */ - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); + mch_signal(SIGINT, SIG_IGN); + mch_signal(SIGQUIT, SIG_IGN); if (menuBar && textArea) { /* diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c @@ -1557,7 +1557,7 @@ getout_preserve_modified(int exitval) // Ignore SIGHUP, because a dropped connection causes a read error, which // makes Vim exit and then handling SIGHUP causes various reentrance // problems. - signal(SIGHUP, SIG_IGN); + mch_signal(SIGHUP, SIG_IGN); # endif ml_close_notmod(); // close all not-modified buffers diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -2208,7 +2208,7 @@ prepare_to_exit(void) // Ignore SIGHUP, because a dropped connection causes a read error, which // makes Vim exit and then handling SIGHUP causes various reentrance // problems. - signal(SIGHUP, SIG_IGN); + mch_signal(SIGHUP, SIG_IGN); #endif #ifdef FEAT_GUI diff --git a/src/os_unix.c b/src/os_unix.c --- a/src/os_unix.c +++ b/src/os_unix.c @@ -214,7 +214,10 @@ static int have_dollars(int, char_u **) static int save_patterns(int num_pat, char_u **pat, int *num_file, char_u ***file); #ifndef SIG_ERR -# define SIG_ERR ((void (*)())-1) +# define SIG_ERR ((sighandler_T)-1) +#endif +#ifndef SIG_HOLD +# define SIG_HOLD ((sighandler_T)-2) #endif // volatile because it is used in signal handler sig_winch(). @@ -340,6 +343,62 @@ static struct signalinfo {-1, "Unknown!", FALSE} }; + sighandler_T +mch_signal(int sig, sighandler_T func) +{ +#if defined(HAVE_SIGACTION) && defined(HAVE_SIGPROCMASK) + // Modern implementation: use sigaction(). + struct sigaction sa, old; + sigset_t curset; + int blocked; + + if (sigprocmask(SIG_BLOCK, NULL, &curset) == -1) + return SIG_ERR; + + blocked = sigismember(&curset, sig); + + if (func == SIG_HOLD) + { + if (blocked) + return SIG_HOLD; + + sigemptyset(&curset); + sigaddset(&curset, sig); + + if (sigaction(sig, NULL, &old) == -1 + || sigprocmask(SIG_BLOCK, &curset, NULL) == -1) + return SIG_ERR; + return old.sa_handler; + } + + if (blocked) + { + sigemptyset(&curset); + sigaddset(&curset, sig); + + if (sigprocmask(SIG_UNBLOCK, &curset, NULL) == -1) + return SIG_ERR; + } + + sa.sa_handler = func; + sigemptyset(&sa.sa_mask); +# ifdef SA_RESTART + sa.sa_flags = SA_RESTART; +# else + sa.sa_flags = 0; +# endif + if (sigaction(sig, &sa, &old) == -1) + return SIG_ERR; + return blocked ? SIG_HOLD: old.sa_handler; +#elif defined(HAVE_SIGSET) + // Using sigset() is preferred above signal(). + return sigset(sig, func); +#else + // Oldest and most compatible solution. + return signal(sig, func); +#endif +} + int mch_chdir(char *path) { @@ -349,11 +408,11 @@ mch_chdir(char *path) smsg("chdir(%s)", path); verbose_leave(); } -# ifdef VMS +#ifdef VMS return chdir(vms_fixfilename(path)); -# else +#else return chdir(path); -# endif +#endif } // Why is NeXT excluded here (and not in os_unixx.h)? @@ -869,7 +928,7 @@ init_signal_stack(void) sig_winch SIGDEFARG(sigarg) { // this is not required on all systems, but it doesn't hurt anybody - signal(SIGWINCH, (void (*)(int))sig_winch); + mch_signal(SIGWINCH, sig_winch); do_resize = TRUE; } #endif @@ -881,7 +940,7 @@ sig_tstp SIGDEFARG(sigarg) // Second time we get called we actually need to suspend if (in_mch_suspend) { - signal(SIGTSTP, ignore_sigtstp ? SIG_IGN : SIG_DFL); + mch_signal(SIGTSTP, ignore_sigtstp ? SIG_IGN : SIG_DFL); raise(sigarg); } else @@ -890,7 +949,7 @@ sig_tstp SIGDEFARG(sigarg) #if !defined(__ANDROID__) && !defined(__OpenBSD__) && !defined(__DragonFly__) // This is not required on all systems. On some systems (at least Android, // OpenBSD, and DragonFlyBSD) this breaks suspending with CTRL-Z. - signal(SIGTSTP, (void (*)(int))sig_tstp); + mch_signal(SIGTSTP, sig_tstp); #endif } #endif @@ -900,7 +959,7 @@ sig_tstp SIGDEFARG(sigarg) catch_sigint SIGDEFARG(sigarg) { // this is not required on all systems, but it doesn't hurt anybody - signal(SIGINT, (void (*)(int))catch_sigint); + mch_signal(SIGINT, catch_sigint); got_int = TRUE; } #endif @@ -910,7 +969,7 @@ catch_sigint SIGDEFARG(sigarg) catch_sigusr1 SIGDEFARG(sigarg) { // this is not required on all systems, but it doesn't hurt anybody - signal(SIGUSR1, (void (*)(int))catch_sigusr1); + mch_signal(SIGUSR1, catch_sigusr1); got_sigusr1 = TRUE; } #endif @@ -920,7 +979,7 @@ catch_sigusr1 SIGDEFARG(sigarg) catch_sigpwr SIGDEFARG(sigarg) { // this is not required on all systems, but it doesn't hurt anybody - signal(SIGPWR, (void (*)())catch_sigpwr); + mch_signal(SIGPWR, catch_sigpwr); /* * I'm not sure we get the SIGPWR signal when the system is really going * down or when the batteries are almost empty. Just preserve the swap @@ -1364,7 +1423,7 @@ mch_init(void) // that indicates the shell (or program) that launched us does not support // tty job control and thus we should ignore that signal. If invoked as a // restricted editor (e.g., as "rvim") SIGTSTP is always ignored. - ignore_sigtstp = restricted || SIG_IGN == signal(SIGTSTP, SIG_ERR); + ignore_sigtstp = restricted || SIG_IGN == mch_signal(SIGTSTP, SIG_ERR); #endif set_signals(); @@ -1383,7 +1442,7 @@ set_signals(void) /* * WINDOW CHANGE signal is handled with sig_winch(). */ - signal(SIGWINCH, (void (*)(int))sig_winch); + mch_signal(SIGWINCH, sig_winch); #endif #ifdef SIGTSTP @@ -1391,20 +1450,20 @@ set_signals(void) // In the GUI default TSTP processing is OK. // Checking both gui.in_use and gui.starting because gui.in_use is not set // at this point (set after menus are displayed), but gui.starting is set. - signal(SIGTSTP, ignore_sigtstp ? SIG_IGN + mch_signal(SIGTSTP, ignore_sigtstp ? SIG_IGN # ifdef FEAT_GUI : gui.in_use || gui.starting ? SIG_DFL # endif - : (void (*)(int))sig_tstp); + : sig_tstp); #endif #if defined(SIGCONT) - signal(SIGCONT, sigcont_handler); + mch_signal(SIGCONT, sigcont_handler); #endif #ifdef SIGPIPE /* * We want to ignore breaking of PIPEs. */ - signal(SIGPIPE, SIG_IGN); + mch_signal(SIGPIPE, SIG_IGN); #endif #ifdef SIGINT @@ -1415,14 +1474,14 @@ set_signals(void) /* * Call user's handler on SIGUSR1 */ - signal(SIGUSR1, (void (*)(int))catch_sigusr1); + mch_signal(SIGUSR1, catch_sigusr1); #endif /* * Ignore alarm signals (Perl's alarm() generates it). */ #ifdef SIGALRM - signal(SIGALRM, SIG_IGN); + mch_signal(SIGALRM, SIG_IGN); #endif #ifdef SIGPWR @@ -1430,7 +1489,7 @@ set_signals(void) * Catch SIGPWR (power failure?) to preserve the swap files, so that no * work will be lost. */ - signal(SIGPWR, (void (*)())catch_sigpwr); + mch_signal(SIGPWR, catch_sigpwr); #endif /* @@ -1443,7 +1502,7 @@ set_signals(void) * When the GUI is running, ignore the hangup signal. */ if (gui.in_use) - signal(SIGHUP, SIG_IGN); + mch_signal(SIGHUP, SIG_IGN); #endif } @@ -1454,7 +1513,7 @@ set_signals(void) static void catch_int_signal(void) { - signal(SIGINT, (void (*)(int))catch_sigint); + mch_signal(SIGINT, catch_sigint); } #endif @@ -1464,7 +1523,7 @@ reset_signals(void) catch_signals(SIG_DFL, SIG_DFL); #if defined(SIGCONT) // SIGCONT isn't in the list, because its default action is ignore - signal(SIGCONT, SIG_DFL); + mch_signal(SIGCONT, SIG_DFL); #endif } @@ -1506,7 +1565,7 @@ catch_signals( sv.sv_flags = SV_ONSTACK; sigvec(signal_info[i].sig, &sv, NULL); # else - signal(signal_info[i].sig, func_deadly); + mch_signal(signal_info[i].sig, func_deadly); # endif #endif } @@ -1514,11 +1573,11 @@ catch_signals( { // Deal with non-deadly signals. #ifdef SIGTSTP - signal(signal_info[i].sig, + mch_signal(signal_info[i].sig, signal_info[i].sig == SIGTSTP && ignore_sigtstp ? SIG_IGN : func_other); #else - signal(signal_info[i].sig, func_other); + mch_signal(signal_info[i].sig, func_other); #endif } } @@ -1923,7 +1982,7 @@ get_x11_windis(void) if (x11_window != 0 && x11_display == NULL) { #ifdef SET_SIG_ALARM - void (*sig_save)(); + sighandler_T sig_save; #endif #ifdef ELAPSED_FUNC elapsed_T start_tv; @@ -1938,14 +1997,14 @@ get_x11_windis(void) * the network connection is bad. Set an alarm timer to get out. */ sig_alarm_called = FALSE; - sig_save = (void (*)())signal(SIGALRM, (void (*)())sig_alarm); + sig_save = mch_signal(SIGALRM, sig_alarm); alarm(2); #endif x11_display = XOpenDisplay(NULL); #ifdef SET_SIG_ALARM alarm(0); - signal(SIGALRM, (void (*)())sig_save); + mch_signal(SIGALRM, sig_save); if (p_verbose > 0 && sig_alarm_called) verb_msg(_("Opening the X display timed out")); #endif @@ -3519,7 +3578,7 @@ may_core_dump(void) { if (deadly_signal != 0) { - signal(deadly_signal, SIG_DFL); + mch_signal(deadly_signal, SIG_DFL); kill(getpid(), deadly_signal); // Die using the signal we caught } } @@ -4828,7 +4887,7 @@ mch_call_shell_fork( // will exit and send SIGHUP to all processes in its // group, killing the just started process. Ignore SIGHUP // to avoid that. (suggested by Simon Schubert) - signal(SIGHUP, SIG_IGN); + mch_signal(SIGHUP, SIG_IGN); # endif } # endif @@ -7283,7 +7342,7 @@ gpm_open(void) // we are going to suspend or starting an external process // so we shouldn't have problem with this # ifdef SIGTSTP - signal(SIGTSTP, restricted ? SIG_IGN : (void (*)())sig_tstp); + mch_signal(SIGTSTP, restricted ? SIG_IGN : sig_tstp); # endif return 1; // succeed } @@ -7415,7 +7474,7 @@ sysmouse_open(void) if (ioctl(1, CONS_MOUSECTL, &mouse) == -1) return FAIL; - signal(SIGUSR2, (void (*)())sig_sysmouse); + mch_signal(SIGUSR2, sig_sysmouse); mouse.operation = MOUSE_SHOW; ioctl(1, CONS_MOUSECTL, &mouse); return OK; @@ -7430,7 +7489,7 @@ sysmouse_close(void) { struct mouse_info mouse; - signal(SIGUSR2, restricted ? SIG_IGN : SIG_DFL); + mch_signal(SIGUSR2, restricted ? SIG_IGN : SIG_DFL); mouse.operation = MOUSE_MODE; mouse.u.mode.mode = 0; mouse.u.mode.signal = 0; diff --git a/src/os_unix.h b/src/os_unix.h --- a/src/os_unix.h +++ b/src/os_unix.h @@ -98,6 +98,8 @@ # define SIGDUMMYARG #endif +typedef void (*sighandler_T) SIGPROTOARG; + #ifdef HAVE_DIRENT_H # include # ifndef NAMLEN diff --git a/src/os_unixx.h b/src/os_unixx.h --- a/src/os_unixx.h +++ b/src/os_unixx.h @@ -10,14 +10,7 @@ * os_unixx.h -- include files that are only used in os_unix.c */ -/* - * Stuff for signals - */ -#if defined(HAVE_SIGSET) && !defined(signal) -# define signal sigset -#endif - - // Sun's sys/ioctl.h redefines symbols from termio world +// Sun's sys/ioctl.h redefines symbols from termio world #if defined(HAVE_SYS_IOCTL_H) && !defined(SUN_SYSTEM) # include #endif diff --git a/src/os_win32.c b/src/os_win32.c --- a/src/os_win32.c +++ b/src/os_win32.c @@ -5441,17 +5441,17 @@ mch_call_shell( * Catch all deadly signals while running the external command, because a * CTRL-C, Ctrl-Break or illegal instruction might otherwise kill us. */ - signal(SIGINT, SIG_IGN); + mch_signal(SIGINT, SIG_IGN); #if defined(__GNUC__) && !defined(__MINGW32__) - signal(SIGKILL, SIG_IGN); + mch_signal(SIGKILL, SIG_IGN); #else - signal(SIGBREAK, SIG_IGN); + mch_signal(SIGBREAK, SIG_IGN); #endif - signal(SIGILL, SIG_IGN); - signal(SIGFPE, SIG_IGN); - signal(SIGSEGV, SIG_IGN); - signal(SIGTERM, SIG_IGN); - signal(SIGABRT, SIG_IGN); + mch_signal(SIGILL, SIG_IGN); + mch_signal(SIGFPE, SIG_IGN); + mch_signal(SIGSEGV, SIG_IGN); + mch_signal(SIGTERM, SIG_IGN); + mch_signal(SIGABRT, SIG_IGN); if (options & SHELL_COOKED) settmode(TMODE_COOK); // set to normal mode @@ -5680,17 +5680,17 @@ mch_call_shell( } resettitle(); - signal(SIGINT, SIG_DFL); + mch_signal(SIGINT, SIG_DFL); #if defined(__GNUC__) && !defined(__MINGW32__) - signal(SIGKILL, SIG_DFL); + mch_signal(SIGKILL, SIG_DFL); #else - signal(SIGBREAK, SIG_DFL); + mch_signal(SIGBREAK, SIG_DFL); #endif - signal(SIGILL, SIG_DFL); - signal(SIGFPE, SIG_DFL); - signal(SIGSEGV, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGABRT, SIG_DFL); + mch_signal(SIGILL, SIG_DFL); + mch_signal(SIGFPE, SIG_DFL); + mch_signal(SIGSEGV, SIG_DFL); + mch_signal(SIGTERM, SIG_DFL); + mch_signal(SIGABRT, SIG_DFL); return x; } diff --git a/src/os_win32.h b/src/os_win32.h --- a/src/os_win32.h +++ b/src/os_win32.h @@ -95,6 +95,8 @@ # endif #endif +typedef void (*sighandler_T)(int, int); + /* * Win32 has plenty of memory, use large buffers */ diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -1,4 +1,5 @@ /* os_unix.c */ +sighandler_T mch_signal(int sig, sighandler_T func); int mch_chdir(char *path); void mch_write(char_u *s, int len); int mch_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt); diff --git a/src/pty.c b/src/pty.c --- a/src/pty.c +++ b/src/pty.c @@ -186,9 +186,9 @@ setup_slavepty(int fd) int mch_openpty(char **ttyn) { - int f; - char *m; - void (*sigcld) SIGPROTOARG; + int f; + char *m; + sighandler_T sigcld; static char TtyName[32]; // used for opening a new pty-pair if ((f = posix_openpt(O_RDWR | O_NOCTTY | O_EXTRA)) == -1) @@ -196,14 +196,14 @@ mch_openpty(char **ttyn) // SIGCHLD set to SIG_DFL for grantpt() because it fork()s and // exec()s pt_chmod - sigcld = signal(SIGCHLD, SIG_DFL); + sigcld = mch_signal(SIGCHLD, SIG_DFL); if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f)) { - signal(SIGCHLD, sigcld); + mch_signal(SIGCHLD, sigcld); close(f); return -1; } - signal(SIGCHLD, sigcld); + mch_signal(SIGCHLD, sigcld); vim_strncpy((char_u *)TtyName, (char_u *)m, sizeof(TtyName) - 1); initmaster(f); *ttyn = TtyName; @@ -285,9 +285,9 @@ mch_openpty(char **ttyn) int mch_openpty(char **ttyn) { - int f; - char *m; - void (*sigcld) SIGPROTOARG; + int f; + char *m; + sighandler_T sigcld; // used for opening a new pty-pair: static char TtyName[32]; @@ -298,14 +298,14 @@ mch_openpty(char **ttyn) * SIGCHLD set to SIG_DFL for grantpt() because it fork()s and * exec()s pt_chmod */ - sigcld = signal(SIGCHLD, SIG_DFL); + sigcld = mch_signal(SIGCHLD, SIG_DFL); if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f)) { - signal(SIGCHLD, sigcld); + mch_signal(SIGCHLD, sigcld); close(f); return -1; } - signal(SIGCHLD, sigcld); + mch_signal(SIGCHLD, sigcld); vim_strncpy((char_u *)TtyName, (char_u *)m, sizeof(TtyName) - 1); initmaster(f); *ttyn = TtyName; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1544, +/**/ 1543, /**/ 1542, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -242,6 +242,9 @@ #if (defined(UNIX) || defined(VMS)) \ && (!defined(MACOS_X) || defined(HAVE_CONFIG_H)) # include "os_unix.h" // bring lots of system header files +#else + // For all non-Unix systems: use old-fashioned signal(). +# define mch_signal(signum, sighandler) signal(signum, sighandler) #endif // Mark unused function arguments with UNUSED, so that gcc -Wunused-parameter