1 /* Copyright (c) 1998, 1999, 2001, 2002 John E. Davis
2 * This file is part of the S-Lang library.
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Perl Artistic License.
11 #ifdef HAVE_SYS_TYPES_H
12 # include <sys/types.h>
14 #ifdef HAVE_SYS_WAIT_H
15 # include <sys/wait.h>
23 /* Do not trust these environments */
24 #if defined(__CYGWIN32__) || defined(__MINGW32__) || defined(AMIGA)
25 # ifdef SLANG_POSIX_SIGNALS
26 # undef SLANG_POSIX_SIGNALS
30 /* This function will cause system calls to be restarted after signal if possible */
31 SLSig_Fun_Type
*SLsignal (int sig
, SLSig_Fun_Type
*f
)
33 #if defined(SLANG_POSIX_SIGNALS)
34 struct sigaction old_sa
, new_sa
;
37 /* We want system calls to be interrupted by SIGALRM. */
38 if (sig
== SIGALRM
) return SLsignal_intr (sig
, f
);
41 sigemptyset (&new_sa
.sa_mask
);
42 new_sa
.sa_handler
= f
;
46 new_sa
.sa_flags
|= SA_RESTART
;
49 if (-1 == sigaction (sig
, &new_sa
, &old_sa
))
50 return (SLSig_Fun_Type
*) SIG_ERR
;
52 return old_sa
.sa_handler
;
55 return signal (sig
, f
);
59 /* This function will NOT cause system calls to be restarted after
62 SLSig_Fun_Type
*SLsignal_intr (int sig
, SLSig_Fun_Type
*f
)
64 #ifdef SLANG_POSIX_SIGNALS
65 struct sigaction old_sa
, new_sa
;
67 sigemptyset (&new_sa
.sa_mask
);
68 new_sa
.sa_handler
= f
;
72 new_sa
.sa_flags
|= SA_INTERRUPT
;
75 if (-1 == sigaction (sig
, &new_sa
, &old_sa
))
76 return (SLSig_Fun_Type
*) SIG_ERR
;
78 return old_sa
.sa_handler
;
81 return signal (sig
, f
);
85 /* We are primarily interested in blocking signals that would cause the
86 * application to reset the tty. These include suspend signals and
87 * possibly interrupt signals.
89 #ifdef SLANG_POSIX_SIGNALS
90 static sigset_t Old_Signal_Mask
;
93 static volatile unsigned int Blocked_Depth
;
95 int SLsig_block_signals (void)
97 #ifdef SLANG_POSIX_SIGNALS
102 if (Blocked_Depth
!= 1)
107 #ifdef SLANG_POSIX_SIGNALS
108 sigemptyset (&new_mask
);
110 sigaddset (&new_mask
, SIGQUIT
);
113 sigaddset (&new_mask
, SIGTSTP
);
116 sigaddset (&new_mask
, SIGINT
);
119 sigaddset (&new_mask
, SIGTTIN
);
122 sigaddset (&new_mask
, SIGTTOU
);
125 sigaddset (&new_mask
, SIGWINCH
);
128 (void) sigprocmask (SIG_BLOCK
, &new_mask
, &Old_Signal_Mask
);
131 /* Not implemented. */
136 int SLsig_unblock_signals (void)
138 if (Blocked_Depth
== 0)
143 if (Blocked_Depth
!= 0)
146 #ifdef SLANG_POSIX_SIGNALS
147 (void) sigprocmask (SIG_SETMASK
, &Old_Signal_Mask
, NULL
);
155 int SLsystem (char *cmd
)
157 SLang_verror (SL_NOT_IMPLEMENTED
, "system not implemented");
162 int SLsystem (char *cmd
)
164 #ifdef SLANG_POSIX_SIGNALS
167 struct sigaction ignore
;
169 struct sigaction save_intr
;
172 struct sigaction save_quit
;
175 sigset_t child_mask
, save_mask
;
178 if (cmd
== NULL
) return 1;
180 ignore
.sa_handler
= SIG_IGN
;
181 sigemptyset (&ignore
.sa_mask
);
185 if (-1 == sigaction (SIGINT
, &ignore
, &save_intr
))
190 if (-1 == sigaction (SIGQUIT
, &ignore
, &save_quit
))
192 (void) sigaction (SIGINT
, &save_intr
, NULL
);
198 sigemptyset (&child_mask
);
199 sigaddset (&child_mask
, SIGCHLD
);
200 if (-1 == sigprocmask (SIG_BLOCK
, &child_mask
, &save_mask
))
203 (void) sigaction (SIGINT
, &save_intr
, NULL
);
206 (void) sigaction (SIGQUIT
, &save_quit
, NULL
);
220 (void) sigaction (SIGINT
, &save_intr
, NULL
);
223 (void) sigaction (SIGQUIT
, &save_quit
, NULL
);
226 (void) sigprocmask (SIG_SETMASK
, &save_mask
, NULL
);
229 execl ("/bin/sh", "sh", "-c", cmd
, NULL
);
235 while (-1 == waitpid (pid
, &status
, 0))
242 if (errno
== ERESTARTSYS
)
250 if (-1 == sigaction (SIGINT
, &save_intr
, NULL
))
254 if (-1 == sigaction (SIGQUIT
, &save_quit
, NULL
))
258 if (-1 == sigprocmask (SIG_SETMASK
, &save_mask
, NULL
))
264 #else /* No POSIX Signals */
274 squit
= SLsignal (SIGQUIT
, SIG_IGN
);
277 sint
= SLsignal (SIGINT
, SIG_IGN
);
279 status
= system (cmd
);
281 SLsignal (SIGINT
, sint
);
284 SLsignal (SIGQUIT
, squit
);
287 #endif /* POSIX_SIGNALS */
293 static int msw_system (char *cmd
)
295 STARTUPINFO startup_info
;
296 PROCESS_INFORMATION process_info
;
299 if (cmd
== NULL
) return -1;
301 memset ((char *) &startup_info
, 0, sizeof (STARTUPINFO
));
302 startup_info
.cb
= sizeof(STARTUPINFO
);
303 startup_info
.dwFlags
= STARTF_USESHOWWINDOW
;
304 startup_info
.wShowWindow
= SW_SHOWDEFAULT
;
306 if (FALSE
== CreateProcess (NULL
,
311 NORMAL_PRIORITY_CLASS
|CREATE_NEW_CONSOLE
,
317 SLang_verror (0, "%s: CreateProcess failed.", cmd
);
323 if (0xFFFFFFFFUL
!= WaitForSingleObject (process_info
.hProcess
, INFINITE
))
327 if (TRUE
== GetExitCodeProcess (process_info
.hProcess
, &exit_code
))
328 status
= (int) exit_code
;
331 CloseHandle (process_info
.hThread
);
332 CloseHandle (process_info
.hProcess
);