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

Annotation of src/usr.bin/more/os.c, Revision 1.1

1.1     ! deraadt     1: /*
        !             2:  * Copyright (c) 1988 Mark Nudleman
        !             3:  * Copyright (c) 1988 Regents of the University of California.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  * 3. All advertising materials mentioning features or use of this software
        !            15:  *    must display the following acknowledgement:
        !            16:  *     This product includes software developed by the University of
        !            17:  *     California, Berkeley and its contributors.
        !            18:  * 4. Neither the name of the University nor the names of its contributors
        !            19:  *    may be used to endorse or promote products derived from this software
        !            20:  *    without specific prior written permission.
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            32:  * SUCH DAMAGE.
        !            33:  */
        !            34:
        !            35: #ifndef lint
        !            36: /* from: static char sccsid[] = "@(#)os.c      5.12 (Berkeley) 3/1/91"; */
        !            37: static char *rcsid = "$Id: os.c,v 1.3 1994/12/24 17:17:10 cgd Exp $";
        !            38: #endif /* not lint */
        !            39:
        !            40: /*
        !            41:  * Operating system dependent routines.
        !            42:  *
        !            43:  * Most of the stuff in here is based on Unix, but an attempt
        !            44:  * has been made to make things work on other operating systems.
        !            45:  * This will sometimes result in a loss of functionality, unless
        !            46:  * someone rewrites code specifically for the new operating system.
        !            47:  *
        !            48:  * The makefile provides defines to decide whether various
        !            49:  * Unix features are present.
        !            50:  */
        !            51:
        !            52: #include <sys/param.h>
        !            53: #include <sys/stat.h>
        !            54: #include <sys/file.h>
        !            55: #include <signal.h>
        !            56: #include <setjmp.h>
        !            57: #include <stdio.h>
        !            58: #include <string.h>
        !            59: #include <less.h>
        !            60: #include "pathnames.h"
        !            61:
        !            62: int reading;
        !            63:
        !            64: extern int screen_trashed;
        !            65:
        !            66: static jmp_buf read_label;
        !            67:
        !            68: /*
        !            69:  * Pass the specified command to a shell to be executed.
        !            70:  * Like plain "system()", but handles resetting terminal modes, etc.
        !            71:  */
        !            72: lsystem(cmd)
        !            73:        char *cmd;
        !            74: {
        !            75:        int inp;
        !            76:        char cmdbuf[256];
        !            77:        char *shell, *getenv();
        !            78:
        !            79:        /*
        !            80:         * Print the command which is to be executed,
        !            81:         * unless the command starts with a "-".
        !            82:         */
        !            83:        if (cmd[0] == '-')
        !            84:                cmd++;
        !            85:        else
        !            86:        {
        !            87:                lower_left();
        !            88:                clear_eol();
        !            89:                putstr("!");
        !            90:                putstr(cmd);
        !            91:                putstr("\n");
        !            92:        }
        !            93:
        !            94:        /*
        !            95:         * De-initialize the terminal and take out of raw mode.
        !            96:         */
        !            97:        deinit();
        !            98:        flush();
        !            99:        raw_mode(0);
        !           100:
        !           101:        /*
        !           102:         * Restore signals to their defaults.
        !           103:         */
        !           104:        init_signals(0);
        !           105:
        !           106:        /*
        !           107:         * Force standard input to be the terminal, "/dev/tty",
        !           108:         * even if less's standard input is coming from a pipe.
        !           109:         */
        !           110:        inp = dup(0);
        !           111:        (void)close(0);
        !           112:        if (open(_PATH_TTY, O_RDONLY, 0) < 0)
        !           113:                (void)dup(inp);
        !           114:
        !           115:        /*
        !           116:         * Pass the command to the system to be executed.
        !           117:         * If we have a SHELL environment variable, use
        !           118:         * <$SHELL -c "command"> instead of just <command>.
        !           119:         * If the command is empty, just invoke a shell.
        !           120:         */
        !           121:        if ((shell = getenv("SHELL")) != NULL && *shell != '\0')
        !           122:        {
        !           123:                if (*cmd == '\0')
        !           124:                        cmd = shell;
        !           125:                else
        !           126:                {
        !           127:                        (void)sprintf(cmdbuf, "%s -c \"%s\"", shell, cmd);
        !           128:                        cmd = cmdbuf;
        !           129:                }
        !           130:        }
        !           131:        if (*cmd == '\0')
        !           132:                cmd = "sh";
        !           133:
        !           134:        (void)system(cmd);
        !           135:
        !           136:        /*
        !           137:         * Restore standard input, reset signals, raw mode, etc.
        !           138:         */
        !           139:        (void)close(0);
        !           140:        (void)dup(inp);
        !           141:        (void)close(inp);
        !           142:
        !           143:        init_signals(1);
        !           144:        raw_mode(1);
        !           145:        init();
        !           146:        screen_trashed = 1;
        !           147: #if defined(SIGWINCH) || defined(SIGWIND)
        !           148:        /*
        !           149:         * Since we were ignoring window change signals while we executed
        !           150:         * the system command, we must assume the window changed.
        !           151:         */
        !           152:        winch();
        !           153: #endif
        !           154: }
        !           155:
        !           156: /*
        !           157:  * Like read() system call, but is deliberately interruptable.
        !           158:  * A call to intread() from a signal handler will interrupt
        !           159:  * any pending iread().
        !           160:  */
        !           161: iread(fd, buf, len)
        !           162:        int fd;
        !           163:        char *buf;
        !           164:        int len;
        !           165: {
        !           166:        register int n;
        !           167:
        !           168:        if (setjmp(read_label))
        !           169:                /*
        !           170:                 * We jumped here from intread.
        !           171:                 */
        !           172:                return (READ_INTR);
        !           173:
        !           174:        flush();
        !           175:        reading = 1;
        !           176:        n = read(fd, buf, len);
        !           177:        reading = 0;
        !           178:        if (n < 0)
        !           179:                return (-1);
        !           180:        return (n);
        !           181: }
        !           182:
        !           183: intread()
        !           184: {
        !           185:        (void)sigsetmask(0L);
        !           186:        longjmp(read_label, 1);
        !           187: }
        !           188:
        !           189: /*
        !           190:  * Expand a filename, substituting any environment variables, etc.
        !           191:  * The implementation of this is necessarily very operating system
        !           192:  * dependent.  This implementation is unabashedly only for Unix systems.
        !           193:  */
        !           194: FILE *popen();
        !           195:
        !           196: char *
        !           197: glob(filename)
        !           198:        char *filename;
        !           199: {
        !           200:        FILE *f;
        !           201:        char *p;
        !           202:        int ch;
        !           203:        char *cmd, *malloc(), *getenv();
        !           204:        static char buffer[MAXPATHLEN];
        !           205:
        !           206:        if (filename[0] == '#')
        !           207:                return (filename);
        !           208:
        !           209:        /*
        !           210:         * We get the shell to expand the filename for us by passing
        !           211:         * an "echo" command to the shell and reading its output.
        !           212:         */
        !           213:        p = getenv("SHELL");
        !           214:        if (p == NULL || *p == '\0')
        !           215:        {
        !           216:                /*
        !           217:                 * Read the output of <echo filename>.
        !           218:                 */
        !           219:                cmd = malloc((u_int)(strlen(filename)+8));
        !           220:                if (cmd == NULL)
        !           221:                        return (filename);
        !           222:                (void)sprintf(cmd, "echo \"%s\"", filename);
        !           223:        } else
        !           224:        {
        !           225:                /*
        !           226:                 * Read the output of <$SHELL -c "echo filename">.
        !           227:                 */
        !           228:                cmd = malloc((u_int)(strlen(p)+12));
        !           229:                if (cmd == NULL)
        !           230:                        return (filename);
        !           231:                (void)sprintf(cmd, "%s -c \"echo %s\"", p, filename);
        !           232:        }
        !           233:
        !           234:        if ((f = popen(cmd, "r")) == NULL)
        !           235:                return (filename);
        !           236:        free(cmd);
        !           237:
        !           238:        for (p = buffer;  p < &buffer[sizeof(buffer)-1];  p++)
        !           239:        {
        !           240:                if ((ch = getc(f)) == '\n' || ch == EOF)
        !           241:                        break;
        !           242:                *p = ch;
        !           243:        }
        !           244:        *p = '\0';
        !           245:        (void)pclose(f);
        !           246:        return(buffer);
        !           247: }
        !           248:
        !           249: char *
        !           250: bad_file(filename, message, len)
        !           251:        char *filename, *message;
        !           252:        u_int len;
        !           253: {
        !           254:        extern int errno;
        !           255:        struct stat statbuf;
        !           256:        char *strcat(), *strerror();
        !           257:
        !           258:        if (stat(filename, &statbuf) < 0) {
        !           259:                (void)sprintf(message, "%s: %s", filename, strerror(errno));
        !           260:                return(message);
        !           261:        }
        !           262:        if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
        !           263:                static char is_dir[] = " is a directory";
        !           264:
        !           265:                strtcpy(message, filename, (int)(len-sizeof(is_dir)-1));
        !           266:                (void)strcat(message, is_dir);
        !           267:                return(message);
        !           268:        }
        !           269:        return((char *)NULL);
        !           270: }
        !           271:
        !           272: /*
        !           273:  * Copy a string, truncating to the specified length if necessary.
        !           274:  * Unlike strncpy(), the resulting string is guaranteed to be null-terminated.
        !           275:  */
        !           276: strtcpy(to, from, len)
        !           277:        char *to, *from;
        !           278:        int len;
        !           279: {
        !           280:        char *strncpy();
        !           281:
        !           282:        (void)strncpy(to, from, (int)len);
        !           283:        to[len-1] = '\0';
        !           284: }
        !           285: