2 * The routines in this file are called to create a subjob running a command
3 * interpreter. This code is a big fat nothing on CP/M-86. You lose.
17 #define EFN 0 /* Event flag. */
19 #include <ssdef.h> /* Random headers. */
24 extern int oldmode
[]; /* In "termio.c" */
25 extern int newmode
[]; /* In "termio.c" */
26 extern short iochan
; /* In "termio.c" */
38 * Create a subjob with a copy of the command intrepreter in it. When the
39 * command interpreter exits, mark the screen as garbage so that you do a full
40 * repaint. Bound to "C-C". The message at the start in VMS puts out a newline.
41 * Under some (unknown) condition, you don't get one free when DCL starts up.
51 newcli
= Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW
);
52 mlwrite("[Starting new CLI]");
54 Execute("", newcli
, 0);
64 movecursor(term
.t_nrow
, 0); /* In last line. */
65 mlputs("[Starting DCL]\r\n");
66 (*term
.t_flush
)(); /* Ignore "ttcol". */
68 return (sys(NULL
)); /* NULL => DCL. */
71 mlwrite("Not in CP/M-86");
74 movecursor(term
.t_nrow
, 0); /* Seek to last line. */
76 sys("\\command.com", ""); /* Run CLI. */
81 movecursor(term
.t_nrow
, 0); /* Seek to last line. */
83 ttclose(); /* stty to old settings */
84 if ((cp
= getenv("SHELL")) != NULL
&& *cp
!= '\0')
87 system("exec /bin/sh");
96 * Run a one-liner in a subjob. When the command returns, wait for a single
97 * character to be typed, then mark the screen as garbage so a full repaint is
98 * done. Bound to "C-X !".
109 newcli
= Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW
);
110 if ((s
=mlreply("CLI command: ", line
, NLINE
)) != TRUE
)
112 Execute(line
,0,newcli
);
115 while ((*term
.t_getchar
)() != '\r') /* Pause. */
121 if ((s
=mlreply("DCL command: ", line
, NLINE
)) != TRUE
)
123 (*term
.t_putchar
)('\n'); /* Already have '\r' */
125 s
= sys(line
); /* Run the command. */
126 mlputs("\r\n\n[End]"); /* Pause. */
128 while ((*term
.t_getchar
)() != '\r')
134 mlwrite("Not in CP/M-86");
138 if ((s
=mlreply("MS-DOS command: ", line
, NLINE
)) != TRUE
)
141 while ((*term
.t_getchar
)() != '\r') /* Pause. */
147 if ((s
=mlreply("! ", line
, NLINE
)) != TRUE
)
149 (*term
.t_putchar
)('\n'); /* Already have '\r' */
151 ttclose(); /* stty to old modes */
155 mlputs("[End]"); /* Pause. */
157 while ((s
= (*term
.t_getchar
)()) != '\r' && s
!= ' ')
166 * Run a command. The "cmd" is a pointer to a command string, or NULL if you
167 * want to run a copy of DCL in the subjob (this is how the standard routine
168 * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in
169 * and the way out, because DCL does not want the channel to be in raw mode.
174 struct dsc$descriptor cdsc
;
175 struct dsc$descriptor
*cdscp
;
180 status
= SYS$
QIOW(EFN
, iochan
, IO$_SETMODE
, iosb
, 0, 0,
181 oldmode
, sizeof(oldmode
), 0, 0, 0, 0);
182 if (status
!=SS$_NORMAL
|| (iosb
[0]&0xFFFF)!=SS$_NORMAL
)
184 cdscp
= NULL
; /* Assume DCL. */
185 if (cmd
!= NULL
) { /* Build descriptor. */
186 cdsc
.dsc$a_pointer
= cmd
;
187 cdsc
.dsc$w_length
= strlen(cmd
);
188 cdsc
.dsc$b_dtype
= DSC$K_DTYPE_T
;
189 cdsc
.dsc$b_class
= DSC$K_CLASS_S
;
192 status
= LIB$
SPAWN(cdscp
, 0, 0, 0, 0, 0, &substatus
, 0, 0, 0);
193 if (status
!= SS$_NORMAL
)
195 status
= SYS$
QIOW(EFN
, iochan
, IO$_SETMODE
, iosb
, 0, 0,
196 newmode
, sizeof(newmode
), 0, 0, 0, 0);
197 if (status
!=SS$_NORMAL
|| (iosb
[0]&0xFFFF)!=SS$_NORMAL
)
199 if ((substatus
&STS$M_SUCCESS
) == 0) /* Command failed. */
207 * This routine, once again by Bob McNamara, is a C translation of the "system"
208 * routine in the MWC-86 run time library. It differs from the "system" routine
209 * in that it does not unconditionally append the string ".exe" to the end of
210 * the command name. We needed to do this because we want to be able to spawn
211 * off "command.com". We really do not understand what it does, but if you don't
212 * do it exactly "malloc" starts doing very very strange things.
224 n
= ((n
+ dsreg() + 16) & 0xFFF0) + 16;
225 return(execall(cmd
, tail
, n
));
229 return forklp(cmd
, tail
, NULL
);