Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/libbb/xfuncs.c
- Timestamp:
- Nov 4, 2007, 3:16:40 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.5/mindi-busybox/libbb/xfuncs.c
r821 r1765 4 4 * 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 * Copyright (C) 2006 Rob Landley 7 * Copyright (C) 2006 Denis Vlasenko 6 8 * 7 * Licensed under GPL v2 or later, see file LICENSE in this tarball for details.9 * Licensed under GPL version 2, see file LICENSE in this tarball for details. 8 10 */ 9 11 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #include <sys/wait.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <stdlib.h> 16 #include <unistd.h> 17 #include <fcntl.h> 18 #include "busybox.h" 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. */ 19 17 20 18 #ifndef DMALLOC 21 #ifdef L_xmalloc 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. 24 void *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. 22 33 void *xmalloc(size_t size) 23 34 { … … 27 38 return ptr; 28 39 } 29 #endif 30 31 #ifdef L_xrealloc 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.) 32 44 void *xrealloc(void *ptr, size_t size) 33 45 { … … 37 49 return ptr; 38 50 } 39 #endif 40 41 #ifdef L_xzalloc 51 #endif /* DMALLOC */ 52 53 // Die if we can't allocate and zero size bytes of memory. 42 54 void *xzalloc(size_t size) 43 55 { … … 46 58 return ptr; 47 59 } 48 #endif 49 50 #ifdef L_xcalloc 51 void *xcalloc(size_t nmemb, size_t size) 52 { 53 void *ptr = calloc(nmemb, size); 54 if (ptr == NULL && nmemb != 0 && size != 0) 55 bb_error_msg_and_die(bb_msg_memory_exhausted); 56 return ptr; 57 } 58 #endif 59 #endif /* DMALLOC */ 60 61 #ifdef L_xstrdup 62 char * bb_xstrdup (const char *s) 60 61 // Die if we can't copy a string to freshly allocated memory. 62 char * xstrdup(const char *s) 63 63 { 64 64 char *t; … … 67 67 return NULL; 68 68 69 t = strdup 69 t = strdup(s); 70 70 71 71 if (t == NULL) … … 74 74 return t; 75 75 } 76 #endif 77 78 #ifdef L_xstrndup 79 char * bb_xstrndup (const char *s, int n) 80 { 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. 79 char * xstrndup(const char *s, int n) 80 { 81 int m; 81 82 char *t; 82 83 83 84 if (ENABLE_DEBUG && s == NULL) 84 bb_error_msg_and_die("bb_xstrndup bug"); 85 86 t = xmalloc(++n); 87 88 return safe_strncpy(t,s,n); 89 } 90 #endif 91 92 #ifdef L_xfopen 93 FILE *bb_xfopen(const char *path, const char *mode) 94 { 95 FILE *fp; 96 if ((fp = fopen(path, mode)) == NULL) 97 bb_perror_msg_and_die("%s", path); 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. 105 FILE *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); 98 110 return fp; 99 111 } 100 #endif 101 102 #ifdef L_xopen 103 int bb_xopen(const char *pathname, int flags) 104 { 105 return bb_xopen3(pathname, flags, 0777); 106 } 107 #endif 108 109 #ifdef L_xopen3 110 int bb_xopen3(const char *pathname, int flags, int mode) 112 113 // Die if we can't open a file and return a fd. 114 int xopen3(const char *pathname, int flags, int mode) 111 115 { 112 116 int ret; … … 114 118 ret = open(pathname, flags, mode); 115 119 if (ret < 0) { 116 bb_perror_msg_and_die(" %s", pathname);120 bb_perror_msg_and_die("can't open '%s'", pathname); 117 121 } 118 122 return ret; 119 123 } 120 #endif 121 122 #ifdef L_xread 123 ssize_t bb_xread(int fd, void *buf, size_t count) 124 { 125 ssize_t size; 126 127 size = read(fd, buf, count); 128 if (size < 0) { 129 bb_perror_msg_and_die(bb_msg_read_error); 130 } 131 return(size); 132 } 133 #endif 134 135 #ifdef L_xread_all 136 void bb_xread_all(int fd, void *buf, size_t count) 137 { 138 ssize_t size; 139 140 while (count) { 141 if ((size = bb_xread(fd, buf, count)) == 0) { /* EOF */ 142 bb_error_msg_and_die("Short read"); 143 } 144 count -= size; 145 buf = ((char *) buf) + size; 146 } 147 return; 148 } 149 #endif 150 151 #ifdef L_xread_char 152 unsigned char bb_xread_char(int fd) 153 { 154 char tmp; 155 156 bb_xread_all(fd, &tmp, 1); 157 158 return(tmp); 159 } 160 #endif 161 162 #ifdef L_xferror 163 void bb_xferror(FILE *fp, const char *fn) 124 125 // Die if we can't open an existing file and return a fd. 126 int 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. 132 int 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. 144 int open_or_warn(const char *pathname, int flags) 145 { 146 return open3_or_warn(pathname, flags, 0666); 147 } 148 149 void xpipe(int filedes[2]) 150 { 151 if (pipe(filedes)) 152 bb_perror_msg_and_die("can't create pipe"); 153 } 154 155 void 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 162 int ndelay_on(int fd) 163 { 164 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) | O_NONBLOCK); 165 } 166 167 int ndelay_off(int fd) 168 { 169 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) & ~O_NONBLOCK); 170 } 171 172 void 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 179 void 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. 188 void 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. 198 off_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. 210 void die_if_ferror(FILE *fp, const char *fn) 164 211 { 165 212 if (ferror(fp)) { 166 bb_error_msg_and_die("%s", fn); 167 } 168 } 169 #endif 170 171 #ifdef L_xferror_stdout 172 void bb_xferror_stdout(void) 173 { 174 bb_xferror(stdout, bb_msg_standard_output); 175 } 176 #endif 177 178 #ifdef L_xfflush_stdout 179 void bb_xfflush_stdout(void) 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. 219 void 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. 225 void xfflush_stdout(void) 180 226 { 181 227 if (fflush(stdout)) { … … 183 229 } 184 230 } 231 232 void sig_block(int sig) 233 { 234 sigset_t ss; 235 sigemptyset(&ss); 236 sigaddset(&ss, sig); 237 sigprocmask(SIG_BLOCK, &ss, NULL); 238 } 239 240 void 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 249 void sig_blocknone(void) 250 { 251 sigset_t ss; 252 sigemptyset(&ss); 253 sigprocmask(SIG_SETMASK, &ss, NULL); 254 } 185 255 #endif 186 256 187 #ifdef L_spawn 188 // This does a fork/exec in one call, using vfork(). 189 pid_t bb_spawn(char **argv) 190 { 191 static int failed; 192 pid_t pid; 193 void *app = find_applet_by_name(argv[0]); 194 195 // Be nice to nommu machines. 196 failed = 0; 197 pid = vfork(); 198 if (pid < 0) return pid; 199 if (!pid) { 200 execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv); 201 202 // We're sharing a stack with blocked parent, let parent know we failed 203 // and then exit to unblock parent (but don't run atexit() stuff, which 204 // would screw up parent.) 205 206 failed = -1; 207 _exit(0); 208 } 209 return failed ? failed : pid; 210 } 257 void 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 266 void sig_pause(void) 267 { 268 sigset_t ss; 269 sigemptyset(&ss); 270 sigsuspend(&ss); 271 } 272 273 274 void 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' 283 void 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. 325 void BUG_sizeof_unsigned_not_4(void); 326 char *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() 347 char *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 364 static char local_buf[12]; 365 366 // Convert unsigned integer to ascii using a static buffer (returned). 367 char *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). 375 char *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 383 char *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.) 398 void 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.) 404 void 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. 410 off_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. 451 char *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); 211 471 #endif 212 472 213 #ifdef L_xspawn 214 pid_t bb_xspawn(char **argv) 215 { 216 pid_t pid = bb_spawn(argv); 217 if (pid < 0) bb_perror_msg_and_die("%s", *argv); 218 return pid; 219 } 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... */ 478 int 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 } 220 500 #endif 221 501 222 #ifdef L_wait4 223 int wait4pid(int pid) 224 { 225 int status; 226 227 if (pid == -1 || waitpid(pid, &status, 0) == -1) return -1; 228 if (WIFEXITED(status)) return WEXITSTATUS(status); 229 if (WIFSIGNALED(status)) return WTERMSIG(status); 230 return 0; 231 } 232 #endif 233 234 #ifdef L_setuid 235 void xsetgid(gid_t gid) 236 { 237 if (setgid(gid)) bb_error_msg_and_die("setgid"); 238 } 239 240 void xsetuid(uid_t uid) 241 { 242 if (setuid(uid)) bb_error_msg_and_die("setuid"); 502 if (r >= 0) { 503 full_write(fd, string_ptr, r); 504 free(string_ptr); 505 } 506 return r; 243 507 } 244 508 #endif 509 510 // Die with an error message if we can't copy an entire FILE * to stdout, then 511 // close that file. 512 void 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. 523 void 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. 530 DIR *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. 541 DIR *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. 552 int 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"; 562 USE_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. 573 void 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. 579 void 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 */ 586 ssize_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 599 void 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. 606 void 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. */ 622 int 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 650 void 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 663 int 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 677 int 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 } 686 void 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 692 int 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 } 701 void 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 TracChangeset
for help on using the changeset viewer.