2
/******************************************************************************
3
* MODULE : tm_shell.cpp
4
* DESCRIPTION: TeXmacs shell
5
* COPYRIGHT : (C) 2000 Joris van der Hoeven
6
*******************************************************************************
7
* This software falls under the GNU general public license and comes WITHOUT
8
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
9
* If you don't have this file, write to the Free Software Foundation, Inc.,
10
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
11
******************************************************************************/
25
extern charp* environ;
34
#define DATA_BEGIN ((char) 2)
35
#define DATA_END ((char) 5)
36
#define DATA_ESCAPE ((char) 27)
37
//#define DATA_BEGIN "[BEGIN]"
38
//#define DATA_END "[END]"
39
//#define DATA_ESCAPE "[ESCAPE]"
41
int pid; // process identifier of the child
42
int tochild[2]; // for data going to the child
43
int fromchild[2]; // for data coming from the child
44
int in; // file descriptor for data going to the child
45
int out; // file descriptor for data coming from the child
46
FILE* fin; // file associated to in
48
/******************************************************************************
49
* Handling shell input and output
50
******************************************************************************/
53
append (charp &s, char c, int& pos, int& max) {
58
s= (charp) malloc (max);
59
for (i=0; i<pos; i++) s[i]=r[i];
66
shell_output (bool hide= false) {
69
charp output= (charp) malloc (output_max);
70
cout << DATA_BEGIN << "verbatim:";
80
int nr= select (max_fd, &rfds, NULL, NULL, &tv);
86
if (FD_ISSET (out, &rfds)) {
89
r = read (out, outbuf, 1024);
91
cerr << "TeXmacs shell] read failed\n";
101
else for (i=0; i<r; i++) {
102
append (output, outbuf[i], output_pos, output_max);
103
if (outbuf[i]=='\n') {
104
append (output, '\0', output_pos, output_max);
105
if (hide) hide= false;
113
if (strncmp (output, "tmshell$ ", 9) == 0)
125
cin.getline (input, 10000, '\n');
126
strcat (input, "\n");
127
write (in, input, strlen (input));
132
shell_interrupt (int sig) {
133
cout << DATA_BEGIN << "scheme:(with \"color\" \"red\" \"";
134
cout << "Interrupted TeXmacs shell";
135
cout << "\")" << DATA_END;
137
// kill (pid, SIGINT); // Why does this not work ???
142
/******************************************************************************
143
* Launching the shell using a fork
144
******************************************************************************/
152
execve("/bin/sh", argv, environ);
158
setenv ("PS1", "tmshell$ ", true);
159
cout << DATA_BEGIN << "verbatim:";
160
cout << "Shell session inside TeXmacs";
164
if (pid==0) { // the child
165
dup2 (tochild [IN], STDIN);
166
close (tochild [IN]);
167
close (fromchild [IN]);
168
close (tochild [OUT]);
169
dup2 (fromchild [OUT], STDOUT);
170
dup2 (STDOUT, STDERR);
171
close (fromchild [OUT]);
175
else { // the main process
178
close (fromchild [OUT]);
180
close (tochild [IN]);
181
fin= fdopen (in, "w");
182
signal (SIGINT, shell_interrupt);