Line data Source code
1 : #include "fd_io.h"
2 :
3 : /* TODO: try to eliminate use of FD_LOG_STYLE in log if possible in
4 : favor of FD_IO_STYLE here. */
5 :
6 : #ifndef FD_IO_STYLE
7 : #if FD_HAS_HOSTED
8 : #define FD_IO_STYLE 0
9 : #else
10 : #error "Define FD_IO_STYLE for this platform"
11 : #endif
12 : #endif
13 :
14 : #if FD_IO_STYLE==0 /* POSIX style */
15 :
16 : #include <errno.h>
17 : #include <signal.h>
18 : #include <unistd.h>
19 :
20 : int
21 : fd_io_read( int fd,
22 : void * _dst,
23 : ulong dst_min,
24 : ulong dst_max,
25 227763 : ulong * _dst_sz ) {
26 :
27 227763 : if( FD_UNLIKELY( dst_max==0UL ) ) {
28 6 : *_dst_sz = 0UL;
29 6 : return 0;
30 6 : }
31 :
32 227757 : uchar * dst = (uchar *)_dst;
33 :
34 227757 : ulong dst_sz = 0UL;
35 227757 : do {
36 :
37 : /* Note: POSIX indicates read with sz larger than SSIZE_MAX (which
38 : is the same as LONG_MAX here) is IB. While this is an
39 : impractically large value nowadays, we don't take chances. */
40 :
41 227757 : long ssz = read( fd, dst+dst_sz, fd_ulong_min( dst_max-dst_sz, (ulong)LONG_MAX ) );
42 227757 : ulong rsz = (ulong)ssz;
43 :
44 227757 : if( FD_UNLIKELY( !((0L<ssz) & (rsz<=(dst_max-dst_sz))) ) ) {
45 :
46 : /* At this point, ssz is not in [1,dst_max-dst_sz] */
47 :
48 30 : if( FD_LIKELY( !ssz ) ) { /* hit EOF */
49 24 : *_dst_sz = dst_sz;
50 24 : return -1;
51 24 : }
52 :
53 : /* At this point, ssz is not in [0,dst_max-dst_sz]. Thus, ssz
54 : should be -1 and errno should be set. If errno is set to
55 : EAGAIN, it appears that fd is configured as non-blocking and,
56 : because we have not yet read dst_min, we try again. Because of
57 : glitches in the POSIX spec, read is also allowed to use
58 : EWOULDBLOCK for this and EWOULDBLOCK is not required to have
59 : the same value as EAGAIN (if EAGAIN==EWOULDBLOCK on the target,
60 : the compiler will almost certainly optimize out the unnecessary
61 : cmov). */
62 :
63 6 : int err = errno;
64 6 : if( err==EWOULDBLOCK ) err = EAGAIN; /* cmov / no-op */
65 6 : if( FD_UNLIKELY( (dst_sz<dst_min) & (err==EAGAIN) ) ) continue;
66 :
67 : /* At this point, ssz is not in [0,dst_max-dst_sz]. ssz should be
68 : -1 and errno set (and not EWOULDBLOCK). If not, read does not
69 : seem to be following POSIX and we flag such as EPROTO (which
70 : should not be used as an errno case for read above and is at
71 : least suggestive of the issue) to make a strong guarantee to
72 : the caller. */
73 :
74 6 : if( !err ) err = EPROTO; /* cmov */
75 6 : *_dst_sz = 0UL;
76 6 : return err;
77 6 : }
78 :
79 : /* At this point, rsz is in [1,dst_max-dst_sz] */
80 :
81 227727 : dst_sz += rsz;
82 227727 : } while( dst_sz<dst_min );
83 :
84 227727 : *_dst_sz = dst_sz;
85 227727 : return 0;
86 227757 : }
87 :
88 : int
89 : fd_io_write( int fd,
90 : void const * _src,
91 : ulong src_min,
92 : ulong src_max,
93 518976 : ulong * _src_sz ) {
94 :
95 518976 : if( FD_UNLIKELY( src_max==0UL ) ) {
96 6 : *_src_sz = 0UL;
97 6 : return 0;
98 6 : }
99 :
100 : /* Note: this is virtually identical to read. See read for more
101 : details. */
102 :
103 518970 : uchar const * src = (uchar const *)_src;
104 :
105 518970 : ulong src_sz = 0UL;
106 518970 : do {
107 :
108 518970 : long ssz = write( fd, src+src_sz, fd_ulong_min( src_max-src_sz, (ulong)LONG_MAX ) );
109 518970 : ulong wsz = (ulong)ssz;
110 :
111 518970 : if( FD_UNLIKELY( !((0L<ssz) & (wsz<=(src_max-src_sz))) ) ) {
112 :
113 : /* Note: The POSIX spec explicitly indicates _reads_ use ssz
114 : -1 and errno EAGAIN/EWOULDBLOCK for no-data-available-now and
115 : ssz 0 for end-of-file to explicitly disambiguate these cases.
116 : It also specifically indicates that _writes_ follow the same
117 : convention to keep read and write call return handling similar
118 : even though there is no POSIX concept of an end-of-file for
119 : writes. At the same time, there seem to be no cases in the
120 : standard where a write with a positive size (as it is above)
121 : should return 0. So, we skip "EOF" handling here. If a zero
122 : ssz unexpectedly occurs, it will be likely be treated as an
123 : EPROTO below. */
124 :
125 : # if 0
126 : if( FD_UNLIKELY( !ssz ) ) {
127 : *_src_sz = src_sz;
128 : return -1;
129 : }
130 : # endif
131 :
132 6 : int err = errno;
133 6 : if( err==EWOULDBLOCK ) err = EAGAIN;
134 6 : if( FD_UNLIKELY( (src_sz<src_min) & (err==EAGAIN) ) ) continue;
135 :
136 6 : if( !err ) err = EPROTO;
137 6 : *_src_sz = 0UL;
138 6 : return err;
139 6 : }
140 :
141 518964 : src_sz += wsz;
142 518964 : } while( src_sz<src_min );
143 :
144 518964 : *_src_sz = src_sz;
145 518964 : return 0;
146 518970 : }
147 :
148 : int
149 : fd_io_buffered_read( int fd,
150 : void * _dst,
151 : ulong dst_sz,
152 : void * _rbuf,
153 : ulong rbuf_sz,
154 : ulong * _rbuf_lo,
155 823734 : ulong * _rbuf_ready ) {
156 :
157 823734 : if( FD_UNLIKELY( !dst_sz ) ) return 0; /* Nothing to do ... optimize for non-trivial read */
158 :
159 823635 : uchar * dst = (uchar *)_dst;
160 823635 : uchar * rbuf = (uchar *)_rbuf;
161 823635 : ulong rbuf_lo = *_rbuf_lo;
162 823635 : ulong rbuf_ready = *_rbuf_ready;
163 :
164 823635 : ulong rsz;
165 :
166 823635 : if( FD_LIKELY( rbuf_ready ) ) { /* Optimize for lots of tiny reads */
167 :
168 : /* At this point we have at least one byte already buffered and one
169 : byte to write. Copy as many bytes as possible from rbuf into
170 : dst. */
171 :
172 815550 : ulong cpy_sz = fd_ulong_min( dst_sz, rbuf_ready ); /* At least 1 and either dst_sz or rbuf_ready */
173 815550 : fd_memcpy( dst, rbuf + rbuf_lo, cpy_sz );
174 815550 : dst += cpy_sz;
175 815550 : dst_sz -= cpy_sz;
176 :
177 : /* If this completed the read, we are done. */
178 :
179 815550 : if( FD_LIKELY( !dst_sz ) ) { /* Optimize for lots of tiny reads */
180 737031 : *_rbuf_lo = rbuf_lo + cpy_sz;
181 737031 : *_rbuf_ready = rbuf_ready - cpy_sz;
182 737031 : return 0;
183 737031 : }
184 :
185 : /* At this point we have more bytes to read, which implies cpy_sz
186 : was less than dst_sz, which implies cpy_sz was rbuf_ready, which
187 : implies rbuf is empty because it was drained above. */
188 815550 : }
189 :
190 : /* At this point, rbuf is empty and we have at least one byte to read. */
191 :
192 86604 : if( FD_UNLIKELY( dst_sz>=rbuf_sz ) ) { /* If we have a large amount of data to read ... (optimize for tiny reads) */
193 :
194 : # if 0 /* This implementation guarantees at most one fd read per call but will not block fd reads */
195 :
196 : /* Read it directly into dst */
197 :
198 : *_rbuf_lo = 0UL;
199 : *_rbuf_ready = 0UL;
200 : return fd_io_read( fd, dst, dst_sz, dst_sz, &rsz );
201 :
202 : # else /* This implementation will block fd reads into multiples of rbuf_sz */
203 :
204 : /* Read the largest rbuf_sz multiple directly into dst. */
205 :
206 11451 : ulong bulk_sz = rbuf_sz*(dst_sz/rbuf_sz); /* TODO: require rbuf_sz to be a power of 2 for faster performance here? */
207 :
208 11451 : int err = fd_io_read( fd, dst, bulk_sz, bulk_sz, &rsz );
209 11451 : if( FD_UNLIKELY( err ) ) {
210 9 : *_rbuf_lo = 0UL;
211 9 : *_rbuf_ready = 0UL;
212 9 : return err;
213 9 : }
214 :
215 11442 : dst += bulk_sz;
216 11442 : dst_sz -= bulk_sz;
217 :
218 : /* If this completed the read, we are done. */
219 :
220 11442 : if( FD_LIKELY( !dst_sz ) ) { /* Optimize for tiny reads */
221 240 : *_rbuf_lo = 0UL;
222 240 : *_rbuf_ready = 0UL;
223 240 : return 0;
224 240 : }
225 :
226 : /* At this point, we have dst_sz in [1,rbuf_sz) bytes to read */
227 :
228 11442 : # endif
229 :
230 11442 : }
231 :
232 : /* At this point, we have dst_sz in [1,rbuf_sz). Fill up rbuf
233 : as much as we can and return the results from there. */
234 :
235 86355 : int err = fd_io_read( fd, rbuf, dst_sz, rbuf_sz, &rsz );
236 86355 : if( FD_UNLIKELY( err ) ) { /* failed (err>0,rsz==0) or EOF (err<0,rsz<dst_sz), either way, we can't handle the request */
237 0 : *_rbuf_lo = 0UL;
238 0 : *_rbuf_ready = 0UL;
239 0 : return err;
240 0 : }
241 :
242 86355 : fd_memcpy( dst, rbuf, dst_sz );
243 86355 : *_rbuf_lo = dst_sz;
244 86355 : *_rbuf_ready = rsz - dst_sz;
245 86355 : return 0;
246 86355 : }
247 :
248 : int
249 : fd_io_buffered_skip( int fd,
250 : ulong skip_sz,
251 : void * rbuf,
252 : ulong rbuf_sz,
253 : ulong * _rbuf_lo,
254 1197 : ulong * _rbuf_ready ) {
255 :
256 : /* For large skips, flush rbuf and lseek the fd for the remainder.
257 : TODO: Consider a variant where fd lseek is aligned to a rbuf_sz
258 : like the above (such might require this function to do some
259 : buffering of data if the skip_sz isn't an rbuf_sz multiple). */
260 :
261 1197 : ulong rbuf_ready = *_rbuf_ready;
262 :
263 1197 : if( FD_UNLIKELY( skip_sz>rbuf_ready ) ) { /* Optimize for tiny skips */
264 :
265 1080 : skip_sz -= rbuf_ready; /* At least 1 */
266 1080 : do {
267 :
268 : /* Note: lseek allows seeking past EOF (even on a RDONLY fd). */
269 :
270 1080 : ulong lseek_sz = fd_ulong_min( skip_sz, (ulong)LONG_MAX ); /* Workaround POSIX sign / unsigned glitches */
271 1080 : if( FD_UNLIKELY( lseek( fd, (long)lseek_sz, SEEK_CUR )==-1L ) ) {
272 :
273 0 : int err = errno;
274 :
275 0 : if( FD_UNLIKELY( err==ESPIPE ) ) {
276 :
277 : /* It appears the stream isn't seekable ... skip over via
278 : actual reads. It is kinda gross that we do this every time
279 : we have to skip on an unseekable stream. At the same time,
280 : such usages are likely so low bandwidth and so rare that
281 : the perf hit from just doing the spurious lseeks is
282 : probably in the noise and not worth the extra overhead /
283 : complexity to do more elaborate handling. */
284 :
285 0 : do {
286 0 : ulong read_sz = fd_ulong_min( rbuf_sz, skip_sz );
287 0 : ulong rsz;
288 0 : err = fd_io_read( fd, rbuf, read_sz, read_sz, &rsz );
289 0 : if( FD_UNLIKELY( !((!err) | (err==EAGAIN)) ) ) break;
290 0 : skip_sz -= rsz;
291 0 : } while( skip_sz );
292 :
293 0 : *_rbuf_lo = 0UL;
294 0 : *_rbuf_ready = 0UL;
295 0 : return err;
296 :
297 0 : }
298 :
299 0 : if( !err ) err = EPROTO; /* cmov, paranoia for non-conform to provide strong guarantees to caller */
300 :
301 0 : *_rbuf_lo = 0UL;
302 0 : *_rbuf_ready = 0UL;
303 0 : return err;
304 0 : }
305 :
306 1080 : skip_sz -= lseek_sz;
307 1080 : } while( FD_UNLIKELY( skip_sz ) );
308 :
309 1080 : *_rbuf_lo = 0UL;
310 1080 : *_rbuf_ready = 0UL;
311 1080 : return 0;
312 1080 : }
313 :
314 : /* Skip is purely over buffered bytes */
315 :
316 117 : *_rbuf_lo += skip_sz;
317 117 : *_rbuf_ready = rbuf_ready - skip_sz;
318 117 : return 0;
319 1197 : }
320 :
321 : int
322 : fd_io_buffered_write( int fd,
323 : void const * _src,
324 : ulong src_sz,
325 : void * _wbuf,
326 : ulong wbuf_sz,
327 826659 : ulong * _wbuf_used ) {
328 :
329 826659 : if( FD_UNLIKELY( !src_sz ) ) return 0; /* Nothing to do ... optimize for non-trivial writes */
330 :
331 826635 : uchar const * src = (uchar const *)_src;
332 826635 : uchar * wbuf = (uchar *) _wbuf;
333 :
334 826635 : ulong wsz;
335 :
336 826635 : ulong wbuf_used = *_wbuf_used;
337 :
338 826635 : if( FD_LIKELY( wbuf_used ) ) { /* Optimize for lots of tiny writes */
339 :
340 : /* At this point, we have at least one byte already buffered and one
341 : byte to write. Copy as many bytes as possible from src into
342 : wbuf. */
343 :
344 738201 : ulong cpy_sz = fd_ulong_min( wbuf_sz - wbuf_used, src_sz ); /* cpy_sz>=1, cpy_sz is either wbuf_free or src_sz */
345 :
346 738201 : if( FD_LIKELY( cpy_sz ) ) fd_memcpy( wbuf + wbuf_used, src, cpy_sz );
347 :
348 738201 : src += cpy_sz;
349 738201 : src_sz -= cpy_sz;
350 738201 : wbuf_used += cpy_sz;
351 :
352 : /* If this filled up the buffer, flush it */
353 :
354 738201 : if( FD_UNLIKELY( wbuf_used >= wbuf_sz ) ) { /* Optimize for lots of tiny writes */
355 55962 : int err = fd_io_write( fd, wbuf, wbuf_sz, wbuf_sz, &wsz );
356 55962 : if( FD_UNLIKELY( err ) ) {
357 0 : *_wbuf_used = 0UL;
358 0 : return err;
359 0 : }
360 55962 : wbuf_used = 0UL;
361 55962 : }
362 :
363 : /* If this completed the write, we are done. */
364 :
365 738201 : if( FD_LIKELY( !src_sz ) ) { /* Optimize for lots of tiny writes */
366 682290 : *_wbuf_used = wbuf_used;
367 682290 : return 0;
368 682290 : }
369 :
370 : /* At this point, we have more bytes to write, which implies cpy_sz
371 : was less than src_sz, which implies cpy_sz was wbuf_free, which
372 : implies wbuf is empty because it was flushed above. */
373 :
374 738201 : }
375 :
376 : /* At this point, wbuf is empty and we have at least one byte to
377 : write. */
378 :
379 144345 : if( FD_UNLIKELY( src_sz>=wbuf_sz ) ) { /* If we have a large amount of data to write ... (optimize for tiny writes) */
380 :
381 : # if 0 /* This implementation guarantees at most one fd write per call but will not block fd writes */
382 :
383 : /* Write it directly from src */
384 :
385 : *_wbuf_used = 0UL;
386 : return fd_io_write( fd, src, src_sz, src_sz, &wsz );
387 :
388 : # else /* This implementation will block fd writes into multiples of wbuf_sz */
389 :
390 : /* Write the largest wbuf_sz multiple directly into src. */
391 :
392 9963 : ulong bulk_sz = wbuf_sz*(src_sz/wbuf_sz); /* TODO: require wbuf_sz to be a power of 2 for faster performance here? */
393 :
394 9963 : int err = fd_io_write( fd, src, bulk_sz, bulk_sz, &wsz );
395 9963 : if( FD_UNLIKELY( err ) ) {
396 0 : *_wbuf_used = 0UL;
397 0 : return err;
398 0 : }
399 :
400 9963 : src += bulk_sz;
401 9963 : src_sz -= bulk_sz;
402 :
403 : /* If this completed the write, we are done. */
404 :
405 9963 : if( FD_LIKELY( !src_sz ) ) { /* Optimize for tiny writes */
406 120 : *_wbuf_used = 0UL;
407 120 : return 0;
408 120 : }
409 :
410 : /* At this point, we have src_sz in [1,wbuf_sz) bytes to write. */
411 :
412 9963 : # endif
413 :
414 9963 : }
415 :
416 : /* At this point, we have src_sz in [1,wbuf_sz) and an empty
417 : buffer. Buffer these bytes. */
418 :
419 144225 : fd_memcpy( wbuf, src, src_sz );
420 144225 : *_wbuf_used = src_sz;
421 144225 : return 0;
422 144345 : }
423 :
424 : char const *
425 177 : fd_io_strerror( int err ) {
426 :
427 : /* This covers the standard POSIX-2008 errnos. We handle the POSIX
428 : glitches around EWOULDBLOCK / EAGAIN and EOPNOTSUPP / ENOTSUP so
429 : this will build fine regardless of whether these map to the same
430 : or different error codes (they typically map to the same nowadays).
431 : We also throw in negative values for EOF as that is how the above
432 : handles such. */
433 :
434 177 : if( err<0 ) return "end-of-file";
435 :
436 174 : if( err==EWOULDBLOCK ) err = EAGAIN; /* cmov / no-op */
437 174 : if( err==EOPNOTSUPP ) err = ENOTSUP; /* cmov / no-op */
438 :
439 174 : switch( err ) {
440 3 : case 0 : return "success";
441 0 : case E2BIG : return "E2BIG-argument list too long";
442 147 : case EACCES : return "EACCES-permission denied";
443 0 : case EADDRINUSE : return "EADDRINUSE-address already in use";
444 0 : case EADDRNOTAVAIL : return "EADDRNOTAVAIL-cannot assign requested address";
445 0 : case EAFNOSUPPORT : return "EAFNOSUPPORT-address family not supported by protocol";
446 0 : case EAGAIN : return "EAGAIN-resource temporarily unavailable";
447 0 : case EALREADY : return "EALREADY-operation already in progress";
448 3 : case EBADF : return "EBADF-bad file descriptor";
449 0 : case EBADMSG : return "EBADMSG-bad message";
450 0 : case EBUSY : return "EBUSY-device or resource busy";
451 0 : case ECANCELED : return "ECANCELED-operation canceled";
452 0 : case ECHILD : return "ECHILD-no child processes";
453 0 : case ECONNABORTED : return "ECONNABORTED-software caused connection abort";
454 0 : case ECONNREFUSED : return "ECONNREFUSED-connection refused";
455 0 : case ECONNRESET : return "ECONNRESET-connection reset by peer";
456 0 : case EDEADLK : return "EDEADLK-resource deadlock avoided";
457 0 : case EDESTADDRREQ : return "EDESTADDRREQ-destination address required";
458 0 : case EDOM : return "EDOM-numerical argument out of domain";
459 0 : case EEXIST : return "EEXIST-file exists";
460 0 : case EFAULT : return "EFAULT-bad address";
461 0 : case EFBIG : return "EFBIG-file too large";
462 0 : case EHOSTUNREACH : return "EHOSTUNREACH-no route to host";
463 0 : case EIDRM : return "EIDRM-identifier removed";
464 0 : case EILSEQ : return "EILSEQ-invalid or incomplete multibyte or wide character";
465 0 : case EINPROGRESS : return "EINPROGRESS-operation now in progress";
466 0 : case EINTR : return "EINTR-interrupted system call";
467 0 : case EINVAL : return "EINVAL-invalid argument";
468 0 : case EIO : return "EIO-input/output error";
469 0 : case EISCONN : return "EISCONN-transport endpoint is already connected";
470 0 : case EISDIR : return "EISDIR-is a directory";
471 0 : case ELOOP : return "ELOOP-too many levels of symbolic links";
472 0 : case EMFILE : return "EMFILE-too many open files";
473 0 : case EMLINK : return "EMLINK-too many links";
474 0 : case EMSGSIZE : return "EMSGSIZE-message too long";
475 0 : case ENAMETOOLONG : return "ENAMETOOLONG-file name too long";
476 0 : case ENETDOWN : return "ENETDOWN-network is down";
477 0 : case ENETRESET : return "ENETRESET-network dropped connection on reset";
478 0 : case ENETUNREACH : return "ENETUNREACH-network is unreachable";
479 0 : case ENFILE : return "ENFILE-too many open files in system";
480 0 : case ENOBUFS : return "ENOBUFS-no buffer space available";
481 0 : case ENODEV : return "ENODEV-no such device";
482 0 : case ENOENT : return "ENOENT-no such file or directory";
483 0 : case ENOEXEC : return "ENOEXEC-exec format error";
484 0 : case ENOLCK : return "ENOLCK-no locks available";
485 21 : case ENOMEM : return "ENOMEM-cannot allocate memory";
486 0 : case ENOMSG : return "ENOMSG-no message of desired type";
487 0 : case ENOPROTOOPT : return "ENOPROTOOPT-protocol not available";
488 0 : case ENOSPC : return "ENOSPC-no space left on device";
489 0 : case ENOSYS : return "ENOSYS-function not implemented";
490 0 : case ENOTCONN : return "ENOTCONN-transport endpoint is not connected";
491 0 : case ENOTDIR : return "ENOTDIR-not a directory";
492 0 : case ENOTEMPTY : return "ENOTEMPTY-directory not empty";
493 0 : case ENOTRECOVERABLE: return "ENOTRECOVERABLE-state not recoverable";
494 0 : case ENOTSOCK : return "ENOTSOCK-socket operation on non-socket";
495 0 : case ENOTSUP : return "ENOTSUP-operation not supported";
496 0 : case ENOTTY : return "ENOTTY-inappropriate ioctl for device";
497 0 : case ENXIO : return "ENXIO-no such device or address";
498 0 : case EOVERFLOW : return "EOVERFLOW-value too large for defined data type";
499 0 : case EOWNERDEAD : return "EOWNERDEAD-owner died";
500 0 : case EPERM : return "EPERM-operation not permitted";
501 0 : case EPIPE : return "EPIPE-broken pipe";
502 0 : case EPROTONOSUPPORT: return "EPROTONOSUPPORT-protocol not supported";
503 0 : case EPROTO : return "EPROTO-protocol error";
504 0 : case EPROTOTYPE : return "EPROTOTYPE-protocol wrong type for socket";
505 0 : case ERANGE : return "ERANGE-numerical result out of range";
506 0 : case EROFS : return "EROFS-read-only file system";
507 0 : case ESPIPE : return "ESPIPE-illegal seek";
508 0 : case ESRCH : return "ESRCH-no such process";
509 0 : case ETIMEDOUT : return "ETIMEDOUT-connection timed out";
510 0 : case ETXTBSY : return "ETXTBSY-text file busy";
511 0 : case EXDEV : return "EXDEV-invalid cross-device link";
512 0 : default: break;
513 174 : }
514 :
515 0 : return "unknown";
516 174 : }
517 :
518 : char const *
519 0 : fd_io_strsignal( int sig ) {
520 0 : switch( sig ) {
521 0 : case 0 : return "success";
522 0 : case SIGHUP : return "SIGHUP-Hangup";
523 0 : case SIGINT : return "SIGINT-Interrupt";
524 0 : case SIGQUIT : return "SIGQUIT-Quit";
525 0 : case SIGILL : return "SIGILL-Illegal instruction";
526 0 : case SIGTRAP : return "SIGTRAP-Trace/breakpoint trap";
527 0 : case SIGABRT : return "SIGABRT-Aborted";
528 0 : case SIGBUS : return "SIGBUS-Bus error";
529 0 : case SIGFPE : return "SIGFPE-Arithmetic exception";
530 0 : case SIGKILL : return "SIGKILL-Killed";
531 0 : case SIGUSR1 : return "SIGUSR1-User defined signal 1";
532 0 : case SIGSEGV : return "SIGSEGV-Segmentation fault";
533 0 : case SIGUSR2 : return "SIGUSR2-User defined signal 2";
534 0 : case SIGPIPE : return "SIGPIPE-Broken pipe";
535 0 : case SIGALRM : return "SIGALRM-Alarm clock";
536 0 : case SIGTERM : return "SIGTERM-Terminated";
537 0 : #if defined(SIGSTKFLT)
538 0 : case SIGSTKFLT : return "SIGSTKFLT-Stack fault";
539 : #elif defined(SIGEMT)
540 : case SIGEMT : return "SIGEMT-Emulator trap";
541 : #endif
542 0 : case SIGCHLD : return "SIGCHLD-Child process status";
543 0 : case SIGCONT : return "SIGCONT-Continued";
544 0 : case SIGSTOP : return "SIGSTOP-Stopped (signal)";
545 0 : case SIGTSTP : return "SIGTSTP-Stopped";
546 0 : case SIGTTIN : return "SIGTTIN-Stopped (tty input)";
547 0 : case SIGTTOU : return "SIGTTOU-Stopped (tty output)";
548 0 : case SIGURG : return "SIGURG-Urgent I/O condition";
549 0 : case SIGXCPU : return "SIGXCPU-CPU time limit exceeded";
550 0 : case SIGXFSZ : return "SIGXFSZ-File size limit exceeded";
551 0 : case SIGVTALRM : return "SIGVTALRM-Virtual timer expired";
552 0 : case SIGPROF : return "SIGPROF-Profiling timer expired";
553 0 : #if defined(SIGWINCH)
554 0 : case SIGWINCH : return "SIGWINCH-Window changed";
555 0 : #endif
556 0 : #if defined(SIGPOLL)
557 0 : case SIGPOLL : return "SIGPOLL-I/O possible";
558 0 : #endif
559 0 : #if defined(SIGPWR)
560 0 : case SIGPWR : return "SIGPWR-Power failure";
561 0 : #endif
562 0 : case SIGSYS : return "SIGSYS-Bad system call";
563 0 : default: break;
564 0 : }
565 :
566 0 : return "unknown";
567 0 : }
568 :
569 : #else
570 : #error "Unknown FD_IO_STYLE"
571 : #endif
|