python3: update to 3.11.10
[openadk.git] / package / toolbox / src / cat / cat.c
blob442f720738577b42d5dca529ee4810724464eecf
1 /*-
2 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3 * 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
4 * mirabilos <m@mirbsd.org>
6 * Provided that these terms and disclaimer and all copyright notices
7 * are retained or reproduced in an accompanying document, permission
8 * is granted to deal in this work without restriction, including un-
9 * limited rights to use, publicly perform, distribute, sell, modify,
10 * merge, give away, or sublicence.
12 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
13 * the utmost extent permitted by applicable law, neither express nor
14 * implied; without malicious intent or gross negligence. In no event
15 * may a licensor, author or contributor be held liable for indirect,
16 * direct, other damage, loss, or other issues arising in any way out
17 * of dealing in the work, even if advised of the possibility of such
18 * damage or existence of a defect, except proven that it results out
19 * of said person's immediate fault when using the work as intended.
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <signal.h>
25 #include <stdint.h>
26 #include <string.h>
27 #include <unistd.h>
29 #define MKSH_CAT_BUFSIZ 256
31 #ifndef O_BINARY
32 #define O_BINARY 0
33 #endif
35 #define ksh_sigmask(sig) (((sig) < 1 || (sig) > 127) ? 255 : 128 + (sig))
37 static char buf[MKSH_CAT_BUFSIZ];
38 static volatile sig_atomic_t intrsig;
40 static const char Tsynerr[] = "cat: syntax error\n";
41 static const char unkerr_msg[] = "Unknown error";
42 static const char sigint_msg[] = " ...\ncat: Interrupted\n";
44 static void
45 disperr(const char *fn)
47 int e = errno;
49 write(2, "cat: ", 5);
50 write(2, fn, strlen(fn));
51 write(2, ": ", 2);
52 if (strerror_r(e, buf, MKSH_CAT_BUFSIZ))
53 write(2, unkerr_msg, sizeof(unkerr_msg) - 1);
54 else
55 write(2, buf, strlen(buf));
56 write(2, "\n", 1);
59 static void
60 sighandler(int signo __attribute__((__unused__)))
62 intrsig = 1;
65 int
66 main(int argc __attribute__((__unused__)), char *wp[])
68 int fd = 0, rv;
69 ssize_t n, w;
70 const char *fn = "<stdin>";
71 char *cp;
73 ++wp;
74 /* parse options (POSIX demands this) */
75 while ((cp = *wp) && *cp++ == '-') {
76 if (!cp[0])
77 break;
78 if (cp[0] == '-' && !cp[1]) {
79 ++wp;
80 break;
82 while (*cp == 'u')
83 ++cp;
84 if (*cp) {
85 write(2, Tsynerr, sizeof(Tsynerr) - 1);
86 return (1);
88 ++wp;
90 rv = 0;
92 /* catch SIGPIPE */
93 signal(SIGPIPE, SIG_IGN);
95 /* abort on SIGINT */
96 signal(SIGINT, sighandler);
98 do {
99 if (*wp) {
100 fn = *wp++;
101 if (fn[0] == '-' && !fn[1])
102 fd = 0;
103 else if ((fd = open(fn, O_RDONLY | O_BINARY)) < 0) {
104 disperr(fn);
105 rv = 1;
106 continue;
109 while (/* CONSTCOND */ 1) {
110 if ((n = read(fd, (cp = buf), MKSH_CAT_BUFSIZ)) == -1) {
111 if (errno == EINTR) {
112 /* give the user a chance to ^C out */
113 if (intrsig)
114 goto has_intrsig;
115 /* interrupted, try again */
116 continue;
118 /* an error occured during reading */
119 disperr(fn);
120 rv = 1;
121 break;
122 } else if (n == 0)
123 /* end of file reached */
124 break;
125 while (n) {
126 if (intrsig)
127 goto has_intrsig;
128 if ((w = write(1, cp, n)) != -1) {
129 n -= w;
130 cp += w;
131 continue;
133 if (errno == EINTR) {
134 has_intrsig:
135 /* give the user a chance to ^C out */
136 if (intrsig) {
137 write(2, sigint_msg,
138 sizeof(sigint_msg) - 1);
139 return (ksh_sigmask(SIGINT));
141 /* interrupted, try again */
142 continue;
144 if (errno == EPIPE) {
145 /* fake receiving signal */
146 rv = ksh_sigmask(SIGPIPE);
147 } else {
148 /* an error occured during writing */
149 disperr("<stdout>");
150 rv = 1;
152 if (fd != 0)
153 close(fd);
154 goto out;
157 if (fd != 0)
158 close(fd);
159 } while (*wp);
161 out:
162 return (rv);