2 Copyright (C) 2004, 2005, 2006 John E. Davis
4 This file is part of the S-Lang Library.
6 The S-Lang Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The S-Lang Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26 #ifdef HAVE_SYS_TYPES_H
27 # include <sys/types.h>
29 #ifdef HAVE_SYS_WAIT_H
30 # include <sys/wait.h>
38 /* Do not trust these environments */
39 #if defined(__MINGW32__) || defined(AMIGA)
40 # ifdef SLANG_POSIX_SIGNALS
41 # undef SLANG_POSIX_SIGNALS
45 /* This function will cause system calls to be restarted after signal if possible */
46 SLSig_Fun_Type
*SLsignal (int sig
, SLSig_Fun_Type
*f
)
48 #if defined(SLANG_POSIX_SIGNALS)
49 struct sigaction old_sa
, new_sa
;
52 /* We want system calls to be interrupted by SIGALRM. */
53 if (sig
== SIGALRM
) return SLsignal_intr (sig
, f
);
56 sigemptyset (&new_sa
.sa_mask
);
57 new_sa
.sa_handler
= f
;
61 new_sa
.sa_flags
|= SA_RESTART
;
64 if (-1 == sigaction (sig
, &new_sa
, &old_sa
))
65 return (SLSig_Fun_Type
*) SIG_ERR
;
67 return old_sa
.sa_handler
;
70 return signal (sig
, f
);
74 /* This function will NOT cause system calls to be restarted after
77 SLSig_Fun_Type
*SLsignal_intr (int sig
, SLSig_Fun_Type
*f
)
79 #ifdef SLANG_POSIX_SIGNALS
80 struct sigaction old_sa
, new_sa
;
82 sigemptyset (&new_sa
.sa_mask
);
83 new_sa
.sa_handler
= f
;
87 new_sa
.sa_flags
|= SA_INTERRUPT
;
90 if (-1 == sigaction (sig
, &new_sa
, &old_sa
))
91 return (SLSig_Fun_Type
*) SIG_ERR
;
93 return old_sa
.sa_handler
;
96 return signal (sig
, f
);
100 /* We are primarily interested in blocking signals that would cause the
101 * application to reset the tty. These include suspend signals and
102 * possibly interrupt signals.
104 #ifdef SLANG_POSIX_SIGNALS
105 static sigset_t Old_Signal_Mask
;
108 static volatile unsigned int Blocked_Depth
;
110 int SLsig_block_signals (void)
112 #ifdef SLANG_POSIX_SIGNALS
117 if (Blocked_Depth
!= 1)
122 #ifdef SLANG_POSIX_SIGNALS
123 sigemptyset (&new_mask
);
125 sigaddset (&new_mask
, SIGQUIT
);
128 sigaddset (&new_mask
, SIGTSTP
);
131 sigaddset (&new_mask
, SIGINT
);
134 sigaddset (&new_mask
, SIGTTIN
);
137 sigaddset (&new_mask
, SIGTTOU
);
140 sigaddset (&new_mask
, SIGWINCH
);
143 (void) sigprocmask (SIG_BLOCK
, &new_mask
, &Old_Signal_Mask
);
146 /* Not implemented. */
151 int SLsig_unblock_signals (void)
153 if (Blocked_Depth
== 0)
158 if (Blocked_Depth
!= 0)
161 #ifdef SLANG_POSIX_SIGNALS
162 (void) sigprocmask (SIG_SETMASK
, &Old_Signal_Mask
, NULL
);
170 int SLsystem (char *cmd
)
172 SLang_verror (SL_NOT_IMPLEMENTED
, "system not implemented");
177 int SLsystem (char *cmd
)
179 #ifdef SLANG_POSIX_SIGNALS
182 struct sigaction ignore
;
184 struct sigaction save_intr
;
187 struct sigaction save_quit
;
190 sigset_t child_mask
, save_mask
;
193 if (cmd
== NULL
) return 1;
195 ignore
.sa_handler
= SIG_IGN
;
196 sigemptyset (&ignore
.sa_mask
);
200 if (-1 == sigaction (SIGINT
, &ignore
, &save_intr
))
205 if (-1 == sigaction (SIGQUIT
, &ignore
, &save_quit
))
207 (void) sigaction (SIGINT
, &save_intr
, NULL
);
213 sigemptyset (&child_mask
);
214 sigaddset (&child_mask
, SIGCHLD
);
215 if (-1 == sigprocmask (SIG_BLOCK
, &child_mask
, &save_mask
))
218 (void) sigaction (SIGINT
, &save_intr
, NULL
);
221 (void) sigaction (SIGQUIT
, &save_quit
, NULL
);
235 (void) sigaction (SIGINT
, &save_intr
, NULL
);
238 (void) sigaction (SIGQUIT
, &save_quit
, NULL
);
241 (void) sigprocmask (SIG_SETMASK
, &save_mask
, NULL
);
244 execl ("/bin/sh", "sh", "-c", cmd
, NULL
);
250 while (-1 == waitpid (pid
, &status
, 0))
257 if (errno
== ERESTARTSYS
)
265 if (-1 == sigaction (SIGINT
, &save_intr
, NULL
))
269 if (-1 == sigaction (SIGQUIT
, &save_quit
, NULL
))
273 if (-1 == sigprocmask (SIG_SETMASK
, &save_mask
, NULL
))
279 #else /* No POSIX Signals */
289 squit
= SLsignal (SIGQUIT
, SIG_IGN
);
292 sint
= SLsignal (SIGINT
, SIG_IGN
);
294 status
= system (cmd
);
296 SLsignal (SIGINT
, sint
);
299 SLsignal (SIGQUIT
, squit
);
302 #endif /* POSIX_SIGNALS */
308 static int msw_system (char *cmd
)
310 STARTUPINFO startup_info
;
311 PROCESS_INFORMATION process_info
;
314 if (cmd
== NULL
) return -1;
316 memset ((char *) &startup_info
, 0, sizeof (STARTUPINFO
));
317 startup_info
.cb
= sizeof(STARTUPINFO
);
318 startup_info
.dwFlags
= STARTF_USESHOWWINDOW
;
319 startup_info
.wShowWindow
= SW_SHOWDEFAULT
;
321 if (FALSE
== CreateProcess (NULL
,
326 NORMAL_PRIORITY_CLASS
|CREATE_NEW_CONSOLE
,
332 SLang_verror (0, "%s: CreateProcess failed.", cmd
);
338 if (0xFFFFFFFFUL
!= WaitForSingleObject (process_info
.hProcess
, INFINITE
))
342 if (TRUE
== GetExitCodeProcess (process_info
.hProcess
, &exit_code
))
343 status
= (int) exit_code
;
346 CloseHandle (process_info
.hThread
);
347 CloseHandle (process_info
.hProcess
);