@@ -214,7 +214,10 @@ static int have_dollars(int, char_u **);
214
214
static int save_patterns (int num_pat , char_u * * pat , int * num_file , char_u * * * file );
215
215
216
216
#ifndef SIG_ERR
217
- # define SIG_ERR ((void (*)())-1)
217
+ # define SIG_ERR ((sighandler_T)-1)
218
+ #endif
219
+ #ifndef SIG_HOLD
220
+ # define SIG_HOLD ((sighandler_T)-2)
218
221
#endif
219
222
220
223
// volatile because it is used in signal handler sig_winch().
@@ -340,6 +343,62 @@ static struct signalinfo
340
343
{-1 , "Unknown!" , FALSE}
341
344
};
342
345
346
+ sighandler_T
347
+ mch_signal (int sig , sighandler_T func )
348
+ {
349
+ #if defined(HAVE_SIGACTION ) && defined(HAVE_SIGPROCMASK )
350
+ // Modern implementation: use sigaction().
351
+ struct sigaction sa , old ;
352
+ sigset_t curset ;
353
+ int blocked ;
354
+
355
+ if (sigprocmask (SIG_BLOCK , NULL , & curset ) == -1 )
356
+ return SIG_ERR ;
357
+
358
+ blocked = sigismember (& curset , sig );
359
+
360
+ if (func == SIG_HOLD )
361
+ {
362
+ if (blocked )
363
+ return SIG_HOLD ;
364
+
365
+ sigemptyset (& curset );
366
+ sigaddset (& curset , sig );
367
+
368
+ if (sigaction (sig , NULL , & old ) == -1
369
+ || sigprocmask (SIG_BLOCK , & curset , NULL ) == -1 )
370
+ return SIG_ERR ;
371
+ return old .sa_handler ;
372
+ }
373
+
374
+ if (blocked )
375
+ {
376
+ sigemptyset (& curset );
377
+ sigaddset (& curset , sig );
378
+
379
+ if (sigprocmask (SIG_UNBLOCK , & curset , NULL ) == -1 )
380
+ return SIG_ERR ;
381
+ }
382
+
383
+ sa .sa_handler = func ;
384
+ sigemptyset (& sa .sa_mask );
385
+ # ifdef SA_RESTART
386
+ sa .sa_flags = SA_RESTART ;
387
+ # else
388
+ sa .sa_flags = 0 ;
389
+ # endif
390
+ if (sigaction (sig , & sa , & old ) == -1 )
391
+ return SIG_ERR ;
392
+ return blocked ? SIG_HOLD : old .sa_handler ;
393
+ #elif defined(HAVE_SIGSET )
394
+ // Using sigset() is preferred above signal().
395
+ return sigset (sig , func );
396
+ #else
397
+ // Oldest and most compatible solution.
398
+ return signal (sig , func );
399
+ #endif
400
+ }
401
+
343
402
int
344
403
mch_chdir (char * path )
345
404
{
@@ -349,11 +408,11 @@ mch_chdir(char *path)
349
408
smsg ("chdir(%s)" , path );
350
409
verbose_leave ();
351
410
}
352
- # ifdef VMS
411
+ #ifdef VMS
353
412
return chdir (vms_fixfilename (path ));
354
- # else
413
+ #else
355
414
return chdir (path );
356
- # endif
415
+ #endif
357
416
}
358
417
359
418
// Why is NeXT excluded here (and not in os_unixx.h)?
@@ -869,7 +928,7 @@ init_signal_stack(void)
869
928
sig_winch SIGDEFARG (sigarg )
870
929
{
871
930
// this is not required on all systems, but it doesn't hurt anybody
872
- signal (SIGWINCH , ( void ( * )( int )) sig_winch );
931
+ mch_signal (SIGWINCH , sig_winch );
873
932
do_resize = TRUE;
874
933
}
875
934
#endif
@@ -881,7 +940,7 @@ sig_tstp SIGDEFARG(sigarg)
881
940
// Second time we get called we actually need to suspend
882
941
if (in_mch_suspend )
883
942
{
884
- signal (SIGTSTP , ignore_sigtstp ? SIG_IGN : SIG_DFL );
943
+ mch_signal (SIGTSTP , ignore_sigtstp ? SIG_IGN : SIG_DFL );
885
944
raise (sigarg );
886
945
}
887
946
else
@@ -890,7 +949,7 @@ sig_tstp SIGDEFARG(sigarg)
890
949
#if !defined(__ANDROID__ ) && !defined(__OpenBSD__ ) && !defined(__DragonFly__ )
891
950
// This is not required on all systems. On some systems (at least Android,
892
951
// OpenBSD, and DragonFlyBSD) this breaks suspending with CTRL-Z.
893
- signal (SIGTSTP , ( void ( * )( int )) sig_tstp );
952
+ mch_signal (SIGTSTP , sig_tstp );
894
953
#endif
895
954
}
896
955
#endif
@@ -900,7 +959,7 @@ sig_tstp SIGDEFARG(sigarg)
900
959
catch_sigint SIGDEFARG (sigarg )
901
960
{
902
961
// this is not required on all systems, but it doesn't hurt anybody
903
- signal (SIGINT , ( void ( * )( int )) catch_sigint );
962
+ mch_signal (SIGINT , catch_sigint );
904
963
got_int = TRUE;
905
964
}
906
965
#endif
@@ -910,7 +969,7 @@ catch_sigint SIGDEFARG(sigarg)
910
969
catch_sigusr1 SIGDEFARG (sigarg )
911
970
{
912
971
// this is not required on all systems, but it doesn't hurt anybody
913
- signal (SIGUSR1 , ( void ( * )( int )) catch_sigusr1 );
972
+ mch_signal (SIGUSR1 , catch_sigusr1 );
914
973
got_sigusr1 = TRUE;
915
974
}
916
975
#endif
@@ -920,7 +979,7 @@ catch_sigusr1 SIGDEFARG(sigarg)
920
979
catch_sigpwr SIGDEFARG (sigarg )
921
980
{
922
981
// this is not required on all systems, but it doesn't hurt anybody
923
- signal (SIGPWR , ( void ( * )()) catch_sigpwr );
982
+ mch_signal (SIGPWR , catch_sigpwr );
924
983
/*
925
984
* I'm not sure we get the SIGPWR signal when the system is really going
926
985
* down or when the batteries are almost empty. Just preserve the swap
@@ -1364,7 +1423,7 @@ mch_init(void)
1364
1423
// that indicates the shell (or program) that launched us does not support
1365
1424
// tty job control and thus we should ignore that signal. If invoked as a
1366
1425
// restricted editor (e.g., as "rvim") SIGTSTP is always ignored.
1367
- ignore_sigtstp = restricted || SIG_IGN == signal (SIGTSTP , SIG_ERR );
1426
+ ignore_sigtstp = restricted || SIG_IGN == mch_signal (SIGTSTP , SIG_ERR );
1368
1427
#endif
1369
1428
set_signals ();
1370
1429
@@ -1383,28 +1442,28 @@ set_signals(void)
1383
1442
/*
1384
1443
* WINDOW CHANGE signal is handled with sig_winch().
1385
1444
*/
1386
- signal (SIGWINCH , ( void ( * )( int )) sig_winch );
1445
+ mch_signal (SIGWINCH , sig_winch );
1387
1446
#endif
1388
1447
1389
1448
#ifdef SIGTSTP
1390
1449
// See mch_init() for the conditions under which we ignore SIGTSTP.
1391
1450
// In the GUI default TSTP processing is OK.
1392
1451
// Checking both gui.in_use and gui.starting because gui.in_use is not set
1393
1452
// at this point (set after menus are displayed), but gui.starting is set.
1394
- signal (SIGTSTP , ignore_sigtstp ? SIG_IGN
1453
+ mch_signal (SIGTSTP , ignore_sigtstp ? SIG_IGN
1395
1454
# ifdef FEAT_GUI
1396
1455
: gui .in_use || gui .starting ? SIG_DFL
1397
1456
# endif
1398
- : ( void ( * )( int )) sig_tstp );
1457
+ : sig_tstp );
1399
1458
#endif
1400
1459
#if defined(SIGCONT )
1401
- signal (SIGCONT , sigcont_handler );
1460
+ mch_signal (SIGCONT , sigcont_handler );
1402
1461
#endif
1403
1462
#ifdef SIGPIPE
1404
1463
/*
1405
1464
* We want to ignore breaking of PIPEs.
1406
1465
*/
1407
- signal (SIGPIPE , SIG_IGN );
1466
+ mch_signal (SIGPIPE , SIG_IGN );
1408
1467
#endif
1409
1468
1410
1469
#ifdef SIGINT
@@ -1415,22 +1474,22 @@ set_signals(void)
1415
1474
/*
1416
1475
* Call user's handler on SIGUSR1
1417
1476
*/
1418
- signal (SIGUSR1 , ( void ( * )( int )) catch_sigusr1 );
1477
+ mch_signal (SIGUSR1 , catch_sigusr1 );
1419
1478
#endif
1420
1479
1421
1480
/*
1422
1481
* Ignore alarm signals (Perl's alarm() generates it).
1423
1482
*/
1424
1483
#ifdef SIGALRM
1425
- signal (SIGALRM , SIG_IGN );
1484
+ mch_signal (SIGALRM , SIG_IGN );
1426
1485
#endif
1427
1486
1428
1487
#ifdef SIGPWR
1429
1488
/*
1430
1489
* Catch SIGPWR (power failure?) to preserve the swap files, so that no
1431
1490
* work will be lost.
1432
1491
*/
1433
- signal (SIGPWR , ( void ( * )()) catch_sigpwr );
1492
+ mch_signal (SIGPWR , catch_sigpwr );
1434
1493
#endif
1435
1494
1436
1495
/*
@@ -1443,7 +1502,7 @@ set_signals(void)
1443
1502
* When the GUI is running, ignore the hangup signal.
1444
1503
*/
1445
1504
if (gui .in_use )
1446
- signal (SIGHUP , SIG_IGN );
1505
+ mch_signal (SIGHUP , SIG_IGN );
1447
1506
#endif
1448
1507
}
1449
1508
@@ -1454,7 +1513,7 @@ set_signals(void)
1454
1513
static void
1455
1514
catch_int_signal (void )
1456
1515
{
1457
- signal (SIGINT , ( void ( * )( int )) catch_sigint );
1516
+ mch_signal (SIGINT , catch_sigint );
1458
1517
}
1459
1518
#endif
1460
1519
@@ -1464,7 +1523,7 @@ reset_signals(void)
1464
1523
catch_signals (SIG_DFL , SIG_DFL );
1465
1524
#if defined(SIGCONT )
1466
1525
// SIGCONT isn't in the list, because its default action is ignore
1467
- signal (SIGCONT , SIG_DFL );
1526
+ mch_signal (SIGCONT , SIG_DFL );
1468
1527
#endif
1469
1528
}
1470
1529
@@ -1506,19 +1565,19 @@ catch_signals(
1506
1565
sv .sv_flags = SV_ONSTACK ;
1507
1566
sigvec (signal_info [i ].sig , & sv , NULL );
1508
1567
# else
1509
- signal (signal_info [i ].sig , func_deadly );
1568
+ mch_signal (signal_info [i ].sig , func_deadly );
1510
1569
# endif
1511
1570
#endif
1512
1571
}
1513
1572
else if (func_other != SIG_ERR )
1514
1573
{
1515
1574
// Deal with non-deadly signals.
1516
1575
#ifdef SIGTSTP
1517
- signal (signal_info [i ].sig ,
1576
+ mch_signal (signal_info [i ].sig ,
1518
1577
signal_info [i ].sig == SIGTSTP && ignore_sigtstp
1519
1578
? SIG_IGN : func_other );
1520
1579
#else
1521
- signal (signal_info [i ].sig , func_other );
1580
+ mch_signal (signal_info [i ].sig , func_other );
1522
1581
#endif
1523
1582
}
1524
1583
}
@@ -1923,7 +1982,7 @@ get_x11_windis(void)
1923
1982
if (x11_window != 0 && x11_display == NULL )
1924
1983
{
1925
1984
#ifdef SET_SIG_ALARM
1926
- void ( * sig_save )() ;
1985
+ sighandler_T sig_save ;
1927
1986
#endif
1928
1987
#ifdef ELAPSED_FUNC
1929
1988
elapsed_T start_tv ;
@@ -1938,14 +1997,14 @@ get_x11_windis(void)
1938
1997
* the network connection is bad. Set an alarm timer to get out.
1939
1998
*/
1940
1999
sig_alarm_called = FALSE;
1941
- sig_save = ( void ( * )()) signal ( SIGALRM , ( void ( * )()) sig_alarm );
2000
+ sig_save = mch_signal ( SIGALRM , sig_alarm );
1942
2001
alarm (2 );
1943
2002
#endif
1944
2003
x11_display = XOpenDisplay (NULL );
1945
2004
1946
2005
#ifdef SET_SIG_ALARM
1947
2006
alarm (0 );
1948
- signal (SIGALRM , ( void ( * )()) sig_save );
2007
+ mch_signal (SIGALRM , sig_save );
1949
2008
if (p_verbose > 0 && sig_alarm_called )
1950
2009
verb_msg (_ ("Opening the X display timed out" ));
1951
2010
#endif
@@ -3519,7 +3578,7 @@ may_core_dump(void)
3519
3578
{
3520
3579
if (deadly_signal != 0 )
3521
3580
{
3522
- signal (deadly_signal , SIG_DFL );
3581
+ mch_signal (deadly_signal , SIG_DFL );
3523
3582
kill (getpid (), deadly_signal ); // Die using the signal we caught
3524
3583
}
3525
3584
}
@@ -4828,7 +4887,7 @@ mch_call_shell_fork(
4828
4887
// will exit and send SIGHUP to all processes in its
4829
4888
// group, killing the just started process. Ignore SIGHUP
4830
4889
// to avoid that. (suggested by Simon Schubert)
4831
- signal (SIGHUP , SIG_IGN );
4890
+ mch_signal (SIGHUP , SIG_IGN );
4832
4891
# endif
4833
4892
}
4834
4893
# endif
@@ -7283,7 +7342,7 @@ gpm_open(void)
7283
7342
// we are going to suspend or starting an external process
7284
7343
// so we shouldn't have problem with this
7285
7344
# ifdef SIGTSTP
7286
- signal (SIGTSTP , restricted ? SIG_IGN : ( void ( * )()) sig_tstp );
7345
+ mch_signal (SIGTSTP , restricted ? SIG_IGN : sig_tstp );
7287
7346
# endif
7288
7347
return 1 ; // succeed
7289
7348
}
@@ -7415,7 +7474,7 @@ sysmouse_open(void)
7415
7474
if (ioctl (1 , CONS_MOUSECTL , & mouse ) == -1 )
7416
7475
return FAIL ;
7417
7476
7418
- signal (SIGUSR2 , ( void ( * )()) sig_sysmouse );
7477
+ mch_signal (SIGUSR2 , sig_sysmouse );
7419
7478
mouse .operation = MOUSE_SHOW ;
7420
7479
ioctl (1 , CONS_MOUSECTL , & mouse );
7421
7480
return OK ;
@@ -7430,7 +7489,7 @@ sysmouse_close(void)
7430
7489
{
7431
7490
struct mouse_info mouse ;
7432
7491
7433
- signal (SIGUSR2 , restricted ? SIG_IGN : SIG_DFL );
7492
+ mch_signal (SIGUSR2 , restricted ? SIG_IGN : SIG_DFL );
7434
7493
mouse .operation = MOUSE_MODE ;
7435
7494
mouse .u .mode .mode = 0 ;
7436
7495
mouse .u .mode .signal = 0 ;
0 commit comments