* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)ttymsg.c 8.1 (Berkeley) %G%";
* Display the contents of a uio structure on a terminal. Used by wall(1),
* syslogd(8), and talk(1). Forks and finishes in child if write would block,
* waiting up to tmout seconds. Returns pointer to error string on unexpected
* error; string is not newline-terminated. Various "normal" errors are
* ignored (exclusive-use, lack of permission, etc.).
ttymsg(iov
, iovcnt
, line
, tmout
)
static char device
[MAXNAMLEN
] = _PATH_DEV
;
static char errbuf
[1024];
register int cnt
, fd
, left
, wret
;
struct iovec localiov
[6];
return ("too many iov's (change code in wall/ttymsg.c)");
* open will fail on slip lines or exclusive-use lines
* if not running as root; not an error.
(void) strcpy(device
+ sizeof(_PATH_DEV
) - 1, line
);
if ((fd
= open(device
, O_WRONLY
|O_NONBLOCK
, 0)) < 0) {
if (errno
== EBUSY
|| errno
== EACCES
)
(void) snprintf(errbuf
, sizeof(errbuf
),
"%s: %s", device
, strerror(errno
));
for (cnt
= left
= 0; cnt
< iovcnt
; ++cnt
)
left
+= iov
[cnt
].iov_len
;
wret
= writev(fd
, iov
, iovcnt
);
iovcnt
* sizeof(struct iovec
));
for (cnt
= 0; wret
>= iov
->iov_len
; ++cnt
) {
if (errno
== EWOULDBLOCK
) {
(void) snprintf(errbuf
, sizeof(errbuf
),
"fork: %s", strerror(errno
));
/* wait at most tmout seconds */
(void) signal(SIGALRM
, SIG_DFL
);
(void) signal(SIGTERM
, SIG_DFL
); /* XXX */
(void) alarm((u_int
)tmout
);
(void) fcntl(fd
, O_NONBLOCK
, &off
);
* We get ENODEV on a slip line if we're running as root,
* and EIO if the line just went away.
if (errno
== ENODEV
|| errno
== EIO
)
(void) snprintf(errbuf
, sizeof(errbuf
),
"%s: %s", device
, strerror(errno
));