source: MondoRescue/branches/2.2.5/mindi-busybox/libbb/xfuncs.c@ 1765

Last change on this file since 1765 was 1765, checked in by Bruno Cornec, 16 years ago

Update to busybox 1.7.2

File size: 15.7 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 * Copyright (C) 2006 Rob Landley
7 * Copyright (C) 2006 Denis Vlasenko
8 *
9 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
10 */
11
12#include "libbb.h"
13
14/* All the functions starting with "x" call bb_error_msg_and_die() if they
15 * fail, so callers never need to check for errors. If it returned, it
16 * succeeded. */
17
18#ifndef DMALLOC
19/* dmalloc provides variants of these that do abort() on failure.
20 * Since dmalloc's prototypes overwrite the impls here as they are
21 * included after these prototypes in libbb.h, all is well.
22 */
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 xpipe(int filedes[2])
150{
151 if (pipe(filedes))
152 bb_perror_msg_and_die("can't create pipe");
153}
154
155void xunlink(const char *pathname)
156{
157 if (unlink(pathname))
158 bb_perror_msg_and_die("can't remove file '%s'", pathname);
159}
160
161// Turn on nonblocking I/O on a fd
162int ndelay_on(int fd)
163{
164 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) | O_NONBLOCK);
165}
166
167int ndelay_off(int fd)
168{
169 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) & ~O_NONBLOCK);
170}
171
172void xdup2(int from, int to)
173{
174 if (dup2(from, to) != to)
175 bb_perror_msg_and_die("can't duplicate file descriptor");
176}
177
178// "Renumber" opened fd
179void xmove_fd(int from, int to)
180{
181 if (from == to)
182 return;
183 xdup2(from, to);
184 close(from);
185}
186
187// Die with an error message if we can't write the entire buffer.
188void xwrite(int fd, const void *buf, size_t count)
189{
190 if (count) {
191 ssize_t size = full_write(fd, buf, count);
192 if (size != count)
193 bb_error_msg_and_die("short write");
194 }
195}
196
197// Die with an error message if we can't lseek to the right spot.
198off_t xlseek(int fd, off_t offset, int whence)
199{
200 off_t off = lseek(fd, offset, whence);
201 if (off == (off_t)-1) {
202 if (whence == SEEK_SET)
203 bb_perror_msg_and_die("lseek(%"OFF_FMT"u)", offset);
204 bb_perror_msg_and_die("lseek");
205 }
206 return off;
207}
208
209// Die with supplied filename if this FILE * has ferror set.
210void die_if_ferror(FILE *fp, const char *fn)
211{
212 if (ferror(fp)) {
213 /* ferror doesn't set useful errno */
214 bb_error_msg_and_die("%s: I/O error", fn);
215 }
216}
217
218// Die with an error message if stdout has ferror set.
219void die_if_ferror_stdout(void)
220{
221 die_if_ferror(stdout, bb_msg_standard_output);
222}
223
224// Die with an error message if we have trouble flushing stdout.
225void xfflush_stdout(void)
226{
227 if (fflush(stdout)) {
228 bb_perror_msg_and_die(bb_msg_standard_output);
229 }
230}
231
232void sig_block(int sig)
233{
234 sigset_t ss;
235 sigemptyset(&ss);
236 sigaddset(&ss, sig);
237 sigprocmask(SIG_BLOCK, &ss, NULL);
238}
239
240void sig_unblock(int sig)
241{
242 sigset_t ss;
243 sigemptyset(&ss);
244 sigaddset(&ss, sig);
245 sigprocmask(SIG_UNBLOCK, &ss, NULL);
246}
247
248#if 0
249void sig_blocknone(void)
250{
251 sigset_t ss;
252 sigemptyset(&ss);
253 sigprocmask(SIG_SETMASK, &ss, NULL);
254}
255#endif
256
257void sig_catch(int sig, void (*f)(int))
258{
259 struct sigaction sa;
260 sa.sa_handler = f;
261 sa.sa_flags = 0;
262 sigemptyset(&sa.sa_mask);
263 sigaction(sig, &sa, NULL);
264}
265
266void sig_pause(void)
267{
268 sigset_t ss;
269 sigemptyset(&ss);
270 sigsuspend(&ss);
271}
272
273
274void xsetenv(const char *key, const char *value)
275{
276 if (setenv(key, value, 1))
277 bb_error_msg_and_die(bb_msg_memory_exhausted);
278}
279
280// Converts unsigned long long value into compact 4-char
281// representation. Examples: "1234", "1.2k", " 27M", "123T"
282// Fifth char is always '\0'
283void smart_ulltoa5(unsigned long long ul, char buf[5])
284{
285 const char *fmt;
286 char c;
287 unsigned v,idx = 0;
288 ul *= 10;
289 if (ul > 9999*10) { // do not scale if 9999 or less
290 while (ul >= 10000) {
291 ul /= 1024;
292 idx++;
293 }
294 }
295 v = ul; // ullong divisions are expensive, avoid them
296
297 fmt = " 123456789";
298 if (!idx) { // 9999 or less: use 1234 format
299 c = buf[0] = " 123456789"[v/10000];
300 if (c != ' ') fmt = "0123456789";
301 c = buf[1] = fmt[v/1000%10];
302 if (c != ' ') fmt = "0123456789";
303 buf[2] = fmt[v/100%10];
304 buf[3] = "0123456789"[v/10%10];
305 } else {
306 if (v >= 10*10) { // scaled value is >=10: use 123M format
307 c = buf[0] = " 123456789"[v/1000];
308 if (c != ' ') fmt = "0123456789";
309 buf[1] = fmt[v/100%10];
310 buf[2] = "0123456789"[v/10%10];
311 } else { // scaled value is <10: use 1.2M format
312 buf[0] = "0123456789"[v/10];
313 buf[1] = '.';
314 buf[2] = "0123456789"[v%10];
315 }
316 // see http://en.wikipedia.org/wiki/Tera
317 buf[3] = " kMGTPEZY"[idx];
318 }
319 buf[4] = '\0';
320}
321
322// Convert unsigned integer to ascii, writing into supplied buffer.
323// A truncated result contains the first few digits of the result ala strncpy.
324// Returns a pointer past last generated digit, does _not_ store NUL.
325void BUG_sizeof_unsigned_not_4(void);
326char *utoa_to_buf(unsigned n, char *buf, unsigned buflen)
327{
328 unsigned i, out, res;
329 if (sizeof(unsigned) != 4)
330 BUG_sizeof_unsigned_not_4();
331 if (buflen) {
332 out = 0;
333 for (i = 1000000000; i; i /= 10) {
334 res = n / i;
335 if (res || out || i == 1) {
336 if (!--buflen) break;
337 out++;
338 n -= res*i;
339 *buf++ = '0' + res;
340 }
341 }
342 }
343 return buf;
344}
345
346// Convert signed integer to ascii, like utoa_to_buf()
347char *itoa_to_buf(int n, char *buf, unsigned buflen)
348{
349 if (buflen && n<0) {
350 n = -n;
351 *buf++ = '-';
352 buflen--;
353 }
354 return utoa_to_buf((unsigned)n, buf, buflen);
355}
356
357// The following two functions use a static buffer, so calling either one a
358// second time will overwrite previous results.
359//
360// The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes.
361// Int should always be 32 bits on any remotely Unix-like system, see
362// http://www.unix.org/whitepapers/64bit.html for the reasons why.
363
364static char local_buf[12];
365
366// Convert unsigned integer to ascii using a static buffer (returned).
367char *utoa(unsigned n)
368{
369 *(utoa_to_buf(n, local_buf, sizeof(local_buf))) = '\0';
370
371 return local_buf;
372}
373
374// Convert signed integer to ascii using a static buffer (returned).
375char *itoa(int n)
376{
377 *(itoa_to_buf(n, local_buf, sizeof(local_buf))) = '\0';
378
379 return local_buf;
380}
381
382// Emit a string of hex representation of bytes
383char *bin2hex(char *p, const char *cp, int count)
384{
385 while (count) {
386 unsigned char c = *cp++;
387 /* put lowercase hex digits */
388 *p++ = 0x20 | bb_hexdigits_upcase[c >> 4];
389 *p++ = 0x20 | bb_hexdigits_upcase[c & 0xf];
390 count--;
391 }
392 return p;
393}
394
395// Die with an error message if we can't set gid. (Because resource limits may
396// limit this user to a given number of processes, and if that fills up the
397// setgid() will fail and we'll _still_be_root_, which is bad.)
398void xsetgid(gid_t gid)
399{
400 if (setgid(gid)) bb_perror_msg_and_die("setgid");
401}
402
403// Die with an error message if we can't set uid. (See xsetgid() for why.)
404void xsetuid(uid_t uid)
405{
406 if (setuid(uid)) bb_perror_msg_and_die("setuid");
407}
408
409// Return how long the file at fd is, if there's any way to determine it.
410off_t fdlength(int fd)
411{
412 off_t bottom = 0, top = 0, pos;
413 long size;
414
415 // If the ioctl works for this, return it.
416
417 if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512;
418
419 // FIXME: explain why lseek(SEEK_END) is not used here!
420
421 // If not, do a binary search for the last location we can read. (Some
422 // block devices don't do BLKGETSIZE right.)
423
424 do {
425 char temp;
426
427 pos = bottom + (top - bottom) / 2;
428
429 // If we can read from the current location, it's bigger.
430
431 if (lseek(fd, pos, SEEK_SET)>=0 && safe_read(fd, &temp, 1)==1) {
432 if (bottom == top) bottom = top = (top+1) * 2;
433 else bottom = pos;
434
435 // If we can't, it's smaller.
436
437 } else {
438 if (bottom == top) {
439 if (!top) return 0;
440 bottom = top/2;
441 }
442 else top = pos;
443 }
444 } while (bottom + 1 != top);
445
446 return pos + 1;
447}
448
449// Die with an error message if we can't malloc() enough space and do an
450// sprintf() into that space.
451char *xasprintf(const char *format, ...)
452{
453 va_list p;
454 int r;
455 char *string_ptr;
456
457#if 1
458 // GNU extension
459 va_start(p, format);
460 r = vasprintf(&string_ptr, format, p);
461 va_end(p);
462#else
463 // Bloat for systems that haven't got the GNU extension.
464 va_start(p, format);
465 r = vsnprintf(NULL, 0, format, p);
466 va_end(p);
467 string_ptr = xmalloc(r+1);
468 va_start(p, format);
469 r = vsnprintf(string_ptr, r+1, format, p);
470 va_end(p);
471#endif
472
473 if (r < 0) bb_error_msg_and_die(bb_msg_memory_exhausted);
474 return string_ptr;
475}
476
477#if 0 /* If we will ever meet a libc which hasn't [f]dprintf... */
478int fdprintf(int fd, const char *format, ...)
479{
480 va_list p;
481 int r;
482 char *string_ptr;
483
484#if 1
485 // GNU extension
486 va_start(p, format);
487 r = vasprintf(&string_ptr, format, p);
488 va_end(p);
489#else
490 // Bloat for systems that haven't got the GNU extension.
491 va_start(p, format);
492 r = vsnprintf(NULL, 0, format, p) + 1;
493 va_end(p);
494 string_ptr = malloc(r);
495 if (string_ptr) {
496 va_start(p, format);
497 r = vsnprintf(string_ptr, r, format, p);
498 va_end(p);
499 }
500#endif
501
502 if (r >= 0) {
503 full_write(fd, string_ptr, r);
504 free(string_ptr);
505 }
506 return r;
507}
508#endif
509
510// Die with an error message if we can't copy an entire FILE * to stdout, then
511// close that file.
512void xprint_and_close_file(FILE *file)
513{
514 fflush(stdout);
515 // copyfd outputs error messages for us.
516 if (bb_copyfd_eof(fileno(file), 1) == -1)
517 xfunc_die();
518
519 fclose(file);
520}
521
522// Die if we can't chdir to a new path.
523void xchdir(const char *path)
524{
525 if (chdir(path))
526 bb_perror_msg_and_die("chdir(%s)", path);
527}
528
529// Print a warning message if opendir() fails, but don't die.
530DIR *warn_opendir(const char *path)
531{
532 DIR *dp;
533
534 dp = opendir(path);
535 if (!dp)
536 bb_perror_msg("can't open '%s'", path);
537 return dp;
538}
539
540// Die with an error message if opendir() fails.
541DIR *xopendir(const char *path)
542{
543 DIR *dp;
544
545 dp = opendir(path);
546 if (!dp)
547 bb_perror_msg_and_die("can't open '%s'", path);
548 return dp;
549}
550
551// Die with an error message if we can't open a new socket.
552int xsocket(int domain, int type, int protocol)
553{
554 int r = socket(domain, type, protocol);
555
556 if (r < 0) {
557 /* Hijack vaguely related config option */
558#if ENABLE_VERBOSE_RESOLUTION_ERRORS
559 const char *s = "INET";
560 if (domain == AF_PACKET) s = "PACKET";
561 if (domain == AF_NETLINK) s = "NETLINK";
562USE_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)
563 bb_perror_msg_and_die("socket(AF_%s)", s);
564#else
565 bb_perror_msg_and_die("socket");
566#endif
567 }
568
569 return r;
570}
571
572// Die with an error message if we can't bind a socket to an address.
573void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
574{
575 if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind");
576}
577
578// Die with an error message if we can't listen for connections on a socket.
579void xlisten(int s, int backlog)
580{
581 if (listen(s, backlog)) bb_perror_msg_and_die("listen");
582}
583
584/* Die with an error message if sendto failed.
585 * Return bytes sent otherwise */
586ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
587 socklen_t tolen)
588{
589 ssize_t ret = sendto(s, buf, len, 0, to, tolen);
590 if (ret < 0) {
591 if (ENABLE_FEATURE_CLEAN_UP)
592 close(s);
593 bb_perror_msg_and_die("sendto");
594 }
595 return ret;
596}
597
598// xstat() - a stat() which dies on failure with meaningful error message
599void xstat(const char *name, struct stat *stat_buf)
600{
601 if (stat(name, stat_buf))
602 bb_perror_msg_and_die("can't stat '%s'", name);
603}
604
605// selinux_or_die() - die if SELinux is disabled.
606void selinux_or_die(void)
607{
608#if ENABLE_SELINUX
609 int rc = is_selinux_enabled();
610 if (rc == 0) {
611 bb_error_msg_and_die("SELinux is disabled");
612 } else if (rc < 0) {
613 bb_error_msg_and_die("is_selinux_enabled() failed");
614 }
615#else
616 bb_error_msg_and_die("SELinux support is disabled");
617#endif
618}
619
620/* It is perfectly ok to pass in a NULL for either width or for
621 * height, in which case that value will not be set. */
622int get_terminal_width_height(int fd, int *width, int *height)
623{
624 struct winsize win = { 0, 0, 0, 0 };
625 int ret = ioctl(fd, TIOCGWINSZ, &win);
626
627 if (height) {
628 if (!win.ws_row) {
629 char *s = getenv("LINES");
630 if (s) win.ws_row = atoi(s);
631 }
632 if (win.ws_row <= 1 || win.ws_row >= 30000)
633 win.ws_row = 24;
634 *height = (int) win.ws_row;
635 }
636
637 if (width) {
638 if (!win.ws_col) {
639 char *s = getenv("COLUMNS");
640 if (s) win.ws_col = atoi(s);
641 }
642 if (win.ws_col <= 1 || win.ws_col >= 30000)
643 win.ws_col = 80;
644 *width = (int) win.ws_col;
645 }
646
647 return ret;
648}
649
650void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...)
651{
652 va_list p;
653
654 if (ioctl(fd, request, argp) < 0) {
655 va_start(p, fmt);
656 bb_verror_msg(fmt, p, strerror(errno));
657 /* xfunc_die can actually longjmp, so be nice */
658 va_end(p);
659 xfunc_die();
660 }
661}
662
663int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...)
664{
665 va_list p;
666 int ret = ioctl(fd, request, argp);
667
668 if (ret < 0) {
669 va_start(p, fmt);
670 bb_verror_msg(fmt, p, strerror(errno));
671 va_end(p);
672 }
673 return ret;
674}
675
676#if ENABLE_IOCTL_HEX2STR_ERROR
677int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name)
678{
679 int ret;
680
681 ret = ioctl(fd, request, argp);
682 if (ret < 0)
683 bb_perror_msg("%s", ioctl_name);
684 return ret;
685}
686void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name)
687{
688 if (ioctl(fd, request, argp) < 0)
689 bb_perror_msg_and_die("%s", ioctl_name);
690}
691#else
692int bb_ioctl_or_warn(int fd, int request, void *argp)
693{
694 int ret;
695
696 ret = ioctl(fd, request, argp);
697 if (ret < 0)
698 bb_perror_msg("ioctl %#x failed", request);
699 return ret;
700}
701void bb_xioctl(int fd, int request, void *argp)
702{
703 if (ioctl(fd, request, argp) < 0)
704 bb_perror_msg_and_die("ioctl %#x failed", request);
705}
706#endif
Note: See TracBrowser for help on using the repository browser.