1 2 3 /* This version of microEmacs is based on the public domain C 4 * version written by Dave G. Conroy. 5 * The D programming language version is written by Walter Bright. 6 * http://www.digitalmars.com/d/ 7 * This program is in the public domain. 8 */ 9 10 11 /* 12 * The routines in this file are called to create a subjob running a command 13 * interpreter. 14 */ 15 16 module spawn; 17 18 import core.stdc.stdlib; 19 import core.stdc.time; 20 21 import std.conv; 22 import std.stdio; 23 import std.file; 24 import std.process; 25 import std..string; 26 import std.utf; 27 28 version (Posix) 29 { 30 import core.sys.posix.unistd; 31 } 32 33 import ed; 34 import buffer; 35 import window; 36 import display; 37 import main; 38 import file; 39 import terminal; 40 41 42 43 /* 44 * Create a subjob with a copy of the command intrepreter in it. When the 45 * command interpreter exits, mark the screen as garbage so that you do a full 46 * repaint. Bound to "C-C". The message at the start in VMS puts out a newline. 47 * Under some (unknown) condition, you don't get one free when DCL starts up. 48 */ 49 int spawncli(bool f, int n) 50 { 51 movecursor(term.t_nrow-1, 0); /* Seek to last line. */ 52 version (Windows) 53 { 54 term.t_flush(); 55 auto comspec = core.stdc.stdlib.getenv("COMSPEC"); 56 string[] args; 57 args ~= to!string(comspec); 58 args ~= "COMMAND.COM"; 59 spawnProcess(args); 60 } 61 version (Posix) 62 { 63 term.t_flush(); 64 term.t_close(); /* stty to old settings */ 65 auto cp = core.stdc.stdlib.getenv("SHELL"); 66 if (cp && *cp != '\0') 67 core.stdc.stdlib.system(cp); 68 else 69 core.stdc.stdlib.system("exec /bin/sh"); 70 sleep(2); 71 term.t_open(); 72 } 73 sgarbf = TRUE; 74 return(TRUE); 75 } 76 77 /* 78 * Run a one-liner in a subjob. When the command returns, wait for a single 79 * character to be typed, then mark the screen as garbage so a full repaint is 80 * done. Bound to "C-X !". 81 */ 82 int spawn(bool f, int n) 83 { 84 int s; 85 string line; 86 version (Windows) 87 { 88 if ((s=mlreply("MS-DOS command: ", null, line)) != TRUE) 89 return (s); 90 core.stdc.stdlib.system(toUTF8(line).toStringz()); 91 while (term.t_getchar() != '\r') /* Pause. */ 92 { 93 } 94 sgarbf = TRUE; 95 return (TRUE); 96 } 97 version (Posix) 98 { 99 if ((s=mlreply("! ", null, line)) != TRUE) 100 return (s); 101 term.t_putchar('\n'); /* Already have '\r' */ 102 term.t_flush(); 103 term.t_close(); /* stty to old modes */ 104 core.stdc.stdlib.system(toUTF8(line).toStringz()); 105 sleep(2); 106 term.t_open(); 107 printf("[End]"); /* Pause. */ 108 term.t_flush(); 109 while ((s = term.t_getchar()) != '\r' && s != ' ') 110 { 111 } 112 sgarbf = TRUE; 113 return (TRUE); 114 } 115 } 116 117 /* 118 * Pipe a one line command into a window 119 * Bound to ^X @ 120 */ 121 int spawn_pipe(bool f, int n) 122 { 123 int s; /* return status from CLI */ 124 WINDOW *wp; /* pointer to new window */ 125 BUFFER *bp; /* pointer to buffer to zot */ 126 static string bname = "[DOS]"; 127 128 static string filnam = "DOS.TMP"; 129 string line; /* command line sent to shell */ 130 string sline; 131 132 /* get the command to pipe in */ 133 if ((s = mlreply("DOS:", null, line)) != TRUE) 134 return s; 135 136 /* get rid of the command output buffer if it exists */ 137 if ((bp=buffer_find(bname, FALSE, BFTEMP)) != null) /* if buffer exists */ 138 { 139 /* If buffer is displayed, try to move it off screen */ 140 /* (can't remove an on-screen buffer) */ 141 if (bp.b_nwnd) /* if buffer is displayed */ 142 { if (bp == curbp) /* if it's the current window */ 143 window_next(FALSE,1); /* make another window current */ 144 window_only(FALSE, 1); 145 146 if (buffer_remove(bp) != TRUE) 147 goto fail; 148 } 149 } 150 151 /* split the current window to make room for the command output */ 152 if (window_split(FALSE, 1) == FALSE) 153 goto fail; 154 155 sline = toUTF8(line) ~ ">" ~ filnam; 156 157 version (Windows) 158 { 159 movecursor(term.t_nrow - 2, 0); 160 core.stdc.stdlib.system(sline.toStringz()); 161 sgarbf = TRUE; 162 if (std.file.exists(filnam) && std.file.isFile(filnam)) 163 return FALSE; 164 } 165 version (Posix) 166 { 167 term.t_putchar('\n'); /* Already have '\r' */ 168 term.t_flush(); 169 term.t_close(); /* stty to old modes */ 170 core.stdc.stdlib.system(sline.toStringz()); 171 term.t_open(); 172 term.t_flush(); 173 sgarbf = TRUE; 174 } 175 176 /* and read the stuff in */ 177 if (file_readin(filnam) == FALSE) 178 return(FALSE); 179 180 /* and get rid of the temporary file */ 181 remove(filnam); 182 return(TRUE); 183 184 fail: 185 return FALSE; 186 } 187 188 /* 189 * filter a buffer through an external DOS program 190 * Bound to ^X # 191 */ 192 int spawn_filter(bool f, int n) 193 { 194 int s; /* return status from CLI */ 195 BUFFER *bp; /* pointer to buffer to zot */ 196 string line; /* command line to send to shell */ 197 string tmpnam; /* place to store real file name */ 198 string bname1 = "fltinp"; 199 200 string filnam1 = "fltinp"; 201 string filnam2 = "fltout"; 202 203 if (curbp.b_flag & BFRDONLY) /* if buffer is read-only */ 204 return FALSE; /* fail */ 205 206 /* get the filter name and its args */ 207 if ((s=mlreply("Filter:", null, line)) != TRUE) 208 return(s); 209 210 /* setup the proper file names */ 211 bp = curbp; 212 tmpnam = bp.b_fname; /* save the original name */ 213 bp.b_fname = bname1; /* set it to our new one */ 214 215 /* write it out, checking for errors */ 216 if (writeout(filnam1) != TRUE) { 217 mlwrite("[Cannot write filter file]"); 218 bp.b_fname = tmpnam; 219 return(FALSE); 220 } 221 222 line ~= " <fltinp >fltout"; 223 version (Windows) 224 { 225 movecursor(term.t_nrow - 2, 0); 226 core.stdc.stdlib.system(toUTF8(line).toStringz()); 227 } 228 version (Posix) 229 { 230 term.t_putchar('\n'); /* Already have '\r' */ 231 term.t_flush(); 232 term.t_close(); /* stty to old modes */ 233 core.stdc.stdlib.system(toUTF8(line).toStringz()); 234 term.t_open(); 235 term.t_flush(); 236 } 237 238 sgarbf = TRUE; 239 s = TRUE; 240 241 /* on failure, escape gracefully */ 242 if (s != TRUE || ((s = readin(filnam2)) == FALSE)) { 243 mlwrite("[Execution failed]"); 244 bp.b_fname = tmpnam; 245 goto ret; 246 } 247 248 /* reset file name */ 249 bp.b_fname = tmpnam; /* restore name */ 250 bp.b_flag |= BFCHG; /* flag it as changed */ 251 s = TRUE; 252 253 ret: 254 /* and get rid of the temporary file */ 255 remove(toUTF8(filnam1)); 256 remove(toUTF8(filnam2)); 257 return s; 258 } 259 260