aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-04-09 00:33:23 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-04-09 00:33:23 +0000
commitb12b1c87b590a4bcdcafc8c6bc221ae6390bee93 (patch)
tree67a01dbf5fb43c5bd4664eddcffa755c0679a338
parent79cedcb2c0d88531323e5c2a31fd8465241fbffa (diff)
downloadbusybox-w32-b12b1c87b590a4bcdcafc8c6bc221ae6390bee93.tar.gz
busybox-w32-b12b1c87b590a4bcdcafc8c6bc221ae6390bee93.tar.bz2
busybox-w32-b12b1c87b590a4bcdcafc8c6bc221ae6390bee93.zip
Splitting xfuncs.c into two parts. No code chabges.
-rw-r--r--libbb/Kbuild1
-rw-r--r--libbb/getopt32.c1
-rw-r--r--libbb/xfuncs.c531
3 files changed, 26 insertions, 507 deletions
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 11ae10d7d..3a68efc28 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -101,6 +101,7 @@ lib-y += wfopen_input.o
101lib-y += xatonum.o 101lib-y += xatonum.o
102lib-y += xconnect.o 102lib-y += xconnect.o
103lib-y += xfuncs.o 103lib-y += xfuncs.o
104lib-y += xfuncs_printf.o
104lib-y += xfunc_die.o 105lib-y += xfunc_die.o
105lib-y += xgetcwd.o 106lib-y += xgetcwd.o
106lib-y += xgethostbyname.o 107lib-y += xgethostbyname.o
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index c0d885603..cd890323e 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -560,6 +560,7 @@ getopt32(char **argv, const char *applet_opts, ...)
560 llist_add_to_end((llist_t **)(on_off->optarg), optarg); 560 llist_add_to_end((llist_t **)(on_off->optarg), optarg);
561 } else if (on_off->param_type == PARAM_INT) { 561 } else if (on_off->param_type == PARAM_INT) {
562 if (optarg) 562 if (optarg)
563//TODO: xatoi_u indirectly pulls in printf machinery
563 *(unsigned*)(on_off->optarg) = xatoi_u(optarg); 564 *(unsigned*)(on_off->optarg) = xatoi_u(optarg);
564 } else if (on_off->optarg) { 565 } else if (on_off->optarg) {
565 if (optarg) 566 if (optarg)
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 125063935..5298ee539 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -9,252 +9,38 @@
9 * Licensed under GPL version 2, see file LICENSE in this tarball for details. 9 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
10 */ 10 */
11 11
12#include "libbb.h" 12/* We need to have separate xfuncs.c and xfuncs_printf.c because
13 13 * with current linkers, even with section garbage collection,
14/* All the functions starting with "x" call bb_error_msg_and_die() if they 14 * if *.o module references any of XXXprintf functions, you pull in
15 * fail, so callers never need to check for errors. If it returned, it 15 * entire printf machinery. Even if you do not use the function
16 * succeeded. */ 16 * which uses XXXprintf.
17 17 *
18#ifndef DMALLOC 18 * xfuncs.c contains functions (not necessarily xfuncs)
19/* dmalloc provides variants of these that do abort() on failure. 19 * which do not pull in printf, directly or indirectly.
20 * Since dmalloc's prototypes overwrite the impls here as they are 20 * xfunc_printf.c contains those which do.
21 * included after these prototypes in libbb.h, all is well. 21 *
22 * TODO: move xmalloc() and xatonum() here.
22 */ 23 */
23// Warn if we can't allocate size bytes of memory.
24void *malloc_or_warn(size_t size)
25{
26 void *ptr = malloc(size);
27 if (ptr == NULL && size != 0)
28 bb_error_msg(bb_msg_memory_exhausted);
29 return ptr;
30}
31
32// Die if we can't allocate size bytes of memory.
33void *xmalloc(size_t size)
34{
35 void *ptr = malloc(size);
36 if (ptr == NULL && size != 0)
37 bb_error_msg_and_die(bb_msg_memory_exhausted);
38 return ptr;
39}
40
41// Die if we can't resize previously allocated memory. (This returns a pointer
42// to the new memory, which may or may not be the same as the old memory.
43// It'll copy the contents to a new chunk and free the old one if necessary.)
44void *xrealloc(void *ptr, size_t size)
45{
46 ptr = realloc(ptr, size);
47 if (ptr == NULL && size != 0)
48 bb_error_msg_and_die(bb_msg_memory_exhausted);
49 return ptr;
50}
51#endif /* DMALLOC */
52
53// Die if we can't allocate and zero size bytes of memory.
54void *xzalloc(size_t size)
55{
56 void *ptr = xmalloc(size);
57 memset(ptr, 0, size);
58 return ptr;
59}
60
61// Die if we can't copy a string to freshly allocated memory.
62char * xstrdup(const char *s)
63{
64 char *t;
65
66 if (s == NULL)
67 return NULL;
68
69 t = strdup(s);
70
71 if (t == NULL)
72 bb_error_msg_and_die(bb_msg_memory_exhausted);
73
74 return t;
75}
76
77// Die if we can't allocate n+1 bytes (space for the null terminator) and copy
78// the (possibly truncated to length n) string into it.
79char *xstrndup(const char *s, int n)
80{
81 int m;
82 char *t;
83
84 if (ENABLE_DEBUG && s == NULL)
85 bb_error_msg_and_die("xstrndup bug");
86
87 /* We can just xmalloc(n+1) and strncpy into it, */
88 /* but think about xstrndup("abc", 10000) wastage! */
89 m = n;
90 t = (char*) s;
91 while (m) {
92 if (!*t) break;
93 m--;
94 t++;
95 }
96 n -= m;
97 t = xmalloc(n + 1);
98 t[n] = '\0';
99
100 return memcpy(t, s, n);
101}
102
103// Die if we can't open a file and return a FILE * to it.
104// Notice we haven't got xfread(), This is for use with fscanf() and friends.
105FILE *xfopen(const char *path, const char *mode)
106{
107 FILE *fp = fopen(path, mode);
108 if (fp == NULL)
109 bb_perror_msg_and_die("can't open '%s'", path);
110 return fp;
111}
112
113// Die if we can't open a file and return a fd.
114int xopen3(const char *pathname, int flags, int mode)
115{
116 int ret;
117
118 ret = open(pathname, flags, mode);
119 if (ret < 0) {
120 bb_perror_msg_and_die("can't open '%s'", pathname);
121 }
122 return ret;
123}
124
125// Die if we can't open an existing file and return a fd.
126int xopen(const char *pathname, int flags)
127{
128 return xopen3(pathname, flags, 0666);
129}
130
131// Warn if we can't open a file and return a fd.
132int open3_or_warn(const char *pathname, int flags, int mode)
133{
134 int ret;
135
136 ret = open(pathname, flags, mode);
137 if (ret < 0) {
138 bb_perror_msg("can't open '%s'", pathname);
139 }
140 return ret;
141}
142
143// Warn if we can't open a file and return a fd.
144int open_or_warn(const char *pathname, int flags)
145{
146 return open3_or_warn(pathname, flags, 0666);
147}
148
149void xunlink(const char *pathname)
150{
151 if (unlink(pathname))
152 bb_perror_msg_and_die("can't remove file '%s'", pathname);
153}
154
155void xrename(const char *oldpath, const char *newpath)
156{
157 if (rename(oldpath, newpath))
158 bb_perror_msg_and_die("can't move '%s' to '%s'", oldpath, newpath);
159}
160
161int rename_or_warn(const char *oldpath, const char *newpath)
162{
163 int n = rename(oldpath, newpath);
164 if (n)
165 bb_perror_msg("can't move '%s' to '%s'", oldpath, newpath);
166 return n;
167}
168 24
169void xpipe(int filedes[2]) 25#include "libbb.h"
170{
171 if (pipe(filedes))
172 bb_perror_msg_and_die("can't create pipe");
173}
174 26
175// Turn on nonblocking I/O on a fd 27/* Turn on nonblocking I/O on a fd */
176int ndelay_on(int fd) 28int ndelay_on(int fd)
177{ 29{
178 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) | O_NONBLOCK); 30 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) | O_NONBLOCK);
179} 31}
180 32
181int close_on_exec_on(int fd)
182{
183 return fcntl(fd, F_SETFD, FD_CLOEXEC);
184}
185
186int ndelay_off(int fd) 33int ndelay_off(int fd)
187{ 34{
188 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) & ~O_NONBLOCK); 35 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) & ~O_NONBLOCK);
189} 36}
190 37
191void xdup2(int from, int to) 38int close_on_exec_on(int fd)
192{
193 if (dup2(from, to) != to)
194 bb_perror_msg_and_die("can't duplicate file descriptor");
195}
196
197// "Renumber" opened fd
198void xmove_fd(int from, int to)
199{
200 if (from == to)
201 return;
202 xdup2(from, to);
203 close(from);
204}
205
206// Die with an error message if we can't write the entire buffer.
207void xwrite(int fd, const void *buf, size_t count)
208{
209 if (count) {
210 ssize_t size = full_write(fd, buf, count);
211 if (size != count)
212 bb_error_msg_and_die("short write");
213 }
214}
215
216// Die with an error message if we can't lseek to the right spot.
217off_t xlseek(int fd, off_t offset, int whence)
218{
219 off_t off = lseek(fd, offset, whence);
220 if (off == (off_t)-1) {
221 if (whence == SEEK_SET)
222 bb_perror_msg_and_die("lseek(%"OFF_FMT"u)", offset);
223 bb_perror_msg_and_die("lseek");
224 }
225 return off;
226}
227
228// Die with supplied filename if this FILE * has ferror set.
229void die_if_ferror(FILE *fp, const char *fn)
230{
231 if (ferror(fp)) {
232 /* ferror doesn't set useful errno */
233 bb_error_msg_and_die("%s: I/O error", fn);
234 }
235}
236
237// Die with an error message if stdout has ferror set.
238void die_if_ferror_stdout(void)
239{
240 die_if_ferror(stdout, bb_msg_standard_output);
241}
242
243// Die with an error message if we have trouble flushing stdout.
244void xfflush_stdout(void)
245{
246 if (fflush(stdout)) {
247 bb_perror_msg_and_die(bb_msg_standard_output);
248 }
249}
250
251void xsetenv(const char *key, const char *value)
252{ 39{
253 if (setenv(key, value, 1)) 40 return fcntl(fd, F_SETFD, FD_CLOEXEC);
254 bb_error_msg_and_die(bb_msg_memory_exhausted);
255} 41}
256 42
257/* Converts unsigned long long value into compact 4-char 43/* Convert unsigned long long value into compact 4-char
258 * representation. Examples: "1234", "1.2k", " 27M", "123T" 44 * representation. Examples: "1234", "1.2k", " 27M", "123T"
259 * String is not terminated (buf[4] is untouched) */ 45 * String is not terminated (buf[4] is untouched) */
260void smart_ulltoa4(unsigned long long ul, char buf[5], const char *scale) 46void smart_ulltoa4(unsigned long long ul, char buf[5], const char *scale)
@@ -303,7 +89,7 @@ void smart_ulltoa4(unsigned long long ul, char buf[5], const char *scale)
303 } 89 }
304} 90}
305 91
306/* Converts unsigned long long value into compact 5-char representation. 92/* Convert unsigned long long value into compact 5-char representation.
307 * String is not terminated (buf[5] is untouched) */ 93 * String is not terminated (buf[5] is untouched) */
308void smart_ulltoa5(unsigned long long ul, char buf[6], const char *scale) 94void smart_ulltoa5(unsigned long long ul, char buf[6], const char *scale)
309{ 95{
@@ -383,7 +169,7 @@ char *utoa_to_buf(unsigned n, char *buf, unsigned buflen)
383 return buf; 169 return buf;
384} 170}
385 171
386// Convert signed integer to ascii, like utoa_to_buf() 172/* Convert signed integer to ascii, like utoa_to_buf() */
387char *itoa_to_buf(int n, char *buf, unsigned buflen) 173char *itoa_to_buf(int n, char *buf, unsigned buflen)
388{ 174{
389 if (buflen && n<0) { 175 if (buflen && n<0) {
@@ -398,10 +184,10 @@ char *itoa_to_buf(int n, char *buf, unsigned buflen)
398// second time will overwrite previous results. 184// second time will overwrite previous results.
399// 185//
400// The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes. 186// The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes.
401// Int should always be 32 bits on any remotely Unix-like system, see 187// It so happens that sizeof(int) * 3 is enough for 32+ bits.
402// http://www.unix.org/whitepapers/64bit.html for the reasons why. 188// (sizeof(int) * 3 + 2 is correct for any width, even 8-bit)
403 189
404static char local_buf[12]; 190static char local_buf[sizeof(int) * 3];
405 191
406// Convert unsigned integer to ascii using a static buffer (returned). 192// Convert unsigned integer to ascii using a static buffer (returned).
407char *utoa(unsigned n) 193char *utoa(unsigned n)
@@ -411,7 +197,7 @@ char *utoa(unsigned n)
411 return local_buf; 197 return local_buf;
412} 198}
413 199
414// Convert signed integer to ascii using a static buffer (returned). 200/* Convert signed integer to ascii using a static buffer (returned). */
415char *itoa(int n) 201char *itoa(int n)
416{ 202{
417 *(itoa_to_buf(n, local_buf, sizeof(local_buf))) = '\0'; 203 *(itoa_to_buf(n, local_buf, sizeof(local_buf))) = '\0';
@@ -419,7 +205,7 @@ char *itoa(int n)
419 return local_buf; 205 return local_buf;
420} 206}
421 207
422// Emit a string of hex representation of bytes 208/* Emit a string of hex representation of bytes */
423char *bin2hex(char *p, const char *cp, int count) 209char *bin2hex(char *p, const char *cp, int count)
424{ 210{
425 while (count) { 211 while (count) {
@@ -432,21 +218,7 @@ char *bin2hex(char *p, const char *cp, int count)
432 return p; 218 return p;
433} 219}
434 220
435// Die with an error message if we can't set gid. (Because resource limits may 221/* Return how long the file at fd is, if there's any way to determine it. */
436// limit this user to a given number of processes, and if that fills up the
437// setgid() will fail and we'll _still_be_root_, which is bad.)
438void xsetgid(gid_t gid)
439{
440 if (setgid(gid)) bb_perror_msg_and_die("setgid");
441}
442
443// Die with an error message if we can't set uid. (See xsetgid() for why.)
444void xsetuid(uid_t uid)
445{
446 if (setuid(uid)) bb_perror_msg_and_die("setuid");
447}
448
449// Return how long the file at fd is, if there's any way to determine it.
450#ifdef UNUSED 222#ifdef UNUSED
451off_t fdlength(int fd) 223off_t fdlength(int fd)
452{ 224{
@@ -488,192 +260,6 @@ off_t fdlength(int fd)
488} 260}
489#endif 261#endif
490 262
491int bb_putchar(int ch)
492{
493 /* time.c needs putc(ch, stdout), not putchar(ch).
494 * it does "stdout = stderr;", but then glibc's putchar()
495 * doesn't work as expected. bad glibc, bad */
496 return putc(ch, stdout);
497}
498
499// Die with an error message if we can't malloc() enough space and do an
500// sprintf() into that space.
501char *xasprintf(const char *format, ...)
502{
503 va_list p;
504 int r;
505 char *string_ptr;
506
507#if 1
508 // GNU extension
509 va_start(p, format);
510 r = vasprintf(&string_ptr, format, p);
511 va_end(p);
512#else
513 // Bloat for systems that haven't got the GNU extension.
514 va_start(p, format);
515 r = vsnprintf(NULL, 0, format, p);
516 va_end(p);
517 string_ptr = xmalloc(r+1);
518 va_start(p, format);
519 r = vsnprintf(string_ptr, r+1, format, p);
520 va_end(p);
521#endif
522
523 if (r < 0)
524 bb_error_msg_and_die(bb_msg_memory_exhausted);
525 return string_ptr;
526}
527
528#if 0 /* If we will ever meet a libc which hasn't [f]dprintf... */
529int fdprintf(int fd, const char *format, ...)
530{
531 va_list p;
532 int r;
533 char *string_ptr;
534
535#if 1
536 // GNU extension
537 va_start(p, format);
538 r = vasprintf(&string_ptr, format, p);
539 va_end(p);
540#else
541 // Bloat for systems that haven't got the GNU extension.
542 va_start(p, format);
543 r = vsnprintf(NULL, 0, format, p) + 1;
544 va_end(p);
545 string_ptr = malloc(r);
546 if (string_ptr) {
547 va_start(p, format);
548 r = vsnprintf(string_ptr, r, format, p);
549 va_end(p);
550 }
551#endif
552
553 if (r >= 0) {
554 full_write(fd, string_ptr, r);
555 free(string_ptr);
556 }
557 return r;
558}
559#endif
560
561// Die with an error message if we can't copy an entire FILE * to stdout, then
562// close that file.
563void xprint_and_close_file(FILE *file)
564{
565 fflush(stdout);
566 // copyfd outputs error messages for us.
567 if (bb_copyfd_eof(fileno(file), 1) == -1)
568 xfunc_die();
569
570 fclose(file);
571}
572
573// Die if we can't chdir to a new path.
574void xchdir(const char *path)
575{
576 if (chdir(path))
577 bb_perror_msg_and_die("chdir(%s)", path);
578}
579
580void xchroot(const char *path)
581{
582 if (chroot(path))
583 bb_perror_msg_and_die("can't change root directory to %s", path);
584}
585
586// Print a warning message if opendir() fails, but don't die.
587DIR *warn_opendir(const char *path)
588{
589 DIR *dp;
590
591 dp = opendir(path);
592 if (!dp)
593 bb_perror_msg("can't open '%s'", path);
594 return dp;
595}
596
597// Die with an error message if opendir() fails.
598DIR *xopendir(const char *path)
599{
600 DIR *dp;
601
602 dp = opendir(path);
603 if (!dp)
604 bb_perror_msg_and_die("can't open '%s'", path);
605 return dp;
606}
607
608// Die with an error message if we can't open a new socket.
609int xsocket(int domain, int type, int protocol)
610{
611 int r = socket(domain, type, protocol);
612
613 if (r < 0) {
614 /* Hijack vaguely related config option */
615#if ENABLE_VERBOSE_RESOLUTION_ERRORS
616 const char *s = "INET";
617 if (domain == AF_PACKET) s = "PACKET";
618 if (domain == AF_NETLINK) s = "NETLINK";
619USE_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)
620 bb_perror_msg_and_die("socket(AF_%s)", s);
621#else
622 bb_perror_msg_and_die("socket");
623#endif
624 }
625
626 return r;
627}
628
629// Die with an error message if we can't bind a socket to an address.
630void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
631{
632 if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind");
633}
634
635// Die with an error message if we can't listen for connections on a socket.
636void xlisten(int s, int backlog)
637{
638 if (listen(s, backlog)) bb_perror_msg_and_die("listen");
639}
640
641/* Die with an error message if sendto failed.
642 * Return bytes sent otherwise */
643ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
644 socklen_t tolen)
645{
646 ssize_t ret = sendto(s, buf, len, 0, to, tolen);
647 if (ret < 0) {
648 if (ENABLE_FEATURE_CLEAN_UP)
649 close(s);
650 bb_perror_msg_and_die("sendto");
651 }
652 return ret;
653}
654
655// xstat() - a stat() which dies on failure with meaningful error message
656void xstat(const char *name, struct stat *stat_buf)
657{
658 if (stat(name, stat_buf))
659 bb_perror_msg_and_die("can't stat '%s'", name);
660}
661
662// selinux_or_die() - die if SELinux is disabled.
663void selinux_or_die(void)
664{
665#if ENABLE_SELINUX
666 int rc = is_selinux_enabled();
667 if (rc == 0) {
668 bb_error_msg_and_die("SELinux is disabled");
669 } else if (rc < 0) {
670 bb_error_msg_and_die("is_selinux_enabled() failed");
671 }
672#else
673 bb_error_msg_and_die("SELinux support is disabled");
674#endif
675}
676
677/* It is perfectly ok to pass in a NULL for either width or for 263/* It is perfectly ok to pass in a NULL for either width or for
678 * height, in which case that value will not be set. */ 264 * height, in which case that value will not be set. */
679int get_terminal_width_height(int fd, int *width, int *height) 265int get_terminal_width_height(int fd, int *width, int *height)
@@ -703,72 +289,3 @@ int get_terminal_width_height(int fd, int *width, int *height)
703 289
704 return ret; 290 return ret;
705} 291}
706
707int ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...)
708{
709 int ret;
710 va_list p;
711
712 ret = ioctl(fd, request, argp);
713 if (ret < 0) {
714 va_start(p, fmt);
715 bb_verror_msg(fmt, p, strerror(errno));
716 /* xfunc_die can actually longjmp, so be nice */
717 va_end(p);
718 xfunc_die();
719 }
720 return ret;
721}
722
723int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...)
724{
725 va_list p;
726 int ret = ioctl(fd, request, argp);
727
728 if (ret < 0) {
729 va_start(p, fmt);
730 bb_verror_msg(fmt, p, strerror(errno));
731 va_end(p);
732 }
733 return ret;
734}
735
736#if ENABLE_IOCTL_HEX2STR_ERROR
737int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name)
738{
739 int ret;
740
741 ret = ioctl(fd, request, argp);
742 if (ret < 0)
743 bb_simple_perror_msg(ioctl_name);
744 return ret;
745}
746int bb_xioctl(int fd, int request, void *argp, const char *ioctl_name)
747{
748 int ret;
749
750 ret = ioctl(fd, request, argp);
751 if (ret < 0)
752 bb_simple_perror_msg_and_die(ioctl_name);
753 return ret;
754}
755#else
756int bb_ioctl_or_warn(int fd, int request, void *argp)
757{
758 int ret;
759
760 ret = ioctl(fd, request, argp);
761 if (ret < 0)
762 bb_perror_msg("ioctl %#x failed", request);
763 return ret;
764}
765int bb_xioctl(int fd, int request, void *argp)
766{
767 int ret;
768
769 ret = ioctl(fd, request, argp);
770 if (ret < 0)
771 bb_perror_msg_and_die("ioctl %#x failed", request);
772 return ret;
773}
774#endif