source: mainline/uspace/lib/posix/string.c@ 82cb6768

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 82cb6768 was 3f33b95, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 14 years ago

CStyle in strstr().

  • Property mode set to 100644
File size: 19.8 KB
Line 
1/*
2 * Copyright (c) 2011 Petr Koupy
3 * Copyright (c) 2011 Jiri Zarevucky
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libposix
31 * @{
32 */
33/** @file String manipulation.
34 */
35
36#define LIBPOSIX_INTERNAL
37
38#include "internal/common.h"
39#include "string.h"
40
41#include "assert.h"
42#include "errno.h"
43#include "limits.h"
44#include "stdlib.h"
45#include "signal.h"
46
47#include "libc/str_error.h"
48
49/**
50 * The same as strpbrk, except it returns pointer to the nul terminator
51 * if no occurence is found.
52 *
53 * @param s1 String in which to look for the bytes.
54 * @param s2 String of bytes to look for.
55 * @return Pointer to the found byte on success, pointer to the
56 * string terminator otherwise.
57 */
58static char *strpbrk_null(const char *s1, const char *s2)
59{
60 while (!posix_strchr(s2, *s1)) {
61 ++s1;
62 }
63
64 return (char *) s1;
65}
66
67/**
68 * Copy a string.
69 *
70 * @param dest Destination pre-allocated buffer.
71 * @param src Source string to be copied.
72 * @return Pointer to the destination buffer.
73 */
74char *posix_strcpy(char *restrict dest, const char *restrict src)
75{
76 posix_stpcpy(dest, src);
77 return dest;
78}
79
80/**
81 * Copy fixed length string.
82 *
83 * @param dest Destination pre-allocated buffer.
84 * @param src Source string to be copied.
85 * @param n Number of bytes to be stored into destination buffer.
86 * @return Pointer to the destination buffer.
87 */
88char *posix_strncpy(char *restrict dest, const char *restrict src, size_t n)
89{
90 posix_stpncpy(dest, src, n);
91 return dest;
92}
93
94/**
95 * Copy a string.
96 *
97 * @param dest Destination pre-allocated buffer.
98 * @param src Source string to be copied.
99 * @return Pointer to the nul character in the destination string.
100 */
101char *posix_stpcpy(char *restrict dest, const char *restrict src)
102{
103 assert(dest != NULL);
104 assert(src != NULL);
105
106 for (size_t i = 0; ; ++i) {
107 dest[i] = src[i];
108
109 if (src[i] == '\0') {
110 /* pointer to the terminating nul character */
111 return &dest[i];
112 }
113 }
114
115 /* unreachable */
116 return NULL;
117}
118
119/**
120 * Copy fixed length string.
121 *
122 * @param dest Destination pre-allocated buffer.
123 * @param src Source string to be copied.
124 * @param n Number of bytes to be stored into destination buffer.
125 * @return Pointer to the first written nul character or &dest[n].
126 */
127char *posix_stpncpy(char *restrict dest, const char *restrict src, size_t n)
128{
129 assert(dest != NULL);
130 assert(src != NULL);
131
132 for (size_t i = 0; i < n; ++i) {
133 dest[i] = src[i];
134
135 /* the standard requires that nul characters
136 * are appended to the length of n, in case src is shorter
137 */
138 if (src[i] == '\0') {
139 char *result = &dest[i];
140 for (++i; i < n; ++i) {
141 dest[i] = '\0';
142 }
143 return result;
144 }
145 }
146
147 return &dest[n];
148}
149
150/**
151 * Concatenate two strings.
152 *
153 * @param dest String to which src shall be appended.
154 * @param src String to be appended after dest.
155 * @return Pointer to destination buffer.
156 */
157char *posix_strcat(char *restrict dest, const char *restrict src)
158{
159 assert(dest != NULL);
160 assert(src != NULL);
161
162 posix_strcpy(posix_strchr(dest, '\0'), src);
163 return dest;
164}
165
166/**
167 * Concatenate a string with part of another.
168 *
169 * @param dest String to which part of src shall be appended.
170 * @param src String whose part shall be appended after dest.
171 * @param n Number of bytes to append after dest.
172 * @return Pointer to destination buffer.
173 */
174char *posix_strncat(char *restrict dest, const char *restrict src, size_t n)
175{
176 assert(dest != NULL);
177 assert(src != NULL);
178
179 char *zeroptr = posix_strncpy(posix_strchr(dest, '\0'), src, n);
180 /* strncpy doesn't append the nul terminator, so we do it here */
181 zeroptr[n] = '\0';
182 return dest;
183}
184
185/**
186 * Copy limited number of bytes in memory.
187 *
188 * @param dest Destination buffer.
189 * @param src Source buffer.
190 * @param c Character after which the copying shall stop.
191 * @param n Number of bytes that shall be copied if not stopped earlier by c.
192 * @return Pointer to the first byte after c in dest if found, NULL otherwise.
193 */
194void *posix_memccpy(void *restrict dest, const void *restrict src, int c, size_t n)
195{
196 assert(dest != NULL);
197 assert(src != NULL);
198
199 unsigned char* bdest = dest;
200 const unsigned char* bsrc = src;
201
202 for (size_t i = 0; i < n; ++i) {
203 bdest[i] = bsrc[i];
204
205 if (bsrc[i] == (unsigned char) c) {
206 /* pointer to the next byte */
207 return &bdest[i + 1];
208 }
209 }
210
211 return NULL;
212}
213
214/**
215 * Duplicate a string.
216 *
217 * @param s String to be duplicated.
218 * @return Newly allocated copy of the string.
219 */
220char *posix_strdup(const char *s)
221{
222 return posix_strndup(s, SIZE_MAX);
223}
224
225/**
226 * Duplicate a specific number of bytes from a string.
227 *
228 * @param s String to be duplicated.
229 * @param n Maximum length of the resulting string..
230 * @return Newly allocated string copy of length at most n.
231 */
232char *posix_strndup(const char *s, size_t n)
233{
234 assert(s != NULL);
235
236 size_t len = posix_strnlen(s, n);
237 char *dup = malloc(len + 1);
238 if (dup == NULL) {
239 return NULL;
240 }
241
242 memcpy(dup, s, len);
243 dup[len] = '\0';
244
245 return dup;
246}
247
248/**
249 * Compare bytes in memory.
250 *
251 * @param mem1 First area of memory to be compared.
252 * @param mem2 Second area of memory to be compared.
253 * @param n Maximum number of bytes to be compared.
254 * @return Difference of the first pair of inequal bytes,
255 * or 0 if areas have the same content.
256 */
257int posix_memcmp(const void *mem1, const void *mem2, size_t n)
258{
259 assert(mem1 != NULL);
260 assert(mem2 != NULL);
261
262 const unsigned char *s1 = mem1;
263 const unsigned char *s2 = mem2;
264
265 for (size_t i = 0; i < n; ++i) {
266 if (s1[i] != s2[i]) {
267 return s1[i] - s2[i];
268 }
269 }
270
271 return 0;
272}
273
274/**
275 * Compare two strings.
276 *
277 * @param s1 First string to be compared.
278 * @param s2 Second string to be compared.
279 * @return Difference of the first pair of inequal characters,
280 * or 0 if strings have the same content.
281 */
282int posix_strcmp(const char *s1, const char *s2)
283{
284 assert(s1 != NULL);
285 assert(s2 != NULL);
286
287 return posix_strncmp(s1, s2, STR_NO_LIMIT);
288}
289
290/**
291 * Compare part of two strings.
292 *
293 * @param s1 First string to be compared.
294 * @param s2 Second string to be compared.
295 * @param n Maximum number of characters to be compared.
296 * @return Difference of the first pair of inequal characters,
297 * or 0 if strings have the same content.
298 */
299int posix_strncmp(const char *s1, const char *s2, size_t n)
300{
301 assert(s1 != NULL);
302 assert(s2 != NULL);
303
304 for (size_t i = 0; i < n; ++i) {
305 if (s1[i] != s2[i]) {
306 return s1[i] - s2[i];
307 }
308 if (s1[i] == '\0') {
309 break;
310 }
311 }
312
313 return 0;
314}
315
316/**
317 * Find byte in memory.
318 *
319 * @param mem Memory area in which to look for the byte.
320 * @param c Byte to look for.
321 * @param n Maximum number of bytes to be inspected.
322 * @return Pointer to the specified byte on success,
323 * NULL pointer otherwise.
324 */
325void *posix_memchr(const void *mem, int c, size_t n)
326{
327 assert(mem != NULL);
328
329 const unsigned char *s = mem;
330
331 for (size_t i = 0; i < n; ++i) {
332 if (s[i] == (unsigned char) c) {
333 return (void *) &s[i];
334 }
335 }
336 return NULL;
337}
338
339/**
340 * Scan string for a first occurence of a character.
341 *
342 * @param s String in which to look for the character.
343 * @param c Character to look for.
344 * @return Pointer to the specified character on success,
345 * NULL pointer otherwise.
346 */
347char *posix_strchr(const char *s, int c)
348{
349 assert(s != NULL);
350
351 char *res = gnu_strchrnul(s, c);
352 return (*res == c) ? res : NULL;
353}
354
355/**
356 * Scan string for a last occurence of a character.
357 *
358 * @param s String in which to look for the character.
359 * @param c Character to look for.
360 * @return Pointer to the specified character on success,
361 * NULL pointer otherwise.
362 */
363char *posix_strrchr(const char *s, int c)
364{
365 assert(s != NULL);
366
367 const char *ptr = posix_strchr(s, '\0');
368
369 /* the same as in strchr, except it loops in reverse direction */
370 while (*ptr != (char) c) {
371 if (ptr == s) {
372 return NULL;
373 }
374
375 ptr--;
376 }
377
378 return (char *) ptr;
379}
380
381/**
382 * Scan string for a first occurence of a character.
383 *
384 * @param s String in which to look for the character.
385 * @param c Character to look for.
386 * @return Pointer to the specified character on success, pointer to the
387 * string terminator otherwise.
388 */
389char *gnu_strchrnul(const char *s, int c)
390{
391 assert(s != NULL);
392
393 while (*s != c && *s != '\0') {
394 s++;
395 }
396
397 return (char *) s;
398}
399
400/**
401 * Scan a string for a first occurence of one of provided bytes.
402 *
403 * @param s1 String in which to look for the bytes.
404 * @param s2 String of bytes to look for.
405 * @return Pointer to the found byte on success,
406 * NULL pointer otherwise.
407 */
408char *posix_strpbrk(const char *s1, const char *s2)
409{
410 assert(s1 != NULL);
411 assert(s2 != NULL);
412
413 char *ptr = strpbrk_null(s1, s2);
414 return (*ptr == '\0') ? NULL : ptr;
415}
416
417/**
418 * Get the length of a complementary substring.
419 *
420 * @param s1 String that shall be searched for complementary prefix.
421 * @param s2 String of bytes that shall not occur in the prefix.
422 * @return Length of the prefix.
423 */
424size_t posix_strcspn(const char *s1, const char *s2)
425{
426 assert(s1 != NULL);
427 assert(s2 != NULL);
428
429 char *ptr = strpbrk_null(s1, s2);
430 return (size_t) (ptr - s1);
431}
432
433/**
434 * Get length of a substring.
435 *
436 * @param s1 String that shall be searched for prefix.
437 * @param s2 String of bytes that the prefix must consist of.
438 * @return Length of the prefix.
439 */
440size_t posix_strspn(const char *s1, const char *s2)
441{
442 assert(s1 != NULL);
443 assert(s2 != NULL);
444
445 const char *ptr;
446 for (ptr = s1; *ptr != '\0'; ++ptr) {
447 if (!posix_strchr(s2, *ptr)) {
448 break;
449 }
450 }
451 return ptr - s1;
452}
453
454/**
455 * Find a substring. Uses Knuth-Morris-Pratt algorithm.
456 *
457 * @param s1 String in which to look for a substring.
458 * @param s2 Substring to look for.
459 * @return Pointer to the first character of the substring in s1, or NULL if
460 * not found.
461 */
462char *posix_strstr(const char *haystack, const char *needle)
463{
464 assert(haystack != NULL);
465 assert(needle != NULL);
466
467 /* Special case - needle is an empty string. */
468 if (needle[0] == '\0') {
469 return (char *) haystack;
470 }
471
472 /* Preprocess needle. */
473 size_t nlen = posix_strlen(needle);
474 size_t prefix_table[nlen + 1];
475
476 {
477 size_t i = 0;
478 ssize_t j = -1;
479
480 prefix_table[i] = j;
481
482 while (i < nlen) {
483 while (j >= 0 && needle[i] != needle[j]) {
484 j = prefix_table[j];
485 }
486 i++; j++;
487 prefix_table[i] = j;
488 }
489 }
490
491 /* Search needle using the precomputed table. */
492 size_t npos = 0;
493
494 for (size_t hpos = 0; haystack[hpos] != '\0'; ++hpos) {
495 while (npos != 0 && haystack[hpos] != needle[npos]) {
496 npos = prefix_table[npos];
497 }
498
499 if (haystack[hpos] == needle[npos]) {
500 npos++;
501
502 if (npos == nlen) {
503 return (char *) (haystack + hpos - nlen + 1);
504 }
505 }
506 }
507
508 return NULL;
509}
510
511/**
512 * String comparison using collating information.
513 *
514 * Currently ignores locale and just calls strcmp.
515 *
516 * @param s1 First string to be compared.
517 * @param s2 Second string to be compared.
518 * @return Difference of the first pair of inequal characters,
519 * or 0 if strings have the same content.
520 */
521int posix_strcoll(const char *s1, const char *s2)
522{
523 assert(s1 != NULL);
524 assert(s2 != NULL);
525
526 return posix_strcmp(s1, s2);
527}
528
529/**
530 * Transform a string in such a way that the resulting string yields the same
531 * results when passed to the strcmp as if the original string is passed to
532 * the strcoll.
533 *
534 * Since strcoll is equal to strcmp here, this just makes a copy.
535 *
536 * @param s1 Transformed string.
537 * @param s2 Original string.
538 * @param n Maximum length of the transformed string.
539 * @return Length of the transformed string.
540 */
541size_t posix_strxfrm(char *restrict s1, const char *restrict s2, size_t n)
542{
543 assert(s1 != NULL || n == 0);
544 assert(s2 != NULL);
545
546 size_t len = posix_strlen(s2);
547
548 if (n > len) {
549 posix_strcpy(s1, s2);
550 }
551
552 return len;
553}
554
555/**
556 * Get error message string.
557 *
558 * @param errnum Error code for which to obtain human readable string.
559 * @return Error message.
560 */
561char *posix_strerror(int errnum)
562{
563 static const char *error_msgs[] = {
564 [E2BIG] = "[E2BIG] Argument list too long",
565 [EACCES] = "[EACCES] Permission denied",
566 [EADDRINUSE] = "[EADDRINUSE] Address in use",
567 [EADDRNOTAVAIL] = "[EADDRNOTAVAIL] Address not available",
568 [EAFNOSUPPORT] = "[EAFNOSUPPORT] Address family not supported",
569 [EAGAIN] = "[EAGAIN] Resource unavailable, try again",
570 [EALREADY] = "[EALREADY] Connection already in progress",
571 [EBADF] = "[EBADF] Bad file descriptor",
572 [EBADMSG] = "[EBADMSG] Bad message",
573 [EBUSY] = "[EBUSY] Device or resource busy",
574 [ECANCELED] = "[ECANCELED] Operation canceled",
575 [ECHILD] = "[ECHILD] No child processes",
576 [ECONNABORTED] = "[ECONNABORTED] Connection aborted",
577 [ECONNREFUSED] = "[ECONNREFUSED] Connection refused",
578 [ECONNRESET] = "[ECONNRESET] Connection reset",
579 [EDEADLK] = "[EDEADLK] Resource deadlock would occur",
580 [EDESTADDRREQ] = "[EDESTADDRREQ] Destination address required",
581 [EDOM] = "[EDOM] Mathematics argument out of domain of function",
582 [EDQUOT] = "[EDQUOT] Reserved",
583 [EEXIST] = "[EEXIST] File exists",
584 [EFAULT] = "[EFAULT] Bad address",
585 [EFBIG] = "[EFBIG] File too large",
586 [EHOSTUNREACH] = "[EHOSTUNREACH] Host is unreachable",
587 [EIDRM] = "[EIDRM] Identifier removed",
588 [EILSEQ] = "[EILSEQ] Illegal byte sequence",
589 [EINPROGRESS] = "[EINPROGRESS] Operation in progress",
590 [EINTR] = "[EINTR] Interrupted function",
591 [EINVAL] = "[EINVAL] Invalid argument",
592 [EIO] = "[EIO] I/O error",
593 [EISCONN] = "[EISCONN] Socket is connected",
594 [EISDIR] = "[EISDIR] Is a directory",
595 [ELOOP] = "[ELOOP] Too many levels of symbolic links",
596 [EMFILE] = "[EMFILE] File descriptor value too large",
597 [EMLINK] = "[EMLINK] Too many links",
598 [EMSGSIZE] = "[EMSGSIZE] Message too large",
599 [EMULTIHOP] = "[EMULTIHOP] Reserved",
600 [ENAMETOOLONG] = "[ENAMETOOLONG] Filename too long",
601 [ENETDOWN] = "[ENETDOWN] Network is down",
602 [ENETRESET] = "[ENETRESET] Connection aborted by network",
603 [ENETUNREACH] = "[ENETUNREACH] Network unreachable",
604 [ENFILE] = "[ENFILE] Too many files open in system",
605 [ENOBUFS] = "[ENOBUFS] No buffer space available",
606 [ENODATA] = "[ENODATA] No message is available on the STREAM head read queue",
607 [ENODEV] = "[ENODEV] No such device",
608 [ENOENT] = "[ENOENT] No such file or directory",
609 [ENOEXEC] = "[ENOEXEC] Executable file format error",
610 [ENOLCK] = "[ENOLCK] No locks available",
611 [ENOLINK] = "[ENOLINK] Reserved",
612 [ENOMEM] = "[ENOMEM] Not enough space",
613 [ENOMSG] = "[ENOMSG] No message of the desired type",
614 [ENOPROTOOPT] = "[ENOPROTOOPT] Protocol not available",
615 [ENOSPC] = "[ENOSPC] No space left on device",
616 [ENOSR] = "[ENOSR] No STREAM resources.",
617 [ENOSTR] = "[ENOSTR] Not a STREAM",
618 [ENOSYS] = "[ENOSYS] Function not supported",
619 [ENOTCONN] = "[ENOTCONN] The socket is not connected",
620 [ENOTDIR] = "[ENOTDIR] Not a directory",
621 [ENOTEMPTY] = "[ENOTEMPTY] Directory not empty",
622 [ENOTRECOVERABLE] = "[ENOTRECOVERABLE] State not recoverable",
623 [ENOTSOCK] = "[ENOTSOCK] Not a socket",
624 [ENOTSUP] = "[ENOTSUP] Not supported",
625 [ENOTTY] = "[ENOTTY] Inappropriate I/O control operation",
626 [ENXIO] = "[ENXIO] No such device or address",
627 [EOPNOTSUPP] = "[EOPNOTSUPP] Operation not supported",
628 [EOVERFLOW] = "[EOVERFLOW] Value too large to be stored in data type",
629 [EOWNERDEAD] = "[EOWNERDEAD] Previous owned died",
630 [EPERM] = "[EPERM] Operation not permitted",
631 [EPIPE] = "[EPIPE] Broken pipe",
632 [EPROTO] = "[EPROTO] Protocol error",
633 [EPROTONOSUPPORT] = "[EPROTONOSUPPORT] Protocol not supported",
634 [EPROTOTYPE] = "[EPROTOTYPE] Protocol wrong type for socket",
635 [ERANGE] = "[ERANGE] Result too large",
636 [EROFS] = "[EROFS] Read-only file system",
637 [ESPIPE] = "[ESPIPE] Invalid seek",
638 [ESRCH] = "[ESRCH] No such process",
639 [ESTALE] = "[ESTALE] Reserved",
640 [ETIME] = "[ETIME] Stream ioctl() timeout",
641 [ETIMEDOUT] = "[ETIMEDOUT] Connection timed out",
642 [ETXTBSY] = "[ETXTBSY] Text file busy",
643 [EWOULDBLOCK] = "[EWOULDBLOCK] Operation would block",
644 [EXDEV] = "[EXDEV] Cross-device link",
645 };
646
647 return (char *) error_msgs[posix_abs(errnum)];
648}
649
650/**
651 * Get error message string.
652 *
653 * @param errnum Error code for which to obtain human readable string.
654 * @param buf Buffer to store a human readable string to.
655 * @param bufsz Size of buffer pointed to by buf.
656 * @return Zero on success, errno otherwise.
657 */
658int posix_strerror_r(int errnum, char *buf, size_t bufsz)
659{
660 assert(buf != NULL);
661
662 char *errstr = posix_strerror(errnum);
663
664 if (posix_strlen(errstr) + 1 > bufsz) {
665 return ERANGE;
666 } else {
667 posix_strcpy(buf, errstr);
668 }
669
670 return 0;
671}
672
673/**
674 * Get length of the string.
675 *
676 * @param s String which length shall be determined.
677 * @return Length of the string.
678 */
679size_t posix_strlen(const char *s)
680{
681 assert(s != NULL);
682
683 return (size_t) (posix_strchr(s, '\0') - s);
684}
685
686/**
687 * Get limited length of the string.
688 *
689 * @param s String which length shall be determined.
690 * @param n Maximum number of bytes that can be examined to determine length.
691 * @return The lower of either string length or n limit.
692 */
693size_t posix_strnlen(const char *s, size_t n)
694{
695 assert(s != NULL);
696
697 for (size_t sz = 0; sz < n; ++sz) {
698
699 if (s[sz] == '\0') {
700 return sz;
701 }
702 }
703
704 return n;
705}
706
707/**
708 * Get description of a signal.
709 *
710 * @param signum Signal number.
711 * @return Human readable signal description.
712 */
713char *posix_strsignal(int signum)
714{
715 static const char *const sigstrings[] = {
716 [SIGABRT] = "SIGABRT (Process abort signal)",
717 [SIGALRM] = "SIGALRM (Alarm clock)",
718 [SIGBUS] = "SIGBUS (Access to an undefined portion of a memory object)",
719 [SIGCHLD] = "SIGCHLD (Child process terminated, stopped, or continued)",
720 [SIGCONT] = "SIGCONT (Continue executing, if stopped)",
721 [SIGFPE] = "SIGFPE (Erroneous arithmetic operation)",
722 [SIGHUP] = "SIGHUP (Hangup)",
723 [SIGILL] = "SIGILL (Illegal instruction)",
724 [SIGINT] = "SIGINT (Terminal interrupt signal)",
725 [SIGKILL] = "SIGKILL (Kill process)",
726 [SIGPIPE] = "SIGPIPE (Write on a pipe with no one to read it)",
727 [SIGQUIT] = "SIGQUIT (Terminal quit signal)",
728 [SIGSEGV] = "SIGSEGV (Invalid memory reference)",
729 [SIGSTOP] = "SIGSTOP (Stop executing)",
730 [SIGTERM] = "SIGTERM (Termination signal)",
731 [SIGTSTP] = "SIGTSTP (Terminal stop signal)",
732 [SIGTTIN] = "SIGTTIN (Background process attempting read)",
733 [SIGTTOU] = "SIGTTOU (Background process attempting write)",
734 [SIGUSR1] = "SIGUSR1 (User-defined signal 1)",
735 [SIGUSR2] = "SIGUSR2 (User-defined signal 2)",
736 [SIGPOLL] = "SIGPOLL (Pollable event)",
737 [SIGPROF] = "SIGPROF (Profiling timer expired)",
738 [SIGSYS] = "SIGSYS (Bad system call)",
739 [SIGTRAP] = "SIGTRAP (Trace/breakpoint trap)",
740 [SIGURG] = "SIGURG (High bandwidth data is available at a socket)",
741 [SIGVTALRM] = "SIGVTALRM (Virtual timer expired)",
742 [SIGXCPU] = "SIGXCPU (CPU time limit exceeded)",
743 [SIGXFSZ] = "SIGXFSZ (File size limit exceeded)"
744 };
745
746 if (signum <= _TOP_SIGNAL) {
747 return (char *) sigstrings[signum];
748 }
749
750 return (char *) "ERROR, Invalid signal number";
751}
752
753/** @}
754 */
Note: See TracBrowser for help on using the repository browser.