Annotation of 43BSDReno/usr.bin/wall/ttymsg.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1989 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  */
                     17: 
                     18: #ifndef lint
                     19: static char sccsid[] = "@(#)ttymsg.c   5.5 (Berkeley) 6/29/90";
                     20: #endif /* not lint */
                     21: 
                     22: #include <sys/types.h>
                     23: #include <sys/uio.h>
                     24: #include <sys/file.h>
                     25: #include <sys/signal.h>
                     26: #include <dirent.h>
                     27: #include <errno.h>
                     28: #include <paths.h>
                     29: #include <stdio.h>
                     30: 
                     31: /*
                     32:  * display the contents of a uio structure on a terminal.  Used by
                     33:  * wall(1) and syslogd(8).  Forks and finishes in child if write
                     34:  * would block, waiting at most five minutes.
                     35:  * Returns pointer to error string on unexpected error;
                     36:  * string is not newline-terminated.  Various "normal" errors
                     37:  * are ignored (exclusive-use, lack of permission, etc.).
                     38:  */
                     39: char *
                     40: ttymsg(iov, iovcnt, line)
                     41:        struct iovec *iov;
                     42:        int iovcnt;
                     43:        char *line;
                     44: {
                     45:        extern int errno;
                     46:        static char device[MAXNAMLEN] = _PATH_DEV;
                     47:        static char errbuf[1024];
                     48:        register int cnt, fd, left, wret;
                     49:        char *strcpy(), *strerror();
                     50:        struct iovec localiov[6];
                     51:        int forked = 0;
                     52: 
                     53:        if (iovcnt > 6)
                     54:                return ("too many iov's (change code in wall/ttymsg.c)");
                     55:        /*
                     56:         * open will fail on slip lines or exclusive-use lines
                     57:         * if not running as root; not an error.
                     58:         */
                     59:        (void) strcpy(device + sizeof(_PATH_DEV) - 1, line);
                     60:        if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) {
                     61:                if (errno != EBUSY && errno != EACCES) {
                     62:                        (void) sprintf(errbuf, "open %s: %s", device,
                     63:                            strerror(errno));
                     64:                        return (errbuf);
                     65:                } else
                     66:                        return (NULL);
                     67:        }
                     68: 
                     69:        for (cnt = left = 0; cnt < iovcnt; ++cnt)
                     70:                left += iov[cnt].iov_len;
                     71: 
                     72:        for (;;) {
                     73:                if ((wret = writev(fd, iov, iovcnt)) < 0) {
                     74:                        if (errno == EWOULDBLOCK) {
                     75:                                int off = 0;
                     76:                                int cpid;
                     77: 
                     78:                                if (forked) {
                     79:                                        (void) close(fd);
                     80:                                        /* return ("already forked"); */
                     81:                                        /* "can't happen" */
                     82:                                        exit(1);
                     83:                                }
                     84:                                cpid = fork();
                     85:                                if (cpid < 0) {
                     86:                                        (void) sprintf(errbuf, "can't fork: %s",
                     87:                                                strerror(errno));
                     88:                                        (void) close(fd);
                     89:                                        return (errbuf);
                     90:                                }
                     91:                                if (cpid) {     /* parent */
                     92:                                        (void) close(fd);
                     93:                                        return (NULL);
                     94:                                }
                     95:                                forked++;
                     96:                                /* wait at most 5 minutes */
                     97:                                (void) signal(SIGALRM, SIG_DFL);
                     98:                                (void) signal(SIGTERM, SIG_DFL); /* XXX */
                     99:                                (void) sigsetmask(0);
                    100:                                (void) alarm((u_int)(60 * 5));
                    101:                                (void) fcntl(fd, FNDELAY, &off);
                    102:                                continue;
                    103:                        } else {
                    104:                                /*
                    105:                                 * we get ENODEV on a slip line if we're
                    106:                                 * running as root, and EIO if the line
                    107:                                 * just went away
                    108:                                 */
                    109:                                if (errno == ENODEV || errno == EIO)
                    110:                                        break;
                    111:                                (void) sprintf(errbuf, "writing %s: %s",
                    112:                                    device, strerror(errno));
                    113:                                (void) close(fd);
                    114:                                return (errbuf);
                    115:                        }
                    116:                } 
                    117:                if (wret < left) {
                    118:                        left -= wret;
                    119:                        if (iov != localiov) {
                    120:                                bcopy(iov, localiov, 
                    121:                                        iovcnt * sizeof (struct iovec));
                    122:                                iov = localiov;
                    123:                        }
                    124:                        for (cnt = 0; wret >= iov->iov_len; ++cnt) {
                    125:                                wret -= iov->iov_len;
                    126:                                ++iov;
                    127:                                --iovcnt;
                    128:                        }
                    129:                        if (wret) {
                    130:                                iov->iov_base += wret;
                    131:                                iov->iov_len -= wret;
                    132:                        }
                    133:                } else
                    134:                        break;
                    135:        }
                    136:        if (forked)
                    137:                exit(0);
                    138:        (void) close(fd);
                    139:        return (NULL);
                    140: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.