[BACK]Return to lsystem.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Annotation of src/usr.bin/less/lsystem.c, Revision 1.2

1.2     ! niklas      1: /*     $OpenBSD$       */
        !             2:
1.1       etheisen    3: /*
                      4:  * Copyright (c) 1984,1985,1989,1994,1995  Mark Nudelman
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice in the documentation and/or other materials provided with
                     14:  *    the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
                     17:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     18:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     19:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
                     20:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     21:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
                     22:  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
                     23:  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     24:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
                     25:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
                     26:  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28:
                     29:
                     30: /*
                     31:  * Routines to execute other programs.
                     32:  * Necessarily very OS dependent.
                     33:  */
                     34:
                     35: #include <signal.h>
                     36: #include "less.h"
                     37: #include "position.h"
                     38:
                     39: #if MSOFTC
                     40: #include <dos.h>
                     41: #endif
                     42:
                     43: extern int screen_trashed;
                     44: extern IFILE curr_ifile;
                     45:
                     46:
                     47: #if HAVE_SYSTEM
                     48:
                     49: /*
                     50:  * Pass the specified command to a shell to be executed.
                     51:  * Like plain "system()", but handles resetting terminal modes, etc.
                     52:  */
                     53:        public void
                     54: lsystem(cmd)
                     55:        char *cmd;
                     56: {
                     57:        register int inp;
                     58: #if MSOFTC || OS2
                     59:        register int inp2;
                     60: #endif
                     61:        register char *shell;
                     62:        register char *p;
                     63:        IFILE save_ifile;
                     64:
                     65:        /*
                     66:         * Print the command which is to be executed,
                     67:         * unless the command starts with a "-".
                     68:         */
                     69:        if (cmd[0] == '-')
                     70:                cmd++;
                     71:        else
                     72:        {
                     73:                clear_bot();
                     74:                putstr("!");
                     75:                putstr(cmd);
                     76:                putstr("\n");
                     77:        }
                     78:
                     79:        /*
                     80:         * Close the current input file.
                     81:         */
                     82:        save_ifile = curr_ifile;
                     83:        (void) edit_ifile(NULL_IFILE);
                     84:
                     85:        /*
                     86:         * De-initialize the terminal and take out of raw mode.
                     87:         */
                     88:        deinit();
                     89:        flush();        /* Make sure the deinit chars get out */
                     90:        raw_mode(0);
                     91:
                     92:        /*
                     93:         * Restore signals to their defaults.
                     94:         */
                     95:        init_signals(0);
                     96:
                     97:        /*
                     98:         * Force standard input to be the user's terminal
                     99:         * (the normal standard input), even if less's standard input
                    100:         * is coming from a pipe.
                    101:         */
                    102:        inp = dup(0);
                    103:        close(0);
                    104:        if (OPEN_TTYIN() < 0)
                    105:                dup(inp);
                    106:
                    107:        /*
                    108:         * Pass the command to the system to be executed.
                    109:         * If we have a SHELL environment variable, use
                    110:         * <$SHELL -c "command"> instead of just <command>.
                    111:         * If the command is empty, just invoke a shell.
                    112:         */
                    113: #if HAVE_SHELL
                    114:        p = NULL;
                    115:        if ((shell = getenv("SHELL")) != NULL && *shell != '\0')
                    116:        {
                    117:                if (*cmd == '\0')
                    118:                        p = save(shell);
                    119:                else
                    120:                {
                    121:                        p = (char *) ecalloc(strlen(shell) + strlen(cmd) + 7,
                    122:                                        sizeof(char));
                    123:                        sprintf(p, "%s -c \"%s\"", shell, cmd);
                    124:                }
                    125:        }
                    126:        if (p == NULL)
                    127:        {
                    128:                if (*cmd == '\0')
                    129:                        p = save("sh");
                    130:                else
                    131:                        p = save(cmd);
                    132:        }
                    133:
                    134:        system(p);
                    135:        free(p);
                    136: #else
                    137: #if OS2
                    138:        if (*cmd == '\0')
                    139:                cmd = "cmd.exe";
                    140: #endif
                    141:        system(cmd);
                    142: #endif
                    143:
                    144:        /*
                    145:         * Restore standard input, reset signals, raw mode, etc.
                    146:         */
                    147:        close(0);
                    148:        dup(inp);
                    149:        close(inp);
                    150:
                    151:        init_signals(1);
                    152:        raw_mode(1);
                    153:        init();
                    154:        screen_trashed = 1;
                    155:
                    156:        /*
                    157:         * Reopen the current input file.
                    158:         */
                    159:        if (edit_ifile(save_ifile))
                    160:                quit(QUIT_ERROR);
                    161:
                    162: #if defined(SIGWINCH) || defined(SIGWIND)
                    163:        /*
                    164:         * Since we were ignoring window change signals while we executed
                    165:         * the system command, we must assume the window changed.
                    166:         * Warning: this leaves a signal pending (in "sigs"),
                    167:         * so psignals() should be called soon after lsystem().
                    168:         */
                    169:        winch(0);
                    170: #endif
                    171: }
                    172:
                    173: #endif
                    174:
                    175: #if PIPEC
                    176:
                    177: /*
                    178:  * Pipe a section of the input file into the given shell command.
                    179:  * The section to be piped is the section "between" the current
                    180:  * position and the position marked by the given letter.
                    181:  *
                    182:  * The "current" position means the top line displayed if the mark
                    183:  * is after the current screen, or the bottom line displayed if
                    184:  * the mark is before the current screen.
                    185:  * If the mark is on the current screen, the whole screen is displayed.
                    186:  */
                    187:        public int
                    188: pipe_mark(c, cmd)
                    189:        int c;
                    190:        char *cmd;
                    191: {
                    192:        POSITION mpos, tpos, bpos;
                    193:
                    194:        /*
                    195:         * mpos = the marked position.
                    196:         * tpos = top of screen.
                    197:         * bpos = bottom of screen.
                    198:         */
                    199:        mpos = markpos(c);
                    200:        if (mpos == NULL_POSITION)
                    201:                return (-1);
                    202:        tpos = position(TOP);
                    203:        if (tpos == NULL_POSITION)
                    204:                tpos = ch_zero();
                    205:        bpos = position(BOTTOM);
                    206:
                    207:        if (c == '.')
                    208:                return (pipe_data(cmd, tpos, bpos));
                    209:        else if (mpos <= tpos)
                    210:                return (pipe_data(cmd, mpos, tpos));
                    211:        else if (bpos == NULL_POSITION)
                    212:                return (pipe_data(cmd, tpos, bpos));
                    213:        else
                    214:                return (pipe_data(cmd, tpos, mpos));
                    215: }
                    216:
                    217: /*
                    218:  * Create a pipe to the given shell command.
                    219:  * Feed it the file contents between the positions spos and epos.
                    220:  */
                    221:        public int
                    222: pipe_data(cmd, spos, epos)
                    223:        char *cmd;
                    224:        POSITION spos;
                    225:        POSITION epos;
                    226: {
                    227:        register FILE *f;
                    228:        register int c;
                    229:        extern FILE *popen();
                    230:
                    231:        /*
                    232:         * This is structured much like lsystem().
                    233:         * Since we're running a shell program, we must be careful
                    234:         * to perform the necessary deinitialization before running
                    235:         * the command, and reinitialization after it.
                    236:         */
                    237:        if (ch_seek(spos) != 0)
                    238:        {
                    239:                error("Cannot seek to start position", NULL_PARG);
                    240:                return (-1);
                    241:        }
                    242:
                    243:        if ((f = popen(cmd, "w")) == NULL)
                    244:        {
                    245:                error("Cannot create pipe", NULL_PARG);
                    246:                return (-1);
                    247:        }
                    248:        clear_bot();
                    249:        putstr("!");
                    250:        putstr(cmd);
                    251:        putstr("\n");
                    252:
                    253:        deinit();
                    254:        flush();
                    255:        raw_mode(0);
                    256:        init_signals(0);
                    257: #ifdef SIGPIPE
                    258:        SIGNAL(SIGPIPE, SIG_IGN);
                    259: #endif
                    260:
                    261:        c = EOI;
                    262:        while (epos == NULL_POSITION || spos++ <= epos)
                    263:        {
                    264:                /*
                    265:                 * Read a character from the file and give it to the pipe.
                    266:                 */
                    267:                c = ch_forw_get();
                    268:                if (c == EOI)
                    269:                        break;
                    270:                if (putc(c, f) == EOF)
                    271:                        break;
                    272:        }
                    273:
                    274:        /*
                    275:         * Finish up the last line.
                    276:         */
                    277:        while (c != '\n' && c != EOI )
                    278:        {
                    279:                c = ch_forw_get();
                    280:                if (c == EOI)
                    281:                        break;
                    282:                if (putc(c, f) == EOF)
                    283:                        break;
                    284:        }
                    285:
                    286:        pclose(f);
                    287:
                    288: #ifdef SIGPIPE
                    289:        SIGNAL(SIGPIPE, SIG_DFL);
                    290: #endif
                    291:        init_signals(1);
                    292:        raw_mode(1);
                    293:        init();
                    294:        screen_trashed = 1;
                    295: #if defined(SIGWINCH) || defined(SIGWIND)
                    296:        /* {{ Probably don't need this here. }} */
                    297:        winch(0);
                    298: #endif
                    299:        return (0);
                    300: }
                    301:
                    302: #endif