]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - term-utils/ttymsg.c
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * Modified Sun Mar 12 10:39:22 1995, faith@cs.unc.edu for Linux
37 /* 1999-02-22 Arkadiusz MiĆkiewicz <misiek@pld.ORG.PL>
38 * - added Native Language Support
39 * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
40 * - fixed strerr(errno) in gettext calls
43 #include <sys/types.h>
44 #include <sys/param.h>
57 #include "closestream.h"
58 #include "pathnames.h"
61 #define ERR_BUFLEN (MAXNAMLEN + 1024)
64 * Display the contents of a uio structure on a terminal. Used by wall(1),
65 * syslogd(8), and talkd(8). Forks and finishes in child if write would block,
66 * waiting up to tmout seconds. Returns pointer to error string on unexpected
67 * error; string is not newline-terminated. Various "normal" errors are
68 * ignored (exclusive-use, lack of permission, etc.).
71 ttymsg(struct iovec
*iov
, size_t iovcnt
, char *line
, int tmout
) {
72 static char device
[MAXNAMLEN
];
73 static char errbuf
[ERR_BUFLEN
];
76 struct iovec localiov
[6];
80 if (iovcnt
> ARRAY_SIZE(localiov
)) {
81 snprintf(errbuf
, sizeof(errbuf
), _("internal error: too many iov's"));
85 /* The old code here rejected the line argument when it contained a '/',
86 saying: "A slash may be an attempt to break security...".
87 However, if a user can control the line argument here
88 then he can make this routine write to /dev/hda or /dev/sda
89 already. So, this test was worthless, and these days it is
90 also wrong since people use /dev/pts/xxx. */
92 len
= snprintf(device
, sizeof(device
), "%s%s", _PATH_DEV
, line
);
93 if (len
< 0 || (size_t)len
>= sizeof(device
)) {
94 snprintf(errbuf
, sizeof(errbuf
), _("excessively long line arg"));
99 * open will fail on slip lines or exclusive-use lines
100 * if not running as root; not an error.
102 if ((fd
= open(device
, O_WRONLY
|O_NONBLOCK
, 0)) < 0) {
103 if (errno
== EBUSY
|| errno
== EACCES
)
106 len
= snprintf(errbuf
, sizeof(errbuf
), "%s: %m", device
);
107 if (len
< 0 || (size_t)len
>= sizeof(errbuf
))
108 snprintf(errbuf
, sizeof(errbuf
), _("open failed"));
112 for (cnt
= left
= 0; cnt
< iovcnt
; ++cnt
)
113 left
+= iov
[cnt
].iov_len
;
116 wret
= writev(fd
, iov
, iovcnt
);
117 if (wret
>= (ssize_t
) left
)
121 if (iov
!= localiov
) {
122 memmove(localiov
, iov
,
123 iovcnt
* sizeof(struct iovec
));
126 for (cnt
= 0; wret
>= (ssize_t
) iov
->iov_len
; ++cnt
) {
127 wret
-= iov
->iov_len
;
132 iov
->iov_base
= (char *) iov
->iov_base
+ wret
;
133 iov
->iov_len
-= wret
;
137 if (errno
== EWOULDBLOCK
) {
147 len
= snprintf(errbuf
, sizeof(errbuf
), _("fork: %m"));
148 if (len
< 0 || (size_t)len
>= sizeof(errbuf
))
149 snprintf(errbuf
, sizeof(errbuf
), _("cannot fork"));
153 if (cpid
) { /* parent */
158 /* wait at most tmout seconds */
159 signal(SIGALRM
, SIG_DFL
);
160 signal(SIGTERM
, SIG_DFL
); /* XXX */
161 sigemptyset(&sigmask
);
162 sigprocmask (SIG_SETMASK
, &sigmask
, NULL
);
164 flags
= fcntl(fd
, F_GETFL
);
165 fcntl(flags
, F_SETFL
, (long) (flags
& ~O_NONBLOCK
));
169 * We get ENODEV on a slip line if we're running as root,
170 * and EIO if the line just went away.
172 if (errno
== ENODEV
|| errno
== EIO
)
174 if (close_fd(fd
) != 0)
175 warn(_("write failed: %s"), device
);
179 len
= snprintf(errbuf
, sizeof(errbuf
), "%s: %m", device
);
180 if (len
< 0 || (size_t)len
>= sizeof(errbuf
))
181 snprintf(errbuf
, sizeof(errbuf
),
182 _("%s: BAD ERROR, message is "
183 "far too long"), device
);