1a5f0fb15SPaul Saab /* 2000ba3e8STim J. Robbins * Copyright (C) 1984-2002 Mark Nudelman 3a5f0fb15SPaul Saab * 4a5f0fb15SPaul Saab * You may distribute under the terms of either the GNU General Public 5a5f0fb15SPaul Saab * License or the Less License, as specified in the README file. 6a5f0fb15SPaul Saab * 7a5f0fb15SPaul Saab * For more information about less, or for information on how to 8a5f0fb15SPaul Saab * contact the author, see the README file. 9a5f0fb15SPaul Saab */ 10a5f0fb15SPaul Saab 11a5f0fb15SPaul Saab 12a5f0fb15SPaul Saab /* 13a5f0fb15SPaul Saab * Routines to execute other programs. 14a5f0fb15SPaul Saab * Necessarily very OS dependent. 15a5f0fb15SPaul Saab */ 16a5f0fb15SPaul Saab 17a5f0fb15SPaul Saab #include "less.h" 18c9346414SPaul Saab #include <signal.h> 19a5f0fb15SPaul Saab #include "position.h" 20a5f0fb15SPaul Saab 21a5f0fb15SPaul Saab #if MSDOS_COMPILER 22a5f0fb15SPaul Saab #include <dos.h> 23a5f0fb15SPaul Saab #ifdef _MSC_VER 24a5f0fb15SPaul Saab #include <direct.h> 25a5f0fb15SPaul Saab #define setdisk(n) _chdrive((n)+1) 26a5f0fb15SPaul Saab #else 27a5f0fb15SPaul Saab #include <dir.h> 28a5f0fb15SPaul Saab #endif 29a5f0fb15SPaul Saab #endif 30a5f0fb15SPaul Saab 31a5f0fb15SPaul Saab extern int screen_trashed; 32a5f0fb15SPaul Saab extern IFILE curr_ifile; 33a5f0fb15SPaul Saab 34a5f0fb15SPaul Saab 35a5f0fb15SPaul Saab #if HAVE_SYSTEM 36a5f0fb15SPaul Saab 37a5f0fb15SPaul Saab /* 38a5f0fb15SPaul Saab * Pass the specified command to a shell to be executed. 39a5f0fb15SPaul Saab * Like plain "system()", but handles resetting terminal modes, etc. 40a5f0fb15SPaul Saab */ 41a5f0fb15SPaul Saab public void 42a5f0fb15SPaul Saab lsystem(cmd, donemsg) 43a5f0fb15SPaul Saab char *cmd; 44a5f0fb15SPaul Saab char *donemsg; 45a5f0fb15SPaul Saab { 46a5f0fb15SPaul Saab register int inp; 47a5f0fb15SPaul Saab #if HAVE_SHELL 48a5f0fb15SPaul Saab register char *shell; 49a5f0fb15SPaul Saab register char *p; 50a5f0fb15SPaul Saab #endif 51a5f0fb15SPaul Saab IFILE save_ifile; 52a5f0fb15SPaul Saab #if MSDOS_COMPILER 53a5f0fb15SPaul Saab char cwd[FILENAME_MAX+1]; 54a5f0fb15SPaul Saab #endif 55a5f0fb15SPaul Saab 56a5f0fb15SPaul Saab /* 57a5f0fb15SPaul Saab * Print the command which is to be executed, 58a5f0fb15SPaul Saab * unless the command starts with a "-". 59a5f0fb15SPaul Saab */ 60a5f0fb15SPaul Saab if (cmd[0] == '-') 61a5f0fb15SPaul Saab cmd++; 62a5f0fb15SPaul Saab else 63a5f0fb15SPaul Saab { 64a5f0fb15SPaul Saab clear_bot(); 65a5f0fb15SPaul Saab putstr("!"); 66a5f0fb15SPaul Saab putstr(cmd); 67a5f0fb15SPaul Saab putstr("\n"); 68a5f0fb15SPaul Saab } 69a5f0fb15SPaul Saab 70a5f0fb15SPaul Saab #if MSDOS_COMPILER 71a5f0fb15SPaul Saab /* 72a5f0fb15SPaul Saab * Working directory is global on MSDOS. 73a5f0fb15SPaul Saab * The child might change the working directory, so we 74a5f0fb15SPaul Saab * must save and restore CWD across calls to "system", 75a5f0fb15SPaul Saab * or else we won't find our file when we return and 76a5f0fb15SPaul Saab * try to "reedit_ifile" it. 77a5f0fb15SPaul Saab */ 78a5f0fb15SPaul Saab getcwd(cwd, FILENAME_MAX); 79a5f0fb15SPaul Saab #endif 80a5f0fb15SPaul Saab 81a5f0fb15SPaul Saab /* 82a5f0fb15SPaul Saab * Close the current input file. 83a5f0fb15SPaul Saab */ 84a5f0fb15SPaul Saab save_ifile = save_curr_ifile(); 85a5f0fb15SPaul Saab (void) edit_ifile(NULL_IFILE); 86a5f0fb15SPaul Saab 87a5f0fb15SPaul Saab /* 88a5f0fb15SPaul Saab * De-initialize the terminal and take out of raw mode. 89a5f0fb15SPaul Saab */ 90a5f0fb15SPaul Saab deinit(); 91a5f0fb15SPaul Saab flush(); /* Make sure the deinit chars get out */ 92a5f0fb15SPaul Saab raw_mode(0); 93a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 94a5f0fb15SPaul Saab close_getchr(); 95a5f0fb15SPaul Saab #endif 96a5f0fb15SPaul Saab 97a5f0fb15SPaul Saab /* 98a5f0fb15SPaul Saab * Restore signals to their defaults. 99a5f0fb15SPaul Saab */ 100a5f0fb15SPaul Saab init_signals(0); 101a5f0fb15SPaul Saab 102a5f0fb15SPaul Saab #if HAVE_DUP 103a5f0fb15SPaul Saab /* 104a5f0fb15SPaul Saab * Force standard input to be the user's terminal 105a5f0fb15SPaul Saab * (the normal standard input), even if less's standard input 106a5f0fb15SPaul Saab * is coming from a pipe. 107a5f0fb15SPaul Saab */ 108a5f0fb15SPaul Saab inp = dup(0); 109a5f0fb15SPaul Saab close(0); 110c9346414SPaul Saab #if OS2 111c9346414SPaul Saab /* The __open() system call translates "/dev/tty" to "con". */ 112c9346414SPaul Saab if (__open("/dev/tty", OPEN_READ) < 0) 113c9346414SPaul Saab #else 114a5f0fb15SPaul Saab if (open("/dev/tty", OPEN_READ) < 0) 115c9346414SPaul Saab #endif 116a5f0fb15SPaul Saab dup(inp); 117a5f0fb15SPaul Saab #endif 118a5f0fb15SPaul Saab 119a5f0fb15SPaul Saab /* 120a5f0fb15SPaul Saab * Pass the command to the system to be executed. 121a5f0fb15SPaul Saab * If we have a SHELL environment variable, use 122a5f0fb15SPaul Saab * <$SHELL -c "command"> instead of just <command>. 123a5f0fb15SPaul Saab * If the command is empty, just invoke a shell. 124a5f0fb15SPaul Saab */ 125a5f0fb15SPaul Saab #if HAVE_SHELL 126a5f0fb15SPaul Saab p = NULL; 127a5f0fb15SPaul Saab if ((shell = lgetenv("SHELL")) != NULL && *shell != '\0') 128a5f0fb15SPaul Saab { 129a5f0fb15SPaul Saab if (*cmd == '\0') 130a5f0fb15SPaul Saab p = save(shell); 131a5f0fb15SPaul Saab else 132a5f0fb15SPaul Saab { 133000ba3e8STim J. Robbins char *esccmd = shell_quote(cmd); 134000ba3e8STim J. Robbins if (esccmd != NULL) 135a5f0fb15SPaul Saab { 136a5f0fb15SPaul Saab p = (char *) ecalloc(strlen(shell) + 137a5f0fb15SPaul Saab strlen(esccmd) + 5, sizeof(char)); 138000ba3e8STim J. Robbins sprintf(p, "%s %s %s", shell, shell_coption(), esccmd); 139a5f0fb15SPaul Saab free(esccmd); 140a5f0fb15SPaul Saab } 141a5f0fb15SPaul Saab } 142a5f0fb15SPaul Saab } 143a5f0fb15SPaul Saab if (p == NULL) 144a5f0fb15SPaul Saab { 145a5f0fb15SPaul Saab if (*cmd == '\0') 146a5f0fb15SPaul Saab p = save("sh"); 147a5f0fb15SPaul Saab else 148a5f0fb15SPaul Saab p = save(cmd); 149a5f0fb15SPaul Saab } 150a5f0fb15SPaul Saab system(p); 151a5f0fb15SPaul Saab free(p); 152a5f0fb15SPaul Saab #else 153a5f0fb15SPaul Saab #if MSDOS_COMPILER==DJGPPC 154a5f0fb15SPaul Saab /* 155a5f0fb15SPaul Saab * Make stdin of the child be in cooked mode. 156a5f0fb15SPaul Saab */ 157a5f0fb15SPaul Saab setmode(0, O_TEXT); 158a5f0fb15SPaul Saab /* 159a5f0fb15SPaul Saab * We don't need to catch signals of the child (it 160a5f0fb15SPaul Saab * also makes trouble with some DPMI servers). 161a5f0fb15SPaul Saab */ 162a5f0fb15SPaul Saab __djgpp_exception_toggle(); 163a5f0fb15SPaul Saab system(cmd); 164a5f0fb15SPaul Saab __djgpp_exception_toggle(); 165a5f0fb15SPaul Saab #else 166a5f0fb15SPaul Saab system(cmd); 167a5f0fb15SPaul Saab #endif 168a5f0fb15SPaul Saab #endif 169a5f0fb15SPaul Saab 170a5f0fb15SPaul Saab #if HAVE_DUP 171a5f0fb15SPaul Saab /* 172a5f0fb15SPaul Saab * Restore standard input, reset signals, raw mode, etc. 173a5f0fb15SPaul Saab */ 174a5f0fb15SPaul Saab close(0); 175a5f0fb15SPaul Saab dup(inp); 176a5f0fb15SPaul Saab close(inp); 177a5f0fb15SPaul Saab #endif 178a5f0fb15SPaul Saab 179a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 180a5f0fb15SPaul Saab open_getchr(); 181a5f0fb15SPaul Saab #endif 182a5f0fb15SPaul Saab init_signals(1); 183a5f0fb15SPaul Saab raw_mode(1); 184a5f0fb15SPaul Saab if (donemsg != NULL) 185a5f0fb15SPaul Saab { 186a5f0fb15SPaul Saab putstr(donemsg); 187a5f0fb15SPaul Saab putstr(" (press RETURN)"); 188a5f0fb15SPaul Saab get_return(); 189a5f0fb15SPaul Saab putchr('\n'); 190a5f0fb15SPaul Saab flush(); 191a5f0fb15SPaul Saab } 192a5f0fb15SPaul Saab init(); 193a5f0fb15SPaul Saab screen_trashed = 1; 194a5f0fb15SPaul Saab 195a5f0fb15SPaul Saab #if MSDOS_COMPILER 196a5f0fb15SPaul Saab /* 197a5f0fb15SPaul Saab * Restore the previous directory (possibly 198a5f0fb15SPaul Saab * changed by the child program we just ran). 199a5f0fb15SPaul Saab */ 200a5f0fb15SPaul Saab chdir(cwd); 201a5f0fb15SPaul Saab #if MSDOS_COMPILER != DJGPPC 202a5f0fb15SPaul Saab /* 203a5f0fb15SPaul Saab * Some versions of chdir() don't change to the drive 204a5f0fb15SPaul Saab * which is part of CWD. (DJGPP does this in chdir.) 205a5f0fb15SPaul Saab */ 206a5f0fb15SPaul Saab if (cwd[1] == ':') 207a5f0fb15SPaul Saab { 208a5f0fb15SPaul Saab if (cwd[0] >= 'a' && cwd[0] <= 'z') 209a5f0fb15SPaul Saab setdisk(cwd[0] - 'a'); 210a5f0fb15SPaul Saab else if (cwd[0] >= 'A' && cwd[0] <= 'Z') 211a5f0fb15SPaul Saab setdisk(cwd[0] - 'A'); 212a5f0fb15SPaul Saab } 213a5f0fb15SPaul Saab #endif 214a5f0fb15SPaul Saab #endif 215a5f0fb15SPaul Saab 216a5f0fb15SPaul Saab /* 217a5f0fb15SPaul Saab * Reopen the current input file. 218a5f0fb15SPaul Saab */ 219a5f0fb15SPaul Saab reedit_ifile(save_ifile); 220a5f0fb15SPaul Saab 221a5f0fb15SPaul Saab #if defined(SIGWINCH) || defined(SIGWIND) 222a5f0fb15SPaul Saab /* 223a5f0fb15SPaul Saab * Since we were ignoring window change signals while we executed 224a5f0fb15SPaul Saab * the system command, we must assume the window changed. 225a5f0fb15SPaul Saab * Warning: this leaves a signal pending (in "sigs"), 226a5f0fb15SPaul Saab * so psignals() should be called soon after lsystem(). 227a5f0fb15SPaul Saab */ 228a5f0fb15SPaul Saab winch(0); 229a5f0fb15SPaul Saab #endif 230a5f0fb15SPaul Saab } 231a5f0fb15SPaul Saab 232a5f0fb15SPaul Saab #endif 233a5f0fb15SPaul Saab 234a5f0fb15SPaul Saab #if PIPEC 235a5f0fb15SPaul Saab 236a5f0fb15SPaul Saab /* 237a5f0fb15SPaul Saab * Pipe a section of the input file into the given shell command. 238a5f0fb15SPaul Saab * The section to be piped is the section "between" the current 239a5f0fb15SPaul Saab * position and the position marked by the given letter. 240a5f0fb15SPaul Saab * 241a5f0fb15SPaul Saab * If the mark is after the current screen, the section between 242a5f0fb15SPaul Saab * the top line displayed and the mark is piped. 243a5f0fb15SPaul Saab * If the mark is before the current screen, the section between 244a5f0fb15SPaul Saab * the mark and the bottom line displayed is piped. 245a5f0fb15SPaul Saab * If the mark is on the current screen, or if the mark is ".", 246a5f0fb15SPaul Saab * the whole current screen is piped. 247a5f0fb15SPaul Saab */ 248a5f0fb15SPaul Saab public int 249a5f0fb15SPaul Saab pipe_mark(c, cmd) 250a5f0fb15SPaul Saab int c; 251a5f0fb15SPaul Saab char *cmd; 252a5f0fb15SPaul Saab { 253a5f0fb15SPaul Saab POSITION mpos, tpos, bpos; 254a5f0fb15SPaul Saab 255a5f0fb15SPaul Saab /* 256a5f0fb15SPaul Saab * mpos = the marked position. 257a5f0fb15SPaul Saab * tpos = top of screen. 258a5f0fb15SPaul Saab * bpos = bottom of screen. 259a5f0fb15SPaul Saab */ 260a5f0fb15SPaul Saab mpos = markpos(c); 261a5f0fb15SPaul Saab if (mpos == NULL_POSITION) 262a5f0fb15SPaul Saab return (-1); 263a5f0fb15SPaul Saab tpos = position(TOP); 264a5f0fb15SPaul Saab if (tpos == NULL_POSITION) 265a5f0fb15SPaul Saab tpos = ch_zero(); 266a5f0fb15SPaul Saab bpos = position(BOTTOM); 267a5f0fb15SPaul Saab 268a5f0fb15SPaul Saab if (c == '.') 269a5f0fb15SPaul Saab return (pipe_data(cmd, tpos, bpos)); 270a5f0fb15SPaul Saab else if (mpos <= tpos) 271a5f0fb15SPaul Saab return (pipe_data(cmd, mpos, bpos)); 272a5f0fb15SPaul Saab else if (bpos == NULL_POSITION) 273a5f0fb15SPaul Saab return (pipe_data(cmd, tpos, bpos)); 274a5f0fb15SPaul Saab else 275a5f0fb15SPaul Saab return (pipe_data(cmd, tpos, mpos)); 276a5f0fb15SPaul Saab } 277a5f0fb15SPaul Saab 278a5f0fb15SPaul Saab /* 279a5f0fb15SPaul Saab * Create a pipe to the given shell command. 280a5f0fb15SPaul Saab * Feed it the file contents between the positions spos and epos. 281a5f0fb15SPaul Saab */ 282a5f0fb15SPaul Saab public int 283a5f0fb15SPaul Saab pipe_data(cmd, spos, epos) 284a5f0fb15SPaul Saab char *cmd; 285a5f0fb15SPaul Saab POSITION spos; 286a5f0fb15SPaul Saab POSITION epos; 287a5f0fb15SPaul Saab { 288a5f0fb15SPaul Saab register FILE *f; 289a5f0fb15SPaul Saab register int c; 290a5f0fb15SPaul Saab extern FILE *popen(); 291a5f0fb15SPaul Saab 292a5f0fb15SPaul Saab /* 293a5f0fb15SPaul Saab * This is structured much like lsystem(). 294a5f0fb15SPaul Saab * Since we're running a shell program, we must be careful 295a5f0fb15SPaul Saab * to perform the necessary deinitialization before running 296a5f0fb15SPaul Saab * the command, and reinitialization after it. 297a5f0fb15SPaul Saab */ 298a5f0fb15SPaul Saab if (ch_seek(spos) != 0) 299a5f0fb15SPaul Saab { 300a5f0fb15SPaul Saab error("Cannot seek to start position", NULL_PARG); 301a5f0fb15SPaul Saab return (-1); 302a5f0fb15SPaul Saab } 303a5f0fb15SPaul Saab 304a5f0fb15SPaul Saab if ((f = popen(cmd, "w")) == NULL) 305a5f0fb15SPaul Saab { 306a5f0fb15SPaul Saab error("Cannot create pipe", NULL_PARG); 307a5f0fb15SPaul Saab return (-1); 308a5f0fb15SPaul Saab } 309a5f0fb15SPaul Saab clear_bot(); 310a5f0fb15SPaul Saab putstr("!"); 311a5f0fb15SPaul Saab putstr(cmd); 312a5f0fb15SPaul Saab putstr("\n"); 313a5f0fb15SPaul Saab 314a5f0fb15SPaul Saab deinit(); 315a5f0fb15SPaul Saab flush(); 316a5f0fb15SPaul Saab raw_mode(0); 317a5f0fb15SPaul Saab init_signals(0); 318a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 319a5f0fb15SPaul Saab close_getchr(); 320a5f0fb15SPaul Saab #endif 321a5f0fb15SPaul Saab #ifdef SIGPIPE 322a5f0fb15SPaul Saab LSIGNAL(SIGPIPE, SIG_IGN); 323a5f0fb15SPaul Saab #endif 324a5f0fb15SPaul Saab 325a5f0fb15SPaul Saab c = EOI; 326a5f0fb15SPaul Saab while (epos == NULL_POSITION || spos++ <= epos) 327a5f0fb15SPaul Saab { 328a5f0fb15SPaul Saab /* 329a5f0fb15SPaul Saab * Read a character from the file and give it to the pipe. 330a5f0fb15SPaul Saab */ 331a5f0fb15SPaul Saab c = ch_forw_get(); 332a5f0fb15SPaul Saab if (c == EOI) 333a5f0fb15SPaul Saab break; 334a5f0fb15SPaul Saab if (putc(c, f) == EOF) 335a5f0fb15SPaul Saab break; 336a5f0fb15SPaul Saab } 337a5f0fb15SPaul Saab 338a5f0fb15SPaul Saab /* 339a5f0fb15SPaul Saab * Finish up the last line. 340a5f0fb15SPaul Saab */ 341a5f0fb15SPaul Saab while (c != '\n' && c != EOI ) 342a5f0fb15SPaul Saab { 343a5f0fb15SPaul Saab c = ch_forw_get(); 344a5f0fb15SPaul Saab if (c == EOI) 345a5f0fb15SPaul Saab break; 346a5f0fb15SPaul Saab if (putc(c, f) == EOF) 347a5f0fb15SPaul Saab break; 348a5f0fb15SPaul Saab } 349a5f0fb15SPaul Saab 350a5f0fb15SPaul Saab pclose(f); 351a5f0fb15SPaul Saab 352a5f0fb15SPaul Saab #ifdef SIGPIPE 353a5f0fb15SPaul Saab LSIGNAL(SIGPIPE, SIG_DFL); 354a5f0fb15SPaul Saab #endif 355a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 356a5f0fb15SPaul Saab open_getchr(); 357a5f0fb15SPaul Saab #endif 358a5f0fb15SPaul Saab init_signals(1); 359a5f0fb15SPaul Saab raw_mode(1); 360a5f0fb15SPaul Saab init(); 361a5f0fb15SPaul Saab screen_trashed = 1; 362a5f0fb15SPaul Saab #if defined(SIGWINCH) || defined(SIGWIND) 363a5f0fb15SPaul Saab /* {{ Probably don't need this here. }} */ 364a5f0fb15SPaul Saab winch(0); 365a5f0fb15SPaul Saab #endif 366a5f0fb15SPaul Saab return (0); 367a5f0fb15SPaul Saab } 368a5f0fb15SPaul Saab 369a5f0fb15SPaul Saab #endif 370a5f0fb15SPaul Saab 371a5f0fb15SPaul Saab #ifdef _OSK 372a5f0fb15SPaul Saab /* 373a5f0fb15SPaul Saab * Popen, and Pclose, for OS-9. 374a5f0fb15SPaul Saab * 375a5f0fb15SPaul Saab * Based on code copyright (c) 1988 by Wolfgang Ocker, Puchheim, 376a5f0fb15SPaul Saab * Ulli Dessauer, Germering and 377a5f0fb15SPaul Saab * Reimer Mellin, Muenchen 378a5f0fb15SPaul Saab * (W-Germany) 379a5f0fb15SPaul Saab * 380a5f0fb15SPaul Saab * These functions can be copied and distributed freely for any 381a5f0fb15SPaul Saab * non-commercial purposes. It can only be incorporated into 382a5f0fb15SPaul Saab * commercial software with the written permission of the authors. 383a5f0fb15SPaul Saab * 384a5f0fb15SPaul Saab * TOP-specific code stripped out and adapted for less by M.Gregorie, 1996 385a5f0fb15SPaul Saab * 386a5f0fb15SPaul Saab * address: Wolfgang Ocker 387a5f0fb15SPaul Saab * Lochhauserstrasse 35a 388a5f0fb15SPaul Saab * D-8039 Puchheim 389a5f0fb15SPaul Saab * West Germany 390a5f0fb15SPaul Saab * 391a5f0fb15SPaul Saab * e-mail: weo@altger.UUCP, ud@altger.UUCP, ram@altger.UUCP 392a5f0fb15SPaul Saab * pyramid!tmpmbx!recco!weo 393a5f0fb15SPaul Saab * pyramid!tmpmbx!nitmar!ud 394a5f0fb15SPaul Saab * pyramid!tmpmbx!ramsys!ram 395a5f0fb15SPaul Saab * 396a5f0fb15SPaul Saab * Martin Gregorie 397a5f0fb15SPaul Saab * 10 Sadlers Mead 398a5f0fb15SPaul Saab * Harlow 399a5f0fb15SPaul Saab * Essex, CM18 6HG 400a5f0fb15SPaul Saab * U.K. 401a5f0fb15SPaul Saab * 402a5f0fb15SPaul Saab * gregorie@logica.com 403a5f0fb15SPaul Saab */ 404a5f0fb15SPaul Saab #include <strings.h> 405a5f0fb15SPaul Saab #include <errno.h> 406a5f0fb15SPaul Saab extern char **environ; 407a5f0fb15SPaul Saab extern char *getenv(); 408a5f0fb15SPaul Saab extern int os9forkc(); 409a5f0fb15SPaul Saab static int pids[_NFILE] = { 0, 0, 0, 0, 0, 0, 0, 0, 410a5f0fb15SPaul Saab 0, 0, 0, 0, 0, 0, 0, 0, 411a5f0fb15SPaul Saab 0, 0, 0, 0, 0, 0, 0, 0, 412a5f0fb15SPaul Saab 0, 0, 0, 0, 0, 0, 0, 0 }; 413a5f0fb15SPaul Saab /* 414a5f0fb15SPaul Saab * p o p e n 415a5f0fb15SPaul Saab */ 416a5f0fb15SPaul Saab FILE *popen(name, mode) 417a5f0fb15SPaul Saab char *name; 418a5f0fb15SPaul Saab char *mode; 419a5f0fb15SPaul Saab { 420a5f0fb15SPaul Saab int fd, fd2, fdsav, pid; 421a5f0fb15SPaul Saab static char *argv[] = {NULL, NULL, NULL }; 422a5f0fb15SPaul Saab static char cmd[200]; 423a5f0fb15SPaul Saab static char cmd_path[200]; 424a5f0fb15SPaul Saab char *cp; 425a5f0fb15SPaul Saab char *shell; 426a5f0fb15SPaul Saab FILE *r; 427a5f0fb15SPaul Saab if ((shell = getenv("SHELL")) == NULL) 428a5f0fb15SPaul Saab return(NULL); 429a5f0fb15SPaul Saab cp = name; 430a5f0fb15SPaul Saab while (*cp == ' ') 431a5f0fb15SPaul Saab cp++; 432a5f0fb15SPaul Saab strcpy(cmd_path, cp); 433a5f0fb15SPaul Saab if (cp = index(cmd_path, ' ')) 434a5f0fb15SPaul Saab *cp++ = '\0'; 435a5f0fb15SPaul Saab strcpy(cmd, "ex "); 436a5f0fb15SPaul Saab strcat(cmd, cmd_path); 437a5f0fb15SPaul Saab if (cp) 438a5f0fb15SPaul Saab { 439a5f0fb15SPaul Saab strcat(cmd, " "); 440a5f0fb15SPaul Saab strcat(cmd, cp); 441a5f0fb15SPaul Saab } 442a5f0fb15SPaul Saab argv[0] = shell; 443a5f0fb15SPaul Saab argv[1] = cmd; 444a5f0fb15SPaul Saab /* 445a5f0fb15SPaul Saab mode is "r" (stdout) or "w" (stdin) 446a5f0fb15SPaul Saab */ 447a5f0fb15SPaul Saab switch(mode[0]) 448a5f0fb15SPaul Saab { 449a5f0fb15SPaul Saab case 'w': fd = 0; 450a5f0fb15SPaul Saab break; 451a5f0fb15SPaul Saab case 'r': fd = 1; 452a5f0fb15SPaul Saab break; 453a5f0fb15SPaul Saab default: return(NULL); 454a5f0fb15SPaul Saab } 455a5f0fb15SPaul Saab if (fd == 1) 456a5f0fb15SPaul Saab fflush(stdout); 457a5f0fb15SPaul Saab fdsav = dup(fd); 458a5f0fb15SPaul Saab close(fd); 459a5f0fb15SPaul Saab 460a5f0fb15SPaul Saab creat("/pipe", S_IWRITE+S_IREAD); 461a5f0fb15SPaul Saab pid = os9exec(os9forkc, argv[0], argv, environ, 0, 0, 3); 462a5f0fb15SPaul Saab fd2 = dup(fd); 463a5f0fb15SPaul Saab close(fd); 464a5f0fb15SPaul Saab dup(fdsav); 465a5f0fb15SPaul Saab close(fdsav); 466a5f0fb15SPaul Saab if (pid > 0) 467a5f0fb15SPaul Saab { 468a5f0fb15SPaul Saab pids[fd2] = pid; 469a5f0fb15SPaul Saab r = fdopen(fd2, mode); 470a5f0fb15SPaul Saab } 471a5f0fb15SPaul Saab else 472a5f0fb15SPaul Saab { 473a5f0fb15SPaul Saab close(fd2); 474a5f0fb15SPaul Saab r = NULL; 475a5f0fb15SPaul Saab } 476a5f0fb15SPaul Saab return(r); 477a5f0fb15SPaul Saab } 478a5f0fb15SPaul Saab 479a5f0fb15SPaul Saab /* 480a5f0fb15SPaul Saab * p c l o s e 481a5f0fb15SPaul Saab */ 482a5f0fb15SPaul Saab int pclose(fp) 483a5f0fb15SPaul Saab FILE *fp; 484a5f0fb15SPaul Saab { 485a5f0fb15SPaul Saab unsigned int status; 486a5f0fb15SPaul Saab int pid; 487a5f0fb15SPaul Saab int fd, 488a5f0fb15SPaul Saab i; 489a5f0fb15SPaul Saab fd = fileno(fp); 490a5f0fb15SPaul Saab if (pids[fd] == 0) 491a5f0fb15SPaul Saab return(-1); 492a5f0fb15SPaul Saab fflush(fp); 493a5f0fb15SPaul Saab fclose(fp); 494a5f0fb15SPaul Saab while ((pid = wait(&status)) != -1) 495a5f0fb15SPaul Saab if (pid == pids[fd]) 496a5f0fb15SPaul Saab break; 497a5f0fb15SPaul Saab else 498a5f0fb15SPaul Saab for (i = 0; i < _NFILE; i++) 499a5f0fb15SPaul Saab if (pids[i] == pid) 500a5f0fb15SPaul Saab { 501a5f0fb15SPaul Saab pids[i] = 0; 502a5f0fb15SPaul Saab break; 503a5f0fb15SPaul Saab } 504a5f0fb15SPaul Saab if (pid == -1) 505a5f0fb15SPaul Saab status = -1; 506a5f0fb15SPaul Saab pids[fd] = 0; 507a5f0fb15SPaul Saab return(status); 508a5f0fb15SPaul Saab } 509a5f0fb15SPaul Saab #endif /* _OSK */ 510