diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2003-04-13 18:26:27 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2003-04-13 18:26:27 +0000 |
commit | 5569f8a6b6c831077f77d24e2c23d2e2d41fb95f (patch) | |
tree | b79fe763d81906631382fbdc80f3b42a44b6c668 /usr.bin/less/lsystem.c | |
parent | 6b9d6b99a4fdda2ee6d9a30dec452d8202fb2017 (diff) |
Merge in less-381 w/ local changes and remove obsolete files.
Diffstat (limited to 'usr.bin/less/lsystem.c')
-rw-r--r-- | usr.bin/less/lsystem.c | 314 |
1 files changed, 261 insertions, 53 deletions
diff --git a/usr.bin/less/lsystem.c b/usr.bin/less/lsystem.c index 9e39a8ed1fe..8fa4683215e 100644 --- a/usr.bin/less/lsystem.c +++ b/usr.bin/less/lsystem.c @@ -1,29 +1,11 @@ -/* $OpenBSD: lsystem.c,v 1.4 2003/04/06 23:38:07 deraadt Exp $ */ - /* - * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman - * All rights reserved. + * Copyright (C) 1984-2002 Mark Nudelman * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice in the documentation and/or other materials provided with - * the distribution. + * You may distribute under the terms of either the GNU General Public + * License or the Less License, as specified in the README file. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * For more information about less, or for information on how to + * contact the author, see the README file. */ @@ -32,12 +14,18 @@ * Necessarily very OS dependent. */ -#include <signal.h> #include "less.h" +#include <signal.h> #include "position.h" -#if MSOFTC +#if MSDOS_COMPILER #include <dos.h> +#ifdef _MSC_VER +#include <direct.h> +#define setdisk(n) _chdrive((n)+1) +#else +#include <dir.h> +#endif #endif extern int screen_trashed; @@ -51,16 +39,19 @@ extern IFILE curr_ifile; * Like plain "system()", but handles resetting terminal modes, etc. */ public void -lsystem(cmd) +lsystem(cmd, donemsg) char *cmd; + char *donemsg; { - int inp; -#if MSOFTC || OS2 - int inp2; + register int inp; +#if HAVE_SHELL + register char *shell; + register char *p; #endif - char *shell; - char *p; IFILE save_ifile; +#if MSDOS_COMPILER + char cwd[FILENAME_MAX+1]; +#endif /* * Print the command which is to be executed, @@ -76,10 +67,21 @@ lsystem(cmd) putstr("\n"); } +#if MSDOS_COMPILER + /* + * Working directory is global on MSDOS. + * The child might change the working directory, so we + * must save and restore CWD across calls to "system", + * or else we won't find our file when we return and + * try to "reedit_ifile" it. + */ + getcwd(cwd, FILENAME_MAX); +#endif + /* * Close the current input file. */ - save_ifile = curr_ifile; + save_ifile = save_curr_ifile(); (void) edit_ifile(NULL_IFILE); /* @@ -88,12 +90,16 @@ lsystem(cmd) deinit(); flush(); /* Make sure the deinit chars get out */ raw_mode(0); +#if MSDOS_COMPILER==WIN32C + close_getchr(); +#endif /* * Restore signals to their defaults. */ init_signals(0); +#if HAVE_DUP /* * Force standard input to be the user's terminal * (the normal standard input), even if less's standard input @@ -101,8 +107,14 @@ lsystem(cmd) */ inp = dup(0); close(0); - if (OPEN_TTYIN() < 0) +#if OS2 + /* The __open() system call translates "/dev/tty" to "con". */ + if (__open("/dev/tty", OPEN_READ) < 0) +#else + if (open("/dev/tty", OPEN_READ) < 0) +#endif dup(inp); +#endif /* * Pass the command to the system to be executed. @@ -112,15 +124,21 @@ lsystem(cmd) */ #if HAVE_SHELL p = NULL; - if ((shell = getenv("SHELL")) != NULL && *shell != '\0') + if ((shell = lgetenv("SHELL")) != NULL && *shell != '\0') { if (*cmd == '\0') p = save(shell); else { - size_t l = strlen(shell) + strlen(cmd) + 7; - p = (char *) ecalloc(l, sizeof(char)); - snprintf(p, l, "%s -c \"%s\"", shell, cmd); + char *esccmd = shell_quote(cmd); + if (esccmd != NULL) + { + size_t len = strlen(shell) + strlen(esccmd) + 5; + p = (char *) ecalloc(len, sizeof(char)); + snprintf(p, len, "%s %s %s", shell, + shell_coption(), esccmd); + free(esccmd); + } } } if (p == NULL) @@ -130,34 +148,76 @@ lsystem(cmd) else p = save(cmd); } - system(p); free(p); #else -#if OS2 - if (*cmd == '\0') - cmd = "cmd.exe"; -#endif +#if MSDOS_COMPILER==DJGPPC + /* + * Make stdin of the child be in cooked mode. + */ + setmode(0, O_TEXT); + /* + * We don't need to catch signals of the child (it + * also makes trouble with some DPMI servers). + */ + __djgpp_exception_toggle(); + system(cmd); + __djgpp_exception_toggle(); +#else system(cmd); #endif +#endif +#if HAVE_DUP /* * Restore standard input, reset signals, raw mode, etc. */ close(0); dup(inp); close(inp); +#endif +#if MSDOS_COMPILER==WIN32C + open_getchr(); +#endif init_signals(1); raw_mode(1); + if (donemsg != NULL) + { + putstr(donemsg); + putstr(" (press RETURN)"); + get_return(); + putchr('\n'); + flush(); + } init(); screen_trashed = 1; +#if MSDOS_COMPILER + /* + * Restore the previous directory (possibly + * changed by the child program we just ran). + */ + chdir(cwd); +#if MSDOS_COMPILER != DJGPPC + /* + * Some versions of chdir() don't change to the drive + * which is part of CWD. (DJGPP does this in chdir.) + */ + if (cwd[1] == ':') + { + if (cwd[0] >= 'a' && cwd[0] <= 'z') + setdisk(cwd[0] - 'a'); + else if (cwd[0] >= 'A' && cwd[0] <= 'Z') + setdisk(cwd[0] - 'A'); + } +#endif +#endif + /* * Reopen the current input file. */ - if (edit_ifile(save_ifile)) - quit(QUIT_ERROR); + reedit_ifile(save_ifile); #if defined(SIGWINCH) || defined(SIGWIND) /* @@ -179,10 +239,12 @@ lsystem(cmd) * The section to be piped is the section "between" the current * position and the position marked by the given letter. * - * The "current" position means the top line displayed if the mark - * is after the current screen, or the bottom line displayed if - * the mark is before the current screen. - * If the mark is on the current screen, the whole screen is displayed. + * If the mark is after the current screen, the section between + * the top line displayed and the mark is piped. + * If the mark is before the current screen, the section between + * the mark and the bottom line displayed is piped. + * If the mark is on the current screen, or if the mark is ".", + * the whole current screen is piped. */ public int pipe_mark(c, cmd) @@ -207,7 +269,7 @@ pipe_mark(c, cmd) if (c == '.') return (pipe_data(cmd, tpos, bpos)); else if (mpos <= tpos) - return (pipe_data(cmd, mpos, tpos)); + return (pipe_data(cmd, mpos, bpos)); else if (bpos == NULL_POSITION) return (pipe_data(cmd, tpos, bpos)); else @@ -224,8 +286,8 @@ pipe_data(cmd, spos, epos) POSITION spos; POSITION epos; { - FILE *f; - int c; + register FILE *f; + register int c; extern FILE *popen(); /* @@ -254,8 +316,11 @@ pipe_data(cmd, spos, epos) flush(); raw_mode(0); init_signals(0); +#if MSDOS_COMPILER==WIN32C + close_getchr(); +#endif #ifdef SIGPIPE - SIGNAL(SIGPIPE, SIG_IGN); + LSIGNAL(SIGPIPE, SIG_IGN); #endif c = EOI; @@ -286,7 +351,10 @@ pipe_data(cmd, spos, epos) pclose(f); #ifdef SIGPIPE - SIGNAL(SIGPIPE, SIG_DFL); + LSIGNAL(SIGPIPE, SIG_DFL); +#endif +#if MSDOS_COMPILER==WIN32C + open_getchr(); #endif init_signals(1); raw_mode(1); @@ -300,3 +368,143 @@ pipe_data(cmd, spos, epos) } #endif + +#ifdef _OSK +/* + * Popen, and Pclose, for OS-9. + * + * Based on code copyright (c) 1988 by Wolfgang Ocker, Puchheim, + * Ulli Dessauer, Germering and + * Reimer Mellin, Muenchen + * (W-Germany) + * + * These functions can be copied and distributed freely for any + * non-commercial purposes. It can only be incorporated into + * commercial software with the written permission of the authors. + * + * TOP-specific code stripped out and adapted for less by M.Gregorie, 1996 + * + * address: Wolfgang Ocker + * Lochhauserstrasse 35a + * D-8039 Puchheim + * West Germany + * + * e-mail: weo@altger.UUCP, ud@altger.UUCP, ram@altger.UUCP + * pyramid!tmpmbx!recco!weo + * pyramid!tmpmbx!nitmar!ud + * pyramid!tmpmbx!ramsys!ram + * + * Martin Gregorie + * 10 Sadlers Mead + * Harlow + * Essex, CM18 6HG + * U.K. + * + * gregorie@logica.com + */ +#include <strings.h> +#include <errno.h> +extern char **environ; +extern char *getenv(); +extern int os9forkc(); +static int pids[_NFILE] = { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; +/* + * p o p e n + */ +FILE *popen(name, mode) + char *name; + char *mode; +{ + int fd, fd2, fdsav, pid; + static char *argv[] = {NULL, NULL, NULL }; + static char cmd[200]; + static char cmd_path[200]; + char *cp; + char *shell; + FILE *r; + if ((shell = getenv("SHELL")) == NULL) + return(NULL); + cp = name; + while (*cp == ' ') + cp++; + strlcpy(cmd_path, cp, sizeof(cmd_path)); + if (cp = index(cmd_path, ' ')) + *cp++ = '\0'; + strlcpy(cmd, "ex ", sizeof(cmd)); + strlcat(cmd, cmd_path, sizeof(cmd)); + if (cp) + { + strlcat(cmd, " ", sizeof(cmd)); + strlcat(cmd, cp, sizeof(cmd)); + } + argv[0] = shell; + argv[1] = cmd; + /* + mode is "r" (stdout) or "w" (stdin) + */ + switch(mode[0]) + { + case 'w': fd = 0; + break; + case 'r': fd = 1; + break; + default: return(NULL); + } + if (fd == 1) + fflush(stdout); + fdsav = dup(fd); + close(fd); + + creat("/pipe", S_IWRITE+S_IREAD); + pid = os9exec(os9forkc, argv[0], argv, environ, 0, 0, 3); + fd2 = dup(fd); + close(fd); + dup(fdsav); + close(fdsav); + if (pid > 0) + { + pids[fd2] = pid; + r = fdopen(fd2, mode); + } + else + { + close(fd2); + r = NULL; + } + return(r); +} + +/* + * p c l o s e + */ +int pclose(fp) + FILE *fp; +{ + unsigned int status; + int pid; + int fd, + i; + fd = fileno(fp); + if (pids[fd] == 0) + return(-1); + fflush(fp); + fclose(fp); + while ((pid = wait(&status)) != -1) + if (pid == pids[fd]) + break; + else + for (i = 0; i < _NFILE; i++) + if (pids[i] == pid) + { + pids[i] = 0; + break; + } + if (pid == -1) + status = -1; + pids[fd] = 0; + return(status); +} +#endif /* _OSK */ |