1 /*
2  * $Id: sysafe.i,v 1.1 2005-09-18 22:06:10 dhmunro Exp $
3  * Replacement for system function safe for use when Yorick gets huge.
4  */
5 /* Copyright (c) 2005, The Regents of the University of California.
6  * All rights reserved.
7  * This file is part of yorick (http://yorick.sourceforge.net).
8  * Read the accompanying LICENSE file for details.
9  */
10 
sysafe(command)11 func sysafe(command)
12 /* DOCUMENT sysafe, "command line"
13          or system, "command line"
14      pass the command line to a UNIX sh (Bourne) shell for execution.
15      This requires a fork() system call, which in turn makes a copy of
16      the yorick executable in virtual memory before replacing that copy
17      with the sh shell.  If yorick has grown to enormous size, the copy
18      can bring your machine to its knees or kill it.  If you include
19      sysafe.i before yorick grows (before you start the calculation that
20      requires the large data arrays), a pipe is opened to an sh which
21      remains running, and the original system command is replaced by
22      sysafe.  Future system commands will be piped to the already
23      running sh, so no dangerous copy operation is required.
24 
25      There are four problems with this approach:
26        (1) You can't run interactive programs with sysafe, because the
27            stdin is from the pipe (sysafe_pipe) instead of the keyboard.
28            Attempting to do so may lock up yorick.
29        (2) Since the command runs asynchronously now, yorick can't wait
30            until it completes, and yorick's prompt will often precede
31            the output from the command, unlike using the default system
32            function.
33        (3) Some typographical errors in commands may kill the sh; since
34            you don't start a new one each time, the system command will
35            stop working.
36        (4) The shorthand $ syntax still uses the dangerous system call;
37            you need to call system as an ordinary function for sysafe
38            to protect you.
39 
40    SEE ALSO: system_orig
41  */
42 {
43   write, sysafe_pipe, format="%s\n", command;
44   fflush, sysafe_pipe;
45 }
46 
47 if (is_void(system_orig)) {
48   sysafe_pipe= popen("sh", 1);
49   system_orig= system;
50   system= sysafe;
51 }
52