diff options
| author | aldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-08-28 23:31:54 +0000 |
|---|---|---|
| committer | aldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-08-28 23:31:54 +0000 |
| commit | d52f45a484fc7fc049ab40db9adc6ead7ea9b122 (patch) | |
| tree | 2a57564b8917a983365c765d4daa83032d9f0a17 | |
| parent | 2803d256e9decd450b955c2846bf945db72bb79e (diff) | |
| download | busybox-w32-d52f45a484fc7fc049ab40db9adc6ead7ea9b122.tar.gz busybox-w32-d52f45a484fc7fc049ab40db9adc6ead7ea9b122.tar.bz2 busybox-w32-d52f45a484fc7fc049ab40db9adc6ead7ea9b122.zip | |
- pull from busybox_scratch: r15829:15850
Various fixes, cleanups and shrinkage:
saves 952 Bytes:
text data bss dec hex filename
1087742 15853 790632 1894227 1ce753 ../busybox/busybox.old
1086790 15853 790632 1893275 1ce39b busybox
via:
# scripts/bloat-o-meter ../busybox/busybox_unstripped.old busybox_unstripped
function old new delta
ipcrm_main 756 822 +66
getval - 61 +61
maybe_set_utc - 40 +40
udhcpc_main 2896 2912 +16
md5_hash_block 428 437 +9
opt 8 16 +8
qgravechar 106 110 +4
make_bitmap 292 295 +3
inflate_unzip 2056 2059 +3
add_partition 1412 1414 +2
__parsespent 156 158 +2
qrealloc 41 42 +1
format - 1 +1
catv_main 313 314 +1
watch_main 293 292 -1
varunset 81 80 -1
part 1 - -1
check_if_skip 837 836 -1
start_stop_daemon_main 840 837 -3
create_lost_and_found 175 172 -3
supress_non_delimited_lines 4 - -4
static.l 4 - -4
static.c 5 1 -4
bsd_sum_file 237 233 -4
eval2 338 332 -6
arithmetic_common 166 158 -8
cmpfunc 22 5 -17
cksum_main 294 275 -19
cmp_main 465 439 -26
dd_main 1535 1508 -27
rmmod_main 376 333 -43
cut_file 727 644 -83
ipcs_main 3809 3721 -88
cut_main 722 614 -108
date_main 1443 1263 -180
remove_ids 222 - -222
------------------------------------------------------------------------------
(add/remove: 3/4 grow/shrink: 11/18 up/down: 217/-853) Total: -636 bytes
git-svn-id: svn://busybox.net/trunk/busybox@16009 69ca8d6d-28ef-0310-b511-8ec308f3f277
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | coreutils/catv.c | 44 | ||||
| -rw-r--r-- | coreutils/cksum.c | 31 | ||||
| -rw-r--r-- | coreutils/cmp.c | 47 | ||||
| -rw-r--r-- | coreutils/cut.c | 479 | ||||
| -rw-r--r-- | coreutils/date.c | 260 | ||||
| -rw-r--r-- | coreutils/dd.c | 128 | ||||
| -rw-r--r-- | coreutils/du.c | 9 | ||||
| -rw-r--r-- | coreutils/expr.c | 406 | ||||
| -rw-r--r-- | coreutils/sum.c | 21 | ||||
| -rw-r--r-- | coreutils/tail.c | 21 | ||||
| -rw-r--r-- | coreutils/tee.c | 3 | ||||
| -rw-r--r-- | coreutils/watch.c | 21 | ||||
| -rw-r--r-- | include/libbb.h | 28 | ||||
| -rw-r--r-- | include/unarchive.h | 2 | ||||
| -rw-r--r-- | include/usage.h | 10 | ||||
| -rw-r--r-- | libbb/xfuncs.c | 133 | ||||
| -rwxr-xr-x | testsuite/all_sourcecode.tests | 1 | ||||
| -rw-r--r-- | util-linux/ipcrm.c | 216 | ||||
| -rw-r--r-- | util-linux/ipcs.c | 584 |
20 files changed, 1162 insertions, 1283 deletions
| @@ -278,6 +278,7 @@ endif # CONFIG_FEATURE_FULL_LIBBUSYBOX | |||
| 278 | APPLET_SRC:=$(APPLET_SRC-y) | 278 | APPLET_SRC:=$(APPLET_SRC-y) |
| 279 | APPLETS_DEFINE:=$(APPLETS_DEFINE-y) | 279 | APPLETS_DEFINE:=$(APPLETS_DEFINE-y) |
| 280 | else # CONFIG_BUILD_AT_ONCE | 280 | else # CONFIG_BUILD_AT_ONCE |
| 281 | APPLET_SRC:= | ||
| 281 | # no --combine, build archives out of the individual .o | 282 | # no --combine, build archives out of the individual .o |
| 282 | # This was the old way the binary was built. | 283 | # This was the old way the binary was built. |
| 283 | libbusybox-obj:=archival/libunarchive/libunarchive.a \ | 284 | libbusybox-obj:=archival/libunarchive/libunarchive.a \ |
diff --git a/coreutils/catv.c b/coreutils/catv.c index e18203915..f8229c20e 100644 --- a/coreutils/catv.c +++ b/coreutils/catv.c | |||
| @@ -14,49 +14,55 @@ | |||
| 14 | 14 | ||
| 15 | int catv_main(int argc, char **argv) | 15 | int catv_main(int argc, char **argv) |
| 16 | { | 16 | { |
| 17 | int retval = EXIT_SUCCESS, fd, flags; | 17 | int retval = EXIT_SUCCESS, fd; |
| 18 | unsigned long flags; | ||
| 18 | 19 | ||
| 19 | flags = bb_getopt_ulflags(argc, argv, "etv"); | 20 | flags = bb_getopt_ulflags(argc, argv, "etv"); |
| 20 | flags ^= 4; | 21 | #define CATV_OPT_e (1<<0) |
| 21 | 22 | #define CATV_OPT_t (1<<1) | |
| 22 | // Loop through files. | 23 | #define CATV_OPT_v (1<<2) |
| 24 | flags ^= CATV_OPT_v; | ||
| 23 | 25 | ||
| 24 | argv += optind; | 26 | argv += optind; |
| 25 | do { | 27 | do { |
| 26 | // Read from stdin if there's nothing else to do. | 28 | /* Read from stdin if there's nothing else to do. */ |
| 27 | |||
| 28 | fd = 0; | 29 | fd = 0; |
| 29 | if (*argv && 0>(fd = xopen(*argv, O_RDONLY))) retval = EXIT_FAILURE; | 30 | if (*argv && 0 > (fd = xopen(*argv, O_RDONLY))) |
| 30 | else for(;;) { | 31 | retval = EXIT_FAILURE; |
| 32 | else for (;;) { | ||
| 31 | int i, res; | 33 | int i, res; |
| 32 | 34 | ||
| 33 | res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1)); | 35 | res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1)); |
| 34 | if (res < 0) retval = EXIT_FAILURE; | 36 | if (res < 0) |
| 35 | if (res <1) break; | 37 | retval = EXIT_FAILURE; |
| 36 | for (i=0; i<res; i++) { | 38 | if (res < 1) |
| 37 | char c=bb_common_bufsiz1[i]; | 39 | break; |
| 40 | for (i = 0; i < res; i++) { | ||
| 41 | char c = bb_common_bufsiz1[i]; | ||
| 38 | 42 | ||
| 39 | if (c > 126 && (flags & 4)) { | 43 | if (c > 126 && (flags & CATV_OPT_v)) { |
| 40 | if (c == 127) { | 44 | if (c == 127) { |
| 41 | printf("^?"); | 45 | bb_printf("^?"); |
| 42 | continue; | 46 | continue; |
| 43 | } else { | 47 | } else { |
| 44 | printf("M-"); | 48 | bb_printf("M-"); |
| 45 | c -= 128; | 49 | c -= 128; |
| 46 | } | 50 | } |
| 47 | } | 51 | } |
| 48 | if (c < 32) { | 52 | if (c < 32) { |
| 49 | if (c == 10) { | 53 | if (c == 10) { |
| 50 | if (flags & 1) putchar('$'); | 54 | if (flags & CATV_OPT_e) |
| 51 | } else if (flags & (c==9 ? 2 : 4)) { | 55 | putchar('$'); |
| 52 | printf("^%c", c+'@'); | 56 | } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) { |
| 57 | bb_printf("^%c", c+'@'); | ||
| 53 | continue; | 58 | continue; |
| 54 | } | 59 | } |
| 55 | } | 60 | } |
| 56 | putchar(c); | 61 | putchar(c); |
| 57 | } | 62 | } |
| 58 | } | 63 | } |
| 59 | if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd); | 64 | if (ENABLE_FEATURE_CLEAN_UP && fd) |
| 65 | close(fd); | ||
| 60 | } while (*++argv); | 66 | } while (*++argv); |
| 61 | 67 | ||
| 62 | return retval; | 68 | return retval; |
diff --git a/coreutils/cksum.c b/coreutils/cksum.c index 5849ddab2..9a45fd656 100644 --- a/coreutils/cksum.c +++ b/coreutils/cksum.c | |||
| @@ -3,12 +3,13 @@ | |||
| 3 | * cksum - calculate the CRC32 checksum of a file | 3 | * cksum - calculate the CRC32 checksum of a file |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms | 5 | * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms |
| 6 | * | 6 | * |
| 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ |
| 8 | 8 | ||
| 9 | #include "busybox.h" | 9 | #include "busybox.h" |
| 10 | 10 | ||
| 11 | int cksum_main(int argc, char **argv) { | 11 | int cksum_main(int argc, char **argv) |
| 12 | { | ||
| 12 | 13 | ||
| 13 | uint32_t *crc32_table = crc32_filltable(1); | 14 | uint32_t *crc32_table = crc32_filltable(1); |
| 14 | 15 | ||
| @@ -17,36 +18,36 @@ int cksum_main(int argc, char **argv) { | |||
| 17 | long length, filesize; | 18 | long length, filesize; |
| 18 | int bytes_read; | 19 | int bytes_read; |
| 19 | char *cp; | 20 | char *cp; |
| 20 | RESERVE_CONFIG_BUFFER(buf, BUFSIZ); | 21 | |
| 21 | int inp_stdin = (argc == optind) ? 1 : 0; | 22 | int inp_stdin = (argc == optind) ? 1 : 0; |
| 22 | 23 | ||
| 23 | do { | 24 | do { |
| 24 | fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++argv); | 25 | fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++argv); |
| 25 | 26 | ||
| 26 | crc = 0; | 27 | crc = 0; |
| 27 | length = 0; | 28 | length = 0; |
| 28 | 29 | ||
| 29 | while ((bytes_read = fread(buf, 1, BUFSIZ, fp)) > 0) { | 30 | while ((bytes_read = fread(bb_common_bufsiz1, 1, BUFSIZ, fp)) > 0) { |
| 30 | cp = buf; | 31 | cp = bb_common_bufsiz1; |
| 31 | length += bytes_read; | 32 | length += bytes_read; |
| 32 | while (bytes_read--) | 33 | while (bytes_read--) |
| 33 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL]; | 34 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL]; |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | filesize = length; | 37 | filesize = length; |
| 37 | 38 | ||
| 38 | for (; length; length >>= 8) | 39 | for (; length; length >>= 8) |
| 39 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL]; | 40 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL]; |
| 40 | crc ^= 0xffffffffL; | 41 | crc ^= 0xffffffffL; |
| 41 | 42 | ||
| 42 | if (inp_stdin) { | 43 | if (inp_stdin) { |
| 43 | printf("%"PRIu32" %li\n", crc, filesize); | 44 | bb_printf("%" PRIu32 " %li\n", crc, filesize); |
| 44 | break; | 45 | break; |
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | printf("%"PRIu32" %li %s\n", crc, filesize, *argv); | 48 | bb_printf("%" PRIu32 " %li %s\n", crc, filesize, *argv); |
| 48 | fclose(fp); | 49 | fclose(fp); |
| 49 | } while (*(argv+1)); | 50 | } while (*(argv + 1)); |
| 50 | 51 | ||
| 51 | return EXIT_SUCCESS; | 52 | return EXIT_SUCCESS; |
| 52 | } | 53 | } |
diff --git a/coreutils/cmp.c b/coreutils/cmp.c index a569eb3fe..ae3f50279 100644 --- a/coreutils/cmp.c +++ b/coreutils/cmp.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | #include "busybox.h" | 24 | #include "busybox.h" |
| 25 | 25 | ||
| 26 | static FILE *cmp_xfopen_input(const char *filename) | 26 | static FILE *cmp_xfopen_input(const char * const filename) |
| 27 | { | 27 | { |
| 28 | FILE *fp; | 28 | FILE *fp; |
| 29 | 29 | ||
| @@ -40,32 +40,28 @@ static const char fmt_differ[] = "%s %s differ: char %d, line %d\n"; | |||
| 40 | static const char fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n"; | 40 | static const char fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n"; |
| 41 | 41 | ||
| 42 | static const char opt_chars[] = "sl"; | 42 | static const char opt_chars[] = "sl"; |
| 43 | 43 | #define CMP_OPT_s (1<<0) | |
| 44 | enum { | 44 | #define CMP_OPT_l (1<<1) |
| 45 | OPT_s = 1, | ||
| 46 | OPT_l = 2 | ||
| 47 | }; | ||
| 48 | 45 | ||
| 49 | int cmp_main(int argc, char **argv) | 46 | int cmp_main(int argc, char **argv) |
| 50 | { | 47 | { |
| 51 | FILE *fp1, *fp2, *outfile = stdout; | 48 | FILE *fp1, *fp2, *outfile = stdout; |
| 52 | const char *filename1, *filename2; | 49 | const char *filename1, *filename2 = "-"; |
| 53 | const char *fmt; | 50 | const char *fmt; |
| 54 | int c1, c2, char_pos, line_pos; | 51 | int c1, c2, char_pos = 0, line_pos = 1; |
| 55 | int opt_flags; | 52 | unsigned opt; |
| 56 | int exit_val = 0; | 53 | int retval = 0; |
| 57 | 54 | ||
| 58 | bb_default_error_retval = 2; /* 1 is returned if files are different. */ | 55 | bb_default_error_retval = 2; /* 1 is returned if files are different. */ |
| 59 | 56 | ||
| 60 | opt_flags = bb_getopt_ulflags(argc, argv, opt_chars); | 57 | opt = bb_getopt_ulflags(argc, argv, opt_chars); |
| 61 | 58 | ||
| 62 | if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > 1)) { | 59 | if ((opt & (CMP_OPT_s|CMP_OPT_l)) |
| 60 | || (((unsigned int)(--argc - optind)) > 1)) | ||
| 63 | bb_show_usage(); | 61 | bb_show_usage(); |
| 64 | } | ||
| 65 | 62 | ||
| 66 | fp1 = cmp_xfopen_input(filename1 = *(argv += optind)); | 63 | fp1 = cmp_xfopen_input(filename1 = *(argv += optind)); |
| 67 | 64 | ||
| 68 | filename2 = "-"; | ||
| 69 | if (*++argv) { | 65 | if (*++argv) { |
| 70 | filename2 = *argv; | 66 | filename2 = *argv; |
| 71 | } | 67 | } |
| @@ -79,19 +75,17 @@ int cmp_main(int argc, char **argv) | |||
| 79 | return 0; | 75 | return 0; |
| 80 | } | 76 | } |
| 81 | 77 | ||
| 82 | fmt = fmt_differ; | 78 | if (opt & CMP_OPT_l) |
| 83 | if (opt_flags == OPT_l) { | ||
| 84 | fmt = fmt_l_opt; | 79 | fmt = fmt_l_opt; |
| 85 | } | 80 | else |
| 81 | fmt = fmt_differ; | ||
| 86 | 82 | ||
| 87 | char_pos = 0; | ||
| 88 | line_pos = 1; | ||
| 89 | do { | 83 | do { |
| 90 | c1 = getc(fp1); | 84 | c1 = getc(fp1); |
| 91 | c2 = getc(fp2); | 85 | c2 = getc(fp2); |
| 92 | ++char_pos; | 86 | ++char_pos; |
| 93 | if (c1 != c2) { /* Remember -- a read error may have occurred. */ | 87 | if (c1 != c2) { /* Remember: a read error may have occurred. */ |
| 94 | exit_val = 1; /* But assume the files are different for now. */ | 88 | retval = 1; /* But assume the files are different for now. */ |
| 95 | if (c2 == EOF) { | 89 | if (c2 == EOF) { |
| 96 | /* We know that fp1 isn't at EOF or in an error state. But to | 90 | /* We know that fp1 isn't at EOF or in an error state. But to |
| 97 | * save space below, things are setup to expect an EOF in fp1 | 91 | * save space below, things are setup to expect an EOF in fp1 |
| @@ -109,13 +103,14 @@ int cmp_main(int argc, char **argv) | |||
| 109 | * make sure we fflush before writing to stderr. */ | 103 | * make sure we fflush before writing to stderr. */ |
| 110 | xfflush_stdout(); | 104 | xfflush_stdout(); |
| 111 | } | 105 | } |
| 112 | if (opt_flags != OPT_s) { | 106 | if (!opt & CMP_OPT_s) { |
| 113 | if (opt_flags == OPT_l) { | 107 | if (opt & CMP_OPT_l) { |
| 114 | line_pos = c1; /* line_pos is unused in the -l case. */ | 108 | line_pos = c1; /* line_pos is unused in the -l case. */ |
| 115 | } | 109 | } |
| 116 | bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2); | 110 | bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2); |
| 117 | if (opt_flags) { /* This must be -l since not -s. */ | 111 | if (opt) { /* This must be -l since not -s. */ |
| 118 | /* If we encountered and EOF, the while check will catch it. */ | 112 | /* If we encountered an EOF, |
| 113 | * the while check will catch it. */ | ||
| 119 | continue; | 114 | continue; |
| 120 | } | 115 | } |
| 121 | } | 116 | } |
| @@ -129,5 +124,5 @@ int cmp_main(int argc, char **argv) | |||
| 129 | xferror(fp1, filename1); | 124 | xferror(fp1, filename1); |
| 130 | xferror(fp2, filename2); | 125 | xferror(fp2, filename2); |
| 131 | 126 | ||
| 132 | bb_fflush_stdout_and_exit(exit_val); | 127 | bb_fflush_stdout_and_exit(retval); |
| 133 | } | 128 | } |
diff --git a/coreutils/cut.c b/coreutils/cut.c index 1b80e7e73..d88a891b0 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c | |||
| @@ -4,28 +4,24 @@ | |||
| 4 | * | 4 | * |
| 5 | * Copyright (C) 1999,2000,2001 by Lineo, inc. | 5 | * Copyright (C) 1999,2000,2001 by Lineo, inc. |
| 6 | * Written by Mark Whitley <markw@codepoet.org> | 6 | * Written by Mark Whitley <markw@codepoet.org> |
| 7 | * debloated by Bernhard Fischer | ||
| 7 | * | 8 | * |
| 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 9 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
| 9 | */ | 10 | */ |
| 10 | 11 | ||
| 11 | #include <stdio.h> | ||
| 12 | #include <stdlib.h> | ||
| 13 | #include <unistd.h> | ||
| 14 | #include <string.h> | ||
| 15 | #include <limits.h> | ||
| 16 | #include "busybox.h" | 12 | #include "busybox.h" |
| 17 | 13 | ||
| 18 | |||
| 19 | /* option vars */ | 14 | /* option vars */ |
| 20 | static const char optstring[] = "b:c:f:d:sn"; | 15 | static const char *const optstring = "b:c:f:d:sn"; |
| 21 | #define OPT_BYTE_FLGS 1 | 16 | |
| 22 | #define OPT_CHAR_FLGS 2 | 17 | #define CUT_OPT_BYTE_FLGS (1<<0) |
| 23 | #define OPT_FIELDS_FLGS 4 | 18 | #define CUT_OPT_CHAR_FLGS (1<<1) |
| 24 | #define OPT_DELIM_FLGS 8 | 19 | #define CUT_OPT_FIELDS_FLGS (1<<2) |
| 25 | #define OPT_SUPRESS_FLGS 16 | 20 | #define CUT_OPT_DELIM_FLGS (1<<3) |
| 26 | static char part; /* (b)yte, (c)har, (f)ields */ | 21 | #define CUT_OPT_SUPPRESS_FLGS (1<<4) |
| 27 | static unsigned int supress_non_delimited_lines; | 22 | static unsigned long opt; |
| 28 | static char delim = '\t'; /* delimiter, default is tab */ | 23 | |
| 24 | static char delim = '\t'; /* delimiter, default is tab */ | ||
| 29 | 25 | ||
| 30 | struct cut_list { | 26 | struct cut_list { |
| 31 | int startpos; | 27 | int startpos; |
| @@ -38,295 +34,268 @@ enum { | |||
| 38 | NON_RANGE = -1 | 34 | NON_RANGE = -1 |
| 39 | }; | 35 | }; |
| 40 | 36 | ||
| 41 | static struct cut_list *cut_lists = NULL; /* growable array holding a series of lists */ | 37 | /* growable array holding a series of lists */ |
| 42 | static unsigned int nlists = 0; /* number of elements in above list */ | 38 | static struct cut_list *cut_lists; |
| 39 | static unsigned int nlists; /* number of elements in above list */ | ||
| 43 | 40 | ||
| 44 | 41 | ||
| 45 | static int cmpfunc(const void *a, const void *b) | 42 | static int cmpfunc(const void *a, const void *b) |
| 46 | { | 43 | { |
| 47 | struct cut_list *la = (struct cut_list *)a; | 44 | return (((struct cut_list *) a)->startpos - |
| 48 | struct cut_list *lb = (struct cut_list *)b; | 45 | ((struct cut_list *) b)->startpos); |
| 49 | |||
| 50 | if (la->startpos > lb->startpos) | ||
| 51 | return 1; | ||
| 52 | if (la->startpos < lb->startpos) | ||
| 53 | return -1; | ||
| 54 | return 0; | ||
| 55 | } | ||
| 56 | 46 | ||
| 47 | } | ||
| 57 | 48 | ||
| 58 | /* | 49 | static void cut_file(FILE * file) |
| 59 | * parse_lists() - parses a list and puts values into startpos and endpos. | ||
| 60 | * valid list formats: N, N-, N-M, -M | ||
| 61 | * more than one list can be separated by commas | ||
| 62 | */ | ||
| 63 | static void parse_lists(char *lists) | ||
| 64 | { | 50 | { |
| 65 | char *ltok = NULL; | 51 | char *line = NULL; |
| 66 | char *ntok = NULL; | 52 | unsigned int linenum = 0; /* keep these zero-based to be consistent */ |
| 67 | char *junk; | ||
| 68 | int s = 0, e = 0; | ||
| 69 | |||
| 70 | /* take apart the lists, one by one (they are separated with commas */ | ||
| 71 | while ((ltok = strsep(&lists, ",")) != NULL) { | ||
| 72 | |||
| 73 | /* it's actually legal to pass an empty list */ | ||
| 74 | if (strlen(ltok) == 0) | ||
| 75 | continue; | ||
| 76 | |||
| 77 | /* get the start pos */ | ||
| 78 | ntok = strsep(<ok, "-"); | ||
| 79 | if (ntok == NULL) { | ||
| 80 | fprintf(stderr, "Help ntok is null for starting position! What do I do?\n"); | ||
| 81 | } else if (strlen(ntok) == 0) { | ||
| 82 | s = BOL; | ||
| 83 | } else { | ||
| 84 | s = strtoul(ntok, &junk, 10); | ||
| 85 | if(*junk != '\0' || s < 0) | ||
| 86 | bb_error_msg_and_die("invalid byte or field list"); | ||
| 87 | |||
| 88 | /* account for the fact that arrays are zero based, while the user | ||
| 89 | * expects the first char on the line to be char # 1 */ | ||
| 90 | if (s != 0) | ||
| 91 | s--; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* get the end pos */ | ||
| 95 | ntok = strsep(<ok, "-"); | ||
| 96 | if (ntok == NULL) { | ||
| 97 | e = NON_RANGE; | ||
| 98 | } else if (strlen(ntok) == 0) { | ||
| 99 | e = EOL; | ||
| 100 | } else { | ||
| 101 | e = strtoul(ntok, &junk, 10); | ||
| 102 | if(*junk != '\0' || e < 0) | ||
| 103 | bb_error_msg_and_die("invalid byte or field list"); | ||
| 104 | /* if the user specified and end position of 0, that means "til the | ||
| 105 | * end of the line */ | ||
| 106 | if (e == 0) | ||
| 107 | e = INT_MAX; | ||
| 108 | e--; /* again, arrays are zero based, lines are 1 based */ | ||
| 109 | if (e == s) | ||
| 110 | e = NON_RANGE; | ||
| 111 | } | ||
| 112 | |||
| 113 | /* if there's something left to tokenize, the user past an invalid list */ | ||
| 114 | if (ltok) | ||
| 115 | bb_error_msg_and_die("invalid byte or field list"); | ||
| 116 | |||
| 117 | /* add the new list */ | ||
| 118 | cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); | ||
| 119 | cut_lists[nlists-1].startpos = s; | ||
| 120 | cut_lists[nlists-1].endpos = e; | ||
| 121 | } | ||
| 122 | |||
| 123 | /* make sure we got some cut positions out of all that */ | ||
| 124 | if (nlists == 0) | ||
| 125 | bb_error_msg_and_die("missing list of positions"); | ||
| 126 | |||
| 127 | /* now that the lists are parsed, we need to sort them to make life easier | ||
| 128 | * on us when it comes time to print the chars / fields / lines */ | ||
| 129 | qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc); | ||
| 130 | 53 | ||
| 131 | } | 54 | /* go through every line in the file */ |
| 55 | while ((line = bb_get_chomped_line_from_file(file)) != NULL) { | ||
| 132 | 56 | ||
| 57 | /* set up a list so we can keep track of what's been printed */ | ||
| 58 | char * printed = xzalloc(strlen(line) * sizeof(char)); | ||
| 59 | char * orig_line = line; | ||
| 60 | unsigned int cl_pos = 0; | ||
| 61 | int spos; | ||
| 133 | 62 | ||
| 134 | static void cut_line_by_chars(const char *line) | 63 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ |
| 135 | { | 64 | if ((opt & (CUT_OPT_CHAR_FLGS | CUT_OPT_BYTE_FLGS))) { |
| 136 | int c, l; | 65 | /* print the chars specified in each cut list */ |
| 137 | /* set up a list so we can keep track of what's been printed */ | 66 | for (; cl_pos < nlists; cl_pos++) { |
| 138 | char *printed = xzalloc(strlen(line)); | 67 | spos = cut_lists[cl_pos].startpos; |
| 139 | 68 | while (spos < strlen(line)) { | |
| 140 | /* print the chars specified in each cut list */ | 69 | if (!printed[spos]) { |
| 141 | for (c = 0; c < nlists; c++) { | 70 | printed[spos] = 'X'; |
| 142 | l = cut_lists[c].startpos; | 71 | putchar(line[spos]); |
| 143 | while (l < strlen(line)) { | 72 | } |
| 144 | if (!printed[l]) { | 73 | spos++; |
| 145 | putchar(line[l]); | 74 | if (spos > cut_lists[cl_pos].endpos |
| 146 | printed[l] = 'X'; | 75 | || cut_lists[cl_pos].endpos == NON_RANGE) |
| 76 | break; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | } else if (delim == '\n') { /* cut by lines */ | ||
| 80 | spos = cut_lists[cl_pos].startpos; | ||
| 81 | |||
| 82 | /* get out if we have no more lists to process or if the lines | ||
| 83 | * are lower than what we're interested in */ | ||
| 84 | if (linenum < spos || cl_pos >= nlists) | ||
| 85 | goto next_line; | ||
| 86 | |||
| 87 | /* if the line we're looking for is lower than the one we were | ||
| 88 | * passed, it means we displayed it already, so move on */ | ||
| 89 | while (spos < linenum) { | ||
| 90 | spos++; | ||
| 91 | /* go to the next list if we're at the end of this one */ | ||
| 92 | if (spos > cut_lists[cl_pos].endpos | ||
| 93 | || cut_lists[cl_pos].endpos == NON_RANGE) { | ||
| 94 | cl_pos++; | ||
| 95 | /* get out if there's no more lists to process */ | ||
| 96 | if (cl_pos >= nlists) | ||
| 97 | goto next_line; | ||
| 98 | spos = cut_lists[cl_pos].startpos; | ||
| 99 | /* get out if the current line is lower than the one | ||
| 100 | * we just became interested in */ | ||
| 101 | if (linenum < spos) | ||
| 102 | goto next_line; | ||
| 103 | } | ||
| 147 | } | 104 | } |
| 148 | l++; | ||
| 149 | if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) | ||
| 150 | break; | ||
| 151 | } | ||
| 152 | } | ||
| 153 | putchar('\n'); /* cuz we were handed a chomped line */ | ||
| 154 | free(printed); | ||
| 155 | } | ||
| 156 | |||
| 157 | 105 | ||
| 158 | static void cut_line_by_fields(char *line) | 106 | /* If we made it here, it means we've found the line we're |
| 159 | { | 107 | * looking for, so print it */ |
| 160 | int c, f; | ||
| 161 | int ndelim = -1; /* zero-based / one-based problem */ | ||
| 162 | int nfields_printed = 0; | ||
| 163 | char *field = NULL; | ||
| 164 | char d[2] = { delim, 0 }; | ||
| 165 | char *printed; | ||
| 166 | |||
| 167 | /* test the easy case first: does this line contain any delimiters? */ | ||
| 168 | if (strchr(line, delim) == NULL) { | ||
| 169 | if (!supress_non_delimited_lines) | ||
| 170 | puts(line); | 108 | puts(line); |
| 171 | return; | 109 | goto next_line; |
| 172 | } | 110 | } else { /* cut by fields */ |
| 173 | 111 | int ndelim = -1; /* zero-based / one-based problem */ | |
| 174 | /* set up a list so we can keep track of what's been printed */ | 112 | int nfields_printed = 0; |
| 175 | printed = xzalloc(strlen(line)); | 113 | char *field = NULL; |
| 176 | 114 | const char delimiter[2] = { delim, 0 }; | |
| 177 | /* process each list on this line, for as long as we've got a line to process */ | 115 | |
| 178 | for (c = 0; c < nlists && line; c++) { | 116 | /* does this line contain any delimiters? */ |
| 179 | f = cut_lists[c].startpos; | 117 | if (strchr(line, delim) == NULL) { |
| 180 | do { | 118 | if (!(opt & CUT_OPT_SUPPRESS_FLGS)) |
| 181 | 119 | puts(line); | |
| 182 | /* find the field we're looking for */ | 120 | goto next_line; |
| 183 | while (line && ndelim < f) { | ||
| 184 | field = strsep(&line, d); | ||
| 185 | ndelim++; | ||
| 186 | } | 121 | } |
| 187 | 122 | ||
| 188 | /* we found it, and it hasn't been printed yet */ | 123 | /* process each list on this line, for as long as we've got |
| 189 | if (field && ndelim == f && !printed[ndelim]) { | 124 | * a line to process */ |
| 190 | /* if this isn't our first time through, we need to print the | 125 | for (; cl_pos < nlists && line; cl_pos++) { |
| 191 | * delimiter after the last field that was printed */ | 126 | spos = cut_lists[cl_pos].startpos; |
| 192 | if (nfields_printed > 0) | 127 | do { |
| 193 | putchar(delim); | 128 | |
| 194 | fputs(field, stdout); | 129 | /* find the field we're looking for */ |
| 195 | printed[ndelim] = 'X'; | 130 | while (line && ndelim < spos) { |
| 196 | nfields_printed++; | 131 | field = strsep(&line, delimiter); |
| 132 | ndelim++; | ||
| 133 | } | ||
| 134 | |||
| 135 | /* we found it, and it hasn't been printed yet */ | ||
| 136 | if (field && ndelim == spos && !printed[ndelim]) { | ||
| 137 | /* if this isn't our first time through, we need to | ||
| 138 | * print the delimiter after the last field that was | ||
| 139 | * printed */ | ||
| 140 | if (nfields_printed > 0) | ||
| 141 | putchar(delim); | ||
| 142 | fputs(field, stdout); | ||
| 143 | printed[ndelim] = 'X'; | ||
| 144 | nfields_printed++; /* shouldn't overflow.. */ | ||
| 145 | } | ||
| 146 | |||
| 147 | spos++; | ||
| 148 | |||
| 149 | /* keep going as long as we have a line to work with, | ||
| 150 | * this is a list, and we're not at the end of that | ||
| 151 | * list */ | ||
| 152 | } while (spos <= cut_lists[cl_pos].endpos && line | ||
| 153 | && cut_lists[cl_pos].endpos != NON_RANGE); | ||
| 197 | } | 154 | } |
| 198 | |||
| 199 | f++; | ||
| 200 | |||
| 201 | /* keep going as long as we have a line to work with, this is a | ||
| 202 | * list, and we're not at the end of that list */ | ||
| 203 | } while (line && cut_lists[c].endpos != NON_RANGE && f <= cut_lists[c].endpos); | ||
| 204 | } | ||
| 205 | |||
| 206 | /* if we printed anything at all, we need to finish it with a newline cuz | ||
| 207 | * we were handed a chomped line */ | ||
| 208 | putchar('\n'); | ||
| 209 | |||
| 210 | free(printed); | ||
| 211 | } | ||
| 212 | |||
| 213 | |||
| 214 | static void cut_file_by_lines(const char *line, unsigned int linenum) | ||
| 215 | { | ||
| 216 | static int c = 0; | ||
| 217 | static int l = -1; | ||
| 218 | |||
| 219 | /* I can't initialize this above cuz the "initializer isn't | ||
| 220 | * constant" *sigh* */ | ||
| 221 | if (l == -1) | ||
| 222 | l = cut_lists[c].startpos; | ||
| 223 | |||
| 224 | /* get out if we have no more lists to process or if the lines are lower | ||
| 225 | * than what we're interested in */ | ||
| 226 | if (c >= nlists || linenum < l) | ||
| 227 | return; | ||
| 228 | |||
| 229 | /* if the line we're looking for is lower than the one we were passed, it | ||
| 230 | * means we displayed it already, so move on */ | ||
| 231 | while (l < linenum) { | ||
| 232 | l++; | ||
| 233 | /* move on to the next list if we're at the end of this one */ | ||
| 234 | if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) { | ||
| 235 | c++; | ||
| 236 | /* get out if there's no more lists to process */ | ||
| 237 | if (c >= nlists) | ||
| 238 | return; | ||
| 239 | l = cut_lists[c].startpos; | ||
| 240 | /* get out if the current line is lower than the one we just became | ||
| 241 | * interested in */ | ||
| 242 | if (linenum < l) | ||
| 243 | return; | ||
| 244 | } | 155 | } |
| 156 | /* if we printed anything at all, we need to finish it with a | ||
| 157 | * newline cuz we were handed a chomped line */ | ||
| 158 | putchar('\n'); | ||
| 159 | next_line: | ||
| 160 | linenum++; | ||
| 161 | free(printed); | ||
| 162 | free(orig_line); | ||
| 245 | } | 163 | } |
| 246 | |||
| 247 | /* If we made it here, it means we've found the line we're looking for, so print it */ | ||
| 248 | puts(line); | ||
| 249 | } | 164 | } |
| 250 | 165 | ||
| 251 | 166 | static int getval(char *ntok) | |
| 252 | /* | ||
| 253 | * snippy-snip | ||
| 254 | */ | ||
| 255 | static void cut_file(FILE *file) | ||
| 256 | { | 167 | { |
| 257 | char *line = NULL; | 168 | char *junk; |
| 258 | unsigned int linenum = 0; /* keep these zero-based to be consistent */ | 169 | int i = strtoul(ntok, &junk, 10); |
| 259 | |||
| 260 | /* go through every line in the file */ | ||
| 261 | while ((line = bb_get_chomped_line_from_file(file)) != NULL) { | ||
| 262 | |||
| 263 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ | ||
| 264 | if ((part & (OPT_CHAR_FLGS | OPT_BYTE_FLGS))) | ||
| 265 | cut_line_by_chars(line); | ||
| 266 | |||
| 267 | /* cut based on fields */ | ||
| 268 | else { | ||
| 269 | if (delim == '\n') | ||
| 270 | cut_file_by_lines(line, linenum); | ||
| 271 | else | ||
| 272 | cut_line_by_fields(line); | ||
| 273 | } | ||
| 274 | 170 | ||
| 275 | linenum++; | 171 | if (*junk != '\0' || i < 0) |
| 276 | free(line); | 172 | bb_error_msg_and_die("invalid byte or field list"); |
| 277 | } | 173 | return i; |
| 278 | } | 174 | } |
| 279 | 175 | ||
| 176 | static const char * const _op_on_field = " only when operating on fields"; | ||
| 280 | 177 | ||
| 281 | int cut_main(int argc, char **argv) | 178 | int cut_main(int argc, char **argv) |
| 282 | { | 179 | { |
| 283 | unsigned long opt; | 180 | char *sopt, *ltok; |
| 284 | char *sopt, *sdopt; | ||
| 285 | 181 | ||
| 286 | bb_opt_complementally = "b--bcf:c--bcf:f--bcf"; | 182 | bb_opt_complementally = "b--bcf:c--bcf:f--bcf"; |
| 287 | opt = bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &sdopt); | 183 | opt = |
| 288 | part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS); | 184 | bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, <ok); |
| 289 | if(part == 0) | 185 | if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) |
| 290 | bb_error_msg_and_die("you must specify a list of bytes, characters, or fields"); | 186 | bb_error_msg_and_die |
| 291 | if(opt & BB_GETOPT_ERROR) | 187 | ("expected a list of bytes, characters, or fields"); |
| 188 | if (opt & BB_GETOPT_ERROR) | ||
| 292 | bb_error_msg_and_die("only one type of list may be specified"); | 189 | bb_error_msg_and_die("only one type of list may be specified"); |
| 293 | parse_lists(sopt); | 190 | |
| 294 | if((opt & (OPT_DELIM_FLGS))) { | 191 | if ((opt & (CUT_OPT_DELIM_FLGS))) { |
| 295 | if (strlen(sdopt) > 1) { | 192 | if (strlen(ltok) > 1) { |
| 296 | bb_error_msg_and_die("the delimiter must be a single character"); | 193 | bb_error_msg_and_die("the delimiter must be a single character"); |
| 297 | } | 194 | } |
| 298 | delim = sdopt[0]; | 195 | delim = ltok[0]; |
| 299 | } | 196 | } |
| 300 | supress_non_delimited_lines = opt & OPT_SUPRESS_FLGS; | ||
| 301 | 197 | ||
| 302 | /* non-field (char or byte) cutting has some special handling */ | 198 | /* non-field (char or byte) cutting has some special handling */ |
| 303 | if (part != OPT_FIELDS_FLGS) { | 199 | if (!(opt & CUT_OPT_FIELDS_FLGS)) { |
| 304 | if (supress_non_delimited_lines) { | 200 | if (opt & CUT_OPT_SUPPRESS_FLGS) { |
| 305 | bb_error_msg_and_die("suppressing non-delimited lines makes sense" | 201 | bb_error_msg_and_die |
| 306 | " only when operating on fields"); | 202 | ("suppressing non-delimited lines makes sense%s", |
| 203 | _op_on_field); | ||
| 307 | } | 204 | } |
| 308 | if (delim != '\t') { | 205 | if (delim != '\t') { |
| 309 | bb_error_msg_and_die("a delimiter may be specified only when operating on fields"); | 206 | bb_error_msg_and_die |
| 207 | ("a delimiter may be specified%s", _op_on_field); | ||
| 310 | } | 208 | } |
| 311 | } | 209 | } |
| 312 | 210 | ||
| 211 | /* | ||
| 212 | * parse list and put values into startpos and endpos. | ||
| 213 | * valid list formats: N, N-, N-M, -M | ||
| 214 | * more than one list can be separated by commas | ||
| 215 | */ | ||
| 216 | { | ||
| 217 | char *ntok; | ||
| 218 | int s = 0, e = 0; | ||
| 219 | |||
| 220 | /* take apart the lists, one by one (they are separated with commas */ | ||
| 221 | while ((ltok = strsep(&sopt, ",")) != NULL) { | ||
| 222 | |||
| 223 | /* it's actually legal to pass an empty list */ | ||
| 224 | if (strlen(ltok) == 0) | ||
| 225 | continue; | ||
| 226 | |||
| 227 | /* get the start pos */ | ||
| 228 | ntok = strsep(<ok, "-"); | ||
| 229 | if (ntok == NULL) { | ||
| 230 | bb_error_msg | ||
| 231 | ("internal error: ntok is null for start pos!?\n"); | ||
| 232 | } else if (strlen(ntok) == 0) { | ||
| 233 | s = BOL; | ||
| 234 | } else { | ||
| 235 | s = getval(ntok); | ||
| 236 | /* account for the fact that arrays are zero based, while | ||
| 237 | * the user expects the first char on the line to be char #1 */ | ||
| 238 | if (s != 0) | ||
| 239 | s--; | ||
| 240 | } | ||
| 241 | |||
| 242 | /* get the end pos */ | ||
| 243 | ntok = strsep(<ok, "-"); | ||
| 244 | if (ntok == NULL) { | ||
| 245 | e = NON_RANGE; | ||
| 246 | } else if (strlen(ntok) == 0) { | ||
| 247 | e = EOL; | ||
| 248 | } else { | ||
| 249 | e = getval(ntok); | ||
| 250 | /* if the user specified and end position of 0, that means "til the | ||
| 251 | * end of the line */ | ||
| 252 | if (e == 0) | ||
| 253 | e = EOL; | ||
| 254 | e--; /* again, arrays are zero based, lines are 1 based */ | ||
| 255 | if (e == s) | ||
| 256 | e = NON_RANGE; | ||
| 257 | } | ||
| 258 | |||
| 259 | /* if there's something left to tokenize, the user passed | ||
| 260 | * an invalid list */ | ||
| 261 | if (ltok) | ||
| 262 | bb_error_msg_and_die("invalid byte or field list"); | ||
| 263 | |||
| 264 | /* add the new list */ | ||
| 265 | cut_lists = | ||
| 266 | xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); | ||
| 267 | cut_lists[nlists - 1].startpos = s; | ||
| 268 | cut_lists[nlists - 1].endpos = e; | ||
| 269 | } | ||
| 270 | |||
| 271 | /* make sure we got some cut positions out of all that */ | ||
| 272 | if (nlists == 0) | ||
| 273 | bb_error_msg_and_die("missing list of positions"); | ||
| 274 | |||
| 275 | /* now that the lists are parsed, we need to sort them to make life | ||
| 276 | * easier on us when it comes time to print the chars / fields / lines | ||
| 277 | */ | ||
| 278 | qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc); | ||
| 279 | } | ||
| 280 | |||
| 313 | /* argv[(optind)..(argc-1)] should be names of file to process. If no | 281 | /* argv[(optind)..(argc-1)] should be names of file to process. If no |
| 314 | * files were specified or '-' was specified, take input from stdin. | 282 | * files were specified or '-' was specified, take input from stdin. |
| 315 | * Otherwise, we process all the files specified. */ | 283 | * Otherwise, we process all the files specified. */ |
| 316 | if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) { | 284 | if (argv[optind] == NULL |
| 285 | || (argv[optind][0] == '-' && argv[optind][1] == '\0')) { | ||
| 317 | cut_file(stdin); | 286 | cut_file(stdin); |
| 318 | } | 287 | } else { |
| 319 | else { | ||
| 320 | int i; | ||
| 321 | FILE *file; | 288 | FILE *file; |
| 322 | for (i = optind; i < argc; i++) { | 289 | |
| 323 | file = bb_wfopen(argv[i], "r"); | 290 | for (; optind < argc; optind++) { |
| 324 | if(file) { | 291 | file = bb_wfopen(argv[optind], "r"); |
| 292 | if (file) { | ||
| 325 | cut_file(file); | 293 | cut_file(file); |
| 326 | fclose(file); | 294 | fclose(file); |
| 327 | } | 295 | } |
| 328 | } | 296 | } |
| 329 | } | 297 | } |
| 330 | 298 | if (ENABLE_FEATURE_CLEAN_UP) | |
| 299 | free(cut_lists); | ||
| 331 | return EXIT_SUCCESS; | 300 | return EXIT_SUCCESS; |
| 332 | } | 301 | } |
diff --git a/coreutils/date.c b/coreutils/date.c index f08392ec2..2a82e0413 100644 --- a/coreutils/date.c +++ b/coreutils/date.c | |||
| @@ -5,14 +5,17 @@ | |||
| 5 | * by Matthew Grant <grantma@anathoth.gen.nz> | 5 | * by Matthew Grant <grantma@anathoth.gen.nz> |
| 6 | * | 6 | * |
| 7 | * iso-format handling added by Robert Griebl <griebl@gmx.de> | 7 | * iso-format handling added by Robert Griebl <griebl@gmx.de> |
| 8 | * bugfixes and cleanup by Bernhard Fischer | ||
| 8 | * | 9 | * |
| 9 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 10 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
| 10 | */ | 11 | */ |
| 11 | 12 | ||
| 13 | #include "busybox.h" | ||
| 14 | |||
| 12 | /* This 'date' command supports only 2 time setting formats, | 15 | /* This 'date' command supports only 2 time setting formats, |
| 13 | all the GNU strftime stuff (its in libc, lets use it), | 16 | all the GNU strftime stuff (its in libc, lets use it), |
| 14 | setting time using UTC and displaying int, as well as | 17 | setting time using UTC and displaying it, as well as |
| 15 | an RFC 822 complient date output for shell scripting | 18 | an RFC 2822 compliant date output for shell scripting |
| 16 | mail commands */ | 19 | mail commands */ |
| 17 | 20 | ||
| 18 | /* Input parsing code is always bulky - used heavy duty libc stuff as | 21 | /* Input parsing code is always bulky - used heavy duty libc stuff as |
| @@ -20,13 +23,6 @@ | |||
| 20 | 23 | ||
| 21 | /* Default input handling to save surprising some people */ | 24 | /* Default input handling to save surprising some people */ |
| 22 | 25 | ||
| 23 | #include <stdlib.h> | ||
| 24 | #include <errno.h> | ||
| 25 | #include <unistd.h> | ||
| 26 | #include <time.h> | ||
| 27 | #include <stdio.h> | ||
| 28 | #include <string.h> | ||
| 29 | #include "busybox.h" | ||
| 30 | 26 | ||
| 31 | #define DATE_OPT_RFC2822 0x01 | 27 | #define DATE_OPT_RFC2822 0x01 |
| 32 | #define DATE_OPT_SET 0x02 | 28 | #define DATE_OPT_SET 0x02 |
| @@ -36,119 +32,45 @@ | |||
| 36 | #define DATE_OPT_TIMESPEC 0x20 | 32 | #define DATE_OPT_TIMESPEC 0x20 |
| 37 | #define DATE_OPT_HINT 0x40 | 33 | #define DATE_OPT_HINT 0x40 |
| 38 | 34 | ||
| 39 | 35 | static void maybe_set_utc(int opt) | |
| 40 | static struct tm *date_conv_time(struct tm *tm_time, const char *t_string) | ||
| 41 | { | ||
| 42 | int nr; | ||
| 43 | char *cp; | ||
| 44 | |||
| 45 | nr = sscanf(t_string, "%2d%2d%2d%2d%d", &(tm_time->tm_mon), | ||
| 46 | &(tm_time->tm_mday), &(tm_time->tm_hour), &(tm_time->tm_min), | ||
| 47 | &(tm_time->tm_year)); | ||
| 48 | |||
| 49 | if (nr < 4 || nr > 5) { | ||
| 50 | bb_error_msg_and_die(bb_msg_invalid_date, t_string); | ||
| 51 | } | ||
| 52 | |||
| 53 | cp = strchr(t_string, '.'); | ||
| 54 | if (cp) { | ||
| 55 | nr = sscanf(cp + 1, "%2d", &(tm_time->tm_sec)); | ||
| 56 | if (nr != 1) { | ||
| 57 | bb_error_msg_and_die(bb_msg_invalid_date, t_string); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | /* correct for century - minor Y2K problem here? */ | ||
| 62 | if (tm_time->tm_year >= 1900) { | ||
| 63 | tm_time->tm_year -= 1900; | ||
| 64 | } | ||
| 65 | /* adjust date */ | ||
| 66 | tm_time->tm_mon -= 1; | ||
| 67 | |||
| 68 | return (tm_time); | ||
| 69 | |||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 73 | /* The new stuff for LRP */ | ||
| 74 | |||
| 75 | static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string) | ||
| 76 | { | 36 | { |
| 77 | struct tm t; | 37 | if ((opt & DATE_OPT_UTC) && putenv("TZ=UTC0") != 0) |
| 78 | 38 | bb_error_msg_and_die(bb_msg_memory_exhausted); | |
| 79 | /* Parse input and assign appropriately to tm_time */ | ||
| 80 | |||
| 81 | if (t = *tm_time, sscanf(t_string, "%d:%d:%d", &t.tm_hour, &t.tm_min, | ||
| 82 | &t.tm_sec) == 3) { | ||
| 83 | /* no adjustments needed */ | ||
| 84 | } else if (t = *tm_time, sscanf(t_string, "%d:%d", &t.tm_hour, | ||
| 85 | &t.tm_min) == 2) { | ||
| 86 | /* no adjustments needed */ | ||
| 87 | } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d:%d", &t.tm_mon, | ||
| 88 | &t.tm_mday, &t.tm_hour, | ||
| 89 | &t.tm_min, &t.tm_sec) == 5) { | ||
| 90 | /* Adjust dates from 1-12 to 0-11 */ | ||
| 91 | t.tm_mon -= 1; | ||
| 92 | } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d", &t.tm_mon, | ||
| 93 | &t.tm_mday, | ||
| 94 | &t.tm_hour, &t.tm_min) == 4) { | ||
| 95 | /* Adjust dates from 1-12 to 0-11 */ | ||
| 96 | t.tm_mon -= 1; | ||
| 97 | } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d:%d", &t.tm_year, | ||
| 98 | &t.tm_mon, &t.tm_mday, | ||
| 99 | &t.tm_hour, &t.tm_min, | ||
| 100 | &t.tm_sec) == 6) { | ||
| 101 | t.tm_year -= 1900; /* Adjust years */ | ||
| 102 | t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
| 103 | } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d", &t.tm_year, | ||
| 104 | &t.tm_mon, &t.tm_mday, | ||
| 105 | &t.tm_hour, &t.tm_min) == 5) { | ||
| 106 | t.tm_year -= 1900; /* Adjust years */ | ||
| 107 | t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
| 108 | } else { | ||
| 109 | bb_error_msg_and_die(bb_msg_invalid_date, t_string); | ||
| 110 | } | ||
| 111 | *tm_time = t; | ||
| 112 | return (tm_time); | ||
| 113 | } | 39 | } |
| 114 | 40 | ||
| 115 | int date_main(int argc, char **argv) | 41 | int date_main(int argc, char **argv) |
| 116 | { | 42 | { |
| 117 | char *date_str = NULL; | ||
| 118 | char *date_fmt = NULL; | ||
| 119 | int set_time; | ||
| 120 | int utc; | ||
| 121 | time_t tm; | 43 | time_t tm; |
| 122 | unsigned long opt; | ||
| 123 | struct tm tm_time; | 44 | struct tm tm_time; |
| 45 | unsigned long opt; | ||
| 46 | int ifmt = -1; | ||
| 47 | char *date_str = NULL; | ||
| 48 | char *date_fmt = NULL; | ||
| 124 | char *filename = NULL; | 49 | char *filename = NULL; |
| 125 | |||
| 126 | int ifmt = 0; | ||
| 127 | char *isofmt_arg; | 50 | char *isofmt_arg; |
| 128 | char *hintfmt_arg; | 51 | char *hintfmt_arg; |
| 129 | 52 | ||
| 130 | bb_opt_complementally = "?:d--s:s--d"; | 53 | bb_opt_complementally = "?:d--s:s--d" |
| 54 | USE_FEATURE_DATE_ISOFMT(":R--I:I--R"); | ||
| 131 | opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" | 55 | opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" |
| 132 | USE_FEATURE_DATE_ISOFMT("I::D:"), | 56 | USE_FEATURE_DATE_ISOFMT("I::D:"), |
| 133 | &date_str, &date_str, &filename | 57 | &date_str, &date_str, &filename |
| 134 | USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); | 58 | USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); |
| 135 | set_time = opt & DATE_OPT_SET; | 59 | maybe_set_utc(opt); |
| 136 | utc = opt & DATE_OPT_UTC; | ||
| 137 | if (utc && putenv("TZ=UTC0") != 0) { | ||
| 138 | bb_error_msg_and_die(bb_msg_memory_exhausted); | ||
| 139 | } | ||
| 140 | 60 | ||
| 141 | if(ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { | 61 | if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { |
| 142 | if (!isofmt_arg) { | 62 | if (!isofmt_arg) { |
| 143 | ifmt = 1; | 63 | ifmt = 0; /* default is date */ |
| 144 | } else { | 64 | } else { |
| 145 | char *isoformats[]={"date","hours","minutes","seconds"}; | 65 | const char * const isoformats[] = |
| 146 | for(ifmt = 4; ifmt;) | 66 | {"date", "hours", "minutes", "seconds"}; |
| 147 | if(!strcmp(isofmt_arg,isoformats[--ifmt])) | 67 | |
| 68 | for (ifmt = 0; ifmt < 4; ifmt++) | ||
| 69 | if (!strcmp(isofmt_arg, isoformats[ifmt])) { | ||
| 148 | break; | 70 | break; |
| 149 | } | 71 | } |
| 150 | if (!ifmt) { | 72 | if (ifmt == 4) /* parse error */ |
| 151 | bb_show_usage(); | 73 | bb_show_usage(); |
| 152 | } | 74 | } |
| 153 | } | 75 | } |
| 154 | 76 | ||
| @@ -156,18 +78,19 @@ int date_main(int argc, char **argv) | |||
| 156 | if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) { | 78 | if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) { |
| 157 | date_fmt = &argv[optind][1]; /* Skip over the '+' */ | 79 | date_fmt = &argv[optind][1]; /* Skip over the '+' */ |
| 158 | } else if (date_str == NULL) { | 80 | } else if (date_str == NULL) { |
| 159 | set_time = 1; | 81 | opt |= DATE_OPT_SET; |
| 160 | date_str = argv[optind]; | 82 | date_str = argv[optind]; |
| 161 | } | 83 | } |
| 162 | 84 | ||
| 163 | /* Now we have parsed all the information except the date format | 85 | /* Now we have parsed all the information except the date format |
| 164 | which depends on whether the clock is being set or read */ | 86 | which depends on whether the clock is being set or read */ |
| 165 | 87 | ||
| 166 | if(filename) { | 88 | if (filename) { |
| 167 | struct stat statbuf; | 89 | struct stat statbuf; |
| 168 | xstat(filename,&statbuf); | 90 | xstat(filename, &statbuf); |
| 169 | tm=statbuf.st_mtime; | 91 | tm = statbuf.st_mtime; |
| 170 | } else time(&tm); | 92 | } else |
| 93 | time(&tm); | ||
| 171 | memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); | 94 | memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); |
| 172 | /* Zero out fields - take her back to midnight! */ | 95 | /* Zero out fields - take her back to midnight! */ |
| 173 | if (date_str != NULL) { | 96 | if (date_str != NULL) { |
| @@ -179,9 +102,64 @@ int date_main(int argc, char **argv) | |||
| 179 | if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) { | 102 | if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) { |
| 180 | strptime(date_str, hintfmt_arg, &tm_time); | 103 | strptime(date_str, hintfmt_arg, &tm_time); |
| 181 | } else if (strchr(date_str, ':') != NULL) { | 104 | } else if (strchr(date_str, ':') != NULL) { |
| 182 | date_conv_ftime(&tm_time, date_str); | 105 | /* Parse input and assign appropriately to tm_time */ |
| 106 | |||
| 107 | if (sscanf(date_str, "%d:%d:%d", &tm_time.tm_hour, &tm_time.tm_min, | ||
| 108 | &tm_time.tm_sec) == 3) { | ||
| 109 | /* no adjustments needed */ | ||
| 110 | } else if (sscanf(date_str, "%d:%d", &tm_time.tm_hour, | ||
| 111 | &tm_time.tm_min) == 2) { | ||
| 112 | /* no adjustments needed */ | ||
| 113 | } else if (sscanf(date_str, "%d.%d-%d:%d:%d", &tm_time.tm_mon, | ||
| 114 | &tm_time.tm_mday, &tm_time.tm_hour, | ||
| 115 | &tm_time.tm_min, &tm_time.tm_sec) == 5) { | ||
| 116 | /* Adjust dates from 1-12 to 0-11 */ | ||
| 117 | tm_time.tm_mon -= 1; | ||
| 118 | } else if (sscanf(date_str, "%d.%d-%d:%d", &tm_time.tm_mon, | ||
| 119 | &tm_time.tm_mday, | ||
| 120 | &tm_time.tm_hour, &tm_time.tm_min) == 4) { | ||
| 121 | /* Adjust dates from 1-12 to 0-11 */ | ||
| 122 | tm_time.tm_mon -= 1; | ||
| 123 | } else if (sscanf(date_str, "%d.%d.%d-%d:%d:%d", &tm_time.tm_year, | ||
| 124 | &tm_time.tm_mon, &tm_time.tm_mday, | ||
| 125 | &tm_time.tm_hour, &tm_time.tm_min, | ||
| 126 | &tm_time.tm_sec) == 6) { | ||
| 127 | tm_time.tm_year -= 1900; /* Adjust years */ | ||
| 128 | tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
| 129 | } else if (sscanf(date_str, "%d.%d.%d-%d:%d", &tm_time.tm_year, | ||
| 130 | &tm_time.tm_mon, &tm_time.tm_mday, | ||
| 131 | &tm_time.tm_hour, &tm_time.tm_min) == 5) { | ||
| 132 | tm_time.tm_year -= 1900; /* Adjust years */ | ||
| 133 | tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
| 134 | } else { | ||
| 135 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | ||
| 136 | } | ||
| 183 | } else { | 137 | } else { |
| 184 | date_conv_time(&tm_time, date_str); | 138 | int nr; |
| 139 | char *cp; | ||
| 140 | |||
| 141 | nr = sscanf(date_str, "%2d%2d%2d%2d%d", &tm_time.tm_mon, | ||
| 142 | &tm_time.tm_mday, &tm_time.tm_hour, &tm_time.tm_min, | ||
| 143 | &tm_time.tm_year); | ||
| 144 | |||
| 145 | if (nr < 4 || nr > 5) { | ||
| 146 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | ||
| 147 | } | ||
| 148 | |||
| 149 | cp = strchr(date_str, '.'); | ||
| 150 | if (cp) { | ||
| 151 | nr = sscanf(cp + 1, "%2d", &tm_time.tm_sec); | ||
| 152 | if (nr != 1) { | ||
| 153 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | /* correct for century - minor Y2K problem here? */ | ||
| 158 | if (tm_time.tm_year >= 1900) { | ||
| 159 | tm_time.tm_year -= 1900; | ||
| 160 | } | ||
| 161 | /* adjust date */ | ||
| 162 | tm_time.tm_mon -= 1; | ||
| 185 | } | 163 | } |
| 186 | 164 | ||
| 187 | /* Correct any day of week and day of year etc. fields */ | 165 | /* Correct any day of week and day of year etc. fields */ |
| @@ -190,12 +168,10 @@ int date_main(int argc, char **argv) | |||
| 190 | if (tm < 0) { | 168 | if (tm < 0) { |
| 191 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | 169 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); |
| 192 | } | 170 | } |
| 193 | if (utc && putenv("TZ=UTC0") != 0) { | 171 | maybe_set_utc(opt); |
| 194 | bb_error_msg_and_die(bb_msg_memory_exhausted); | ||
| 195 | } | ||
| 196 | 172 | ||
| 197 | /* if setting time, set it */ | 173 | /* if setting time, set it */ |
| 198 | if (set_time && stime(&tm) < 0) { | 174 | if ((opt & DATE_OPT_SET) && stime(&tm) < 0) { |
| 199 | bb_perror_msg("cannot set date"); | 175 | bb_perror_msg("cannot set date"); |
| 200 | } | 176 | } |
| 201 | } | 177 | } |
| @@ -203,33 +179,43 @@ int date_main(int argc, char **argv) | |||
| 203 | /* Display output */ | 179 | /* Display output */ |
| 204 | 180 | ||
| 205 | /* Deal with format string */ | 181 | /* Deal with format string */ |
| 182 | |||
| 206 | if (date_fmt == NULL) { | 183 | if (date_fmt == NULL) { |
| 207 | /* Start with the default case */ | 184 | int i; |
| 208 | 185 | date_fmt = xzalloc(32); | |
| 209 | date_fmt = (opt & DATE_OPT_RFC2822 ? | 186 | if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) { |
| 210 | (utc ? "%a, %d %b %Y %H:%M:%S GMT" : | 187 | strcpy(date_fmt, "%Y-%m-%d"); |
| 211 | "%a, %d %b %Y %H:%M:%S %z") : | 188 | if (ifmt > 0) { |
| 212 | "%a %b %e %H:%M:%S %Z %Y"); | 189 | i = 8; |
| 213 | 190 | date_fmt[i++] = 'T'; | |
| 214 | if (ENABLE_FEATURE_DATE_ISOFMT) { | 191 | date_fmt[i++] = '%'; |
| 215 | if (ifmt == 4) | 192 | date_fmt[i++] = 'H'; |
| 216 | date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z"; | 193 | if (ifmt > 1) { |
| 217 | else if (ifmt == 3) | 194 | date_fmt[i++] = ':'; |
| 218 | date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z"; | 195 | date_fmt[i++] = '%'; |
| 219 | else if (ifmt == 2) | 196 | date_fmt[i++] = 'M'; |
| 220 | date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z"; | 197 | } |
| 221 | else if (ifmt == 1) | 198 | if (ifmt > 2) { |
| 222 | date_fmt = "%Y-%m-%d"; | 199 | date_fmt[i++] = ':'; |
| 223 | } | 200 | date_fmt[i++] = '%'; |
| 201 | date_fmt[i++] = 'S'; | ||
| 202 | } | ||
| 203 | format_utc: | ||
| 204 | date_fmt[i++] = '%'; | ||
| 205 | date_fmt[i] = (opt & DATE_OPT_UTC) ? 'Z' : 'z'; | ||
| 206 | } | ||
| 207 | } else if (opt & DATE_OPT_RFC2822) { | ||
| 208 | strcpy(date_fmt, "%a, %d %b %Y %H:%M:%S "); | ||
| 209 | i = 22; | ||
| 210 | goto format_utc; | ||
| 211 | } else /* default case */ | ||
| 212 | date_fmt = "%a %b %e %H:%M:%S %Z %Y"; | ||
| 224 | } | 213 | } |
| 225 | |||
| 226 | if (*date_fmt == '\0') { | ||
| 227 | 214 | ||
| 215 | if (*date_fmt == '\0') { | ||
| 228 | /* With no format string, just print a blank line */ | 216 | /* With no format string, just print a blank line */ |
| 229 | 217 | *bb_common_bufsiz1 = 0; | |
| 230 | *bb_common_bufsiz1=0; | ||
| 231 | } else { | 218 | } else { |
| 232 | |||
| 233 | /* Handle special conversions */ | 219 | /* Handle special conversions */ |
| 234 | 220 | ||
| 235 | if (strncmp(date_fmt, "%f", 2) == 0) { | 221 | if (strncmp(date_fmt, "%f", 2) == 0) { |
diff --git a/coreutils/dd.c b/coreutils/dd.c index 052cd2902..a9536a584 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include "busybox.h" | 11 | #include "busybox.h" |
| 12 | #include <signal.h> /* For FEATURE_DD_SIGNAL_HANDLING */ | ||
| 12 | 13 | ||
| 13 | static const struct suffix_mult dd_suffixes[] = { | 14 | static const struct suffix_mult dd_suffixes[] = { |
| 14 | { "c", 1 }, | 15 | { "c", 1 }, |
| @@ -23,72 +24,72 @@ static const struct suffix_mult dd_suffixes[] = { | |||
| 23 | { NULL, 0 } | 24 | { NULL, 0 } |
| 24 | }; | 25 | }; |
| 25 | 26 | ||
| 26 | static size_t out_full; | 27 | static size_t out_full, out_part, in_full, in_part; |
| 27 | static size_t out_part; | ||
| 28 | static size_t in_full; | ||
| 29 | static size_t in_part; | ||
| 30 | 28 | ||
| 31 | static void dd_output_status(int cur_signal) | 29 | static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal) |
| 32 | { | 30 | { |
| 33 | fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n", | 31 | bb_fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n", |
| 34 | (long)in_full, (long)in_part, | 32 | (long)in_full, (long)in_part, |
| 35 | (long)out_full, (long)out_part); | 33 | (long)out_full, (long)out_part); |
| 36 | } | 34 | } |
| 37 | 35 | ||
| 38 | int dd_main(int argc, char **argv) | 36 | int dd_main(int argc, char **argv) |
| 39 | { | 37 | { |
| 38 | #define sync_flag (1<<0) | ||
| 39 | #define noerror (1<<1) | ||
| 40 | #define trunc_flag (1<<2) | ||
| 41 | #define twobufs_flag (1<<3) | ||
| 42 | int flags = trunc_flag; | ||
| 40 | size_t count = -1, oc = 0, ibs = 512, obs = 512; | 43 | size_t count = -1, oc = 0, ibs = 512, obs = 512; |
| 41 | ssize_t n; | 44 | ssize_t n; |
| 42 | off_t seek = 0, skip = 0; | 45 | off_t seek = 0, skip = 0; |
| 43 | int sync_flag = FALSE, noerror = FALSE, trunc_flag = TRUE, twobufs_flag = 0, | 46 | int oflag, ifd, ofd; |
| 44 | oflag, ifd, ofd, i; | ||
| 45 | const char *infile = NULL, *outfile = NULL; | 47 | const char *infile = NULL, *outfile = NULL; |
| 46 | char *ibuf, *obuf; | 48 | char *ibuf, *obuf; |
| 47 | 49 | ||
| 48 | if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) | 50 | if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) { |
| 49 | { | ||
| 50 | struct sigaction sa; | 51 | struct sigaction sa; |
| 51 | 52 | ||
| 52 | memset(&sa, 0, sizeof(sa)); | 53 | memset(&sa, 0, sizeof(sa)); |
| 53 | sa.sa_handler = dd_output_status; | 54 | sa.sa_handler = dd_output_status; |
| 54 | sa.sa_flags = SA_RESTART; | 55 | sa.sa_flags = SA_RESTART; |
| 55 | sigemptyset(&sa.sa_mask); | 56 | sigemptyset(&sa.sa_mask); |
| 56 | sigaction(SIGUSR1, &sa, 0); | 57 | sigaction(SIGUSR1, &sa, 0); |
| 57 | } | 58 | } |
| 58 | 59 | ||
| 59 | for (i = 1; i < argc; i++) { | 60 | for (n = 1; n < argc; n++) { |
| 60 | if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[i], 4)) { | 61 | if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[n], 4)) { |
| 61 | ibs = bb_xparse_number(argv[i]+4, dd_suffixes); | 62 | ibs = bb_xparse_number(argv[n]+4, dd_suffixes); |
| 62 | twobufs_flag++; | 63 | flags |= twobufs_flag; |
| 63 | } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[i], 4)) { | 64 | } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[n], 4)) { |
| 64 | obs = bb_xparse_number(argv[i]+4, dd_suffixes); | 65 | obs = bb_xparse_number(argv[n]+4, dd_suffixes); |
| 65 | twobufs_flag++; | 66 | flags |= twobufs_flag; |
| 66 | } else if (!strncmp("bs=", argv[i], 3)) { | 67 | } else if (!strncmp("bs=", argv[n], 3)) |
| 67 | ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes); | 68 | ibs = obs = bb_xparse_number(argv[n]+3, dd_suffixes); |
| 68 | } else if (!strncmp("count=", argv[i], 6)) | 69 | else if (!strncmp("count=", argv[n], 6)) |
| 69 | count = bb_xparse_number(argv[i]+6, dd_suffixes); | 70 | count = bb_xparse_number(argv[n]+6, dd_suffixes); |
| 70 | else if (!strncmp("seek=", argv[i], 5)) | 71 | else if (!strncmp("seek=", argv[n], 5)) |
| 71 | seek = bb_xparse_number(argv[i]+5, dd_suffixes); | 72 | seek = bb_xparse_number(argv[n]+5, dd_suffixes); |
| 72 | else if (!strncmp("skip=", argv[i], 5)) | 73 | else if (!strncmp("skip=", argv[n], 5)) |
| 73 | skip = bb_xparse_number(argv[i]+5, dd_suffixes); | 74 | skip = bb_xparse_number(argv[n]+5, dd_suffixes); |
| 74 | else if (!strncmp("if=", argv[i], 3)) | 75 | else if (!strncmp("if=", argv[n], 3)) |
| 75 | infile = argv[i]+3; | 76 | infile = argv[n]+3; |
| 76 | else if (!strncmp("of=", argv[i], 3)) | 77 | else if (!strncmp("of=", argv[n], 3)) |
| 77 | outfile = argv[i]+3; | 78 | outfile = argv[n]+3; |
| 78 | else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[i], 5)) { | 79 | else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[n], 5)) { |
| 79 | ibuf = argv[i]+5; | 80 | ibuf = argv[n]+5; |
| 80 | while (1) { | 81 | while (1) { |
| 81 | if (!strncmp("notrunc", ibuf, 7)) { | 82 | if (!strncmp("notrunc", ibuf, 7)) { |
| 82 | trunc_flag = FALSE; | 83 | flags ^= trunc_flag; |
| 83 | ibuf += 7; | 84 | ibuf += 7; |
| 84 | } else if (!strncmp("sync", ibuf, 4)) { | 85 | } else if (!strncmp("sync", ibuf, 4)) { |
| 85 | sync_flag = TRUE; | 86 | flags |= sync_flag; |
| 86 | ibuf += 4; | 87 | ibuf += 4; |
| 87 | } else if (!strncmp("noerror", ibuf, 7)) { | 88 | } else if (!strncmp("noerror", ibuf, 7)) { |
| 88 | noerror = TRUE; | 89 | flags |= noerror; |
| 89 | ibuf += 7; | 90 | ibuf += 7; |
| 90 | } else { | 91 | } else { |
| 91 | bb_error_msg_and_die(bb_msg_invalid_arg, argv[i]+5, "conv"); | 92 | bb_error_msg_and_die(bb_msg_invalid_arg, argv[n]+5, "conv"); |
| 92 | } | 93 | } |
| 93 | if (ibuf[0] == '\0') break; | 94 | if (ibuf[0] == '\0') break; |
| 94 | if (ibuf[0] == ',') ibuf++; | 95 | if (ibuf[0] == ',') ibuf++; |
| @@ -98,12 +99,14 @@ int dd_main(int argc, char **argv) | |||
| 98 | } | 99 | } |
| 99 | ibuf = xmalloc(ibs); | 100 | ibuf = xmalloc(ibs); |
| 100 | 101 | ||
| 101 | if (twobufs_flag) obuf = xmalloc(obs); | 102 | if (flags & twobufs_flag) |
| 102 | else obuf = ibuf; | 103 | obuf = xmalloc(obs); |
| 104 | else | ||
| 105 | obuf = ibuf; | ||
| 103 | 106 | ||
| 104 | if (infile != NULL) { | 107 | if (infile != NULL) |
| 105 | ifd = xopen(infile, O_RDONLY); | 108 | ifd = xopen(infile, O_RDONLY); |
| 106 | } else { | 109 | else { |
| 107 | ifd = STDIN_FILENO; | 110 | ifd = STDIN_FILENO; |
| 108 | infile = bb_msg_standard_input; | 111 | infile = bb_msg_standard_input; |
| 109 | } | 112 | } |
| @@ -111,20 +114,18 @@ int dd_main(int argc, char **argv) | |||
| 111 | if (outfile != NULL) { | 114 | if (outfile != NULL) { |
| 112 | oflag = O_WRONLY | O_CREAT; | 115 | oflag = O_WRONLY | O_CREAT; |
| 113 | 116 | ||
| 114 | if (!seek && trunc_flag) { | 117 | if (!seek && (flags & trunc_flag)) |
| 115 | oflag |= O_TRUNC; | 118 | oflag |= O_TRUNC; |
| 116 | } | ||
| 117 | 119 | ||
| 118 | ofd = xopen3(outfile, oflag, 0666); | 120 | ofd = xopen3(outfile, oflag, 0666); |
| 119 | 121 | ||
| 120 | if (seek && trunc_flag) { | 122 | if (seek && (flags & trunc_flag)) { |
| 121 | if (ftruncate(ofd, seek * obs) < 0) { | 123 | if (ftruncate(ofd, seek * obs) < 0) { |
| 122 | struct stat st; | 124 | struct stat st; |
| 123 | 125 | ||
| 124 | if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) || | 126 | if (fstat(ofd, &st) < 0 || S_ISREG(st.st_mode) || |
| 125 | S_ISDIR (st.st_mode)) { | 127 | S_ISDIR(st.st_mode)) |
| 126 | bb_perror_msg_and_die("%s", outfile); | 128 | goto die_outfile; |
| 127 | } | ||
| 128 | } | 129 | } |
| 129 | } | 130 | } |
| 130 | } else { | 131 | } else { |
| @@ -145,44 +146,42 @@ int dd_main(int argc, char **argv) | |||
| 145 | } | 146 | } |
| 146 | 147 | ||
| 147 | if (seek) { | 148 | if (seek) { |
| 148 | if (lseek(ofd, seek * obs, SEEK_CUR) < 0) { | 149 | if (lseek(ofd, seek * obs, SEEK_CUR) < 0) |
| 149 | bb_perror_msg_and_die("%s", outfile); | 150 | goto die_outfile; |
| 150 | } | ||
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | while (in_full + in_part != count) { | 153 | while (in_full + in_part != count) { |
| 154 | if (noerror) { | 154 | if (flags & noerror) { |
| 155 | /* Pre-zero the buffer when doing the noerror thing */ | 155 | /* Pre-zero the buffer when doing the noerror thing */ |
| 156 | memset(ibuf, '\0', ibs); | 156 | memset(ibuf, '\0', ibs); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | n = safe_read(ifd, ibuf, ibs); | 159 | n = safe_read(ifd, ibuf, ibs); |
| 160 | if (n == 0) { | 160 | if (n == 0) |
| 161 | break; | 161 | break; |
| 162 | } | ||
| 163 | if (n < 0) { | 162 | if (n < 0) { |
| 164 | if (noerror) { | 163 | if (flags & noerror) { |
| 165 | n = ibs; | 164 | n = ibs; |
| 166 | bb_perror_msg("%s", infile); | 165 | bb_perror_msg("%s", infile); |
| 167 | } else { | 166 | } else |
| 168 | bb_perror_msg_and_die("%s", infile); | 167 | bb_perror_msg_and_die("%s", infile); |
| 169 | } | ||
| 170 | } | 168 | } |
| 171 | if ((size_t)n == ibs) { | 169 | if ((size_t)n == ibs) |
| 172 | in_full++; | 170 | in_full++; |
| 173 | } else { | 171 | else { |
| 174 | in_part++; | 172 | in_part++; |
| 175 | if (sync_flag) { | 173 | if (sync_flag) { |
| 176 | memset(ibuf + n, '\0', ibs - n); | 174 | memset(ibuf + n, '\0', ibs - n); |
| 177 | n = ibs; | 175 | n = ibs; |
| 178 | } | 176 | } |
| 179 | } | 177 | } |
| 180 | if (twobufs_flag) { | 178 | if (flags & twobufs_flag) { |
| 181 | char *tmp = ibuf; | 179 | char *tmp = ibuf; |
| 182 | while (n) { | 180 | while (n) { |
| 183 | size_t d = obs - oc; | 181 | size_t d = obs - oc; |
| 184 | 182 | ||
| 185 | if (d > n) d = n; | 183 | if (d > n) |
| 184 | d = n; | ||
| 186 | memcpy(obuf + oc, tmp, d); | 185 | memcpy(obuf + oc, tmp, d); |
| 187 | n -= d; | 186 | n -= d; |
| 188 | tmp += d; | 187 | tmp += d; |
| @@ -195,8 +194,10 @@ int dd_main(int argc, char **argv) | |||
| 195 | } | 194 | } |
| 196 | } else { | 195 | } else { |
| 197 | xwrite(ofd, ibuf, n); | 196 | xwrite(ofd, ibuf, n); |
| 198 | if (n == ibs) out_full++; | 197 | if (n == ibs) |
| 199 | else out_part++; | 198 | out_full++; |
| 199 | else | ||
| 200 | out_part++; | ||
| 200 | } | 201 | } |
| 201 | } | 202 | } |
| 202 | 203 | ||
| @@ -209,6 +210,7 @@ int dd_main(int argc, char **argv) | |||
| 209 | } | 210 | } |
| 210 | 211 | ||
| 211 | if (close (ofd) < 0) { | 212 | if (close (ofd) < 0) { |
| 213 | die_outfile: | ||
| 212 | bb_perror_msg_and_die("%s", outfile); | 214 | bb_perror_msg_and_die("%s", outfile); |
| 213 | } | 215 | } |
| 214 | 216 | ||
diff --git a/coreutils/du.c b/coreutils/du.c index 29427c779..3cc935553 100644 --- a/coreutils/du.c +++ b/coreutils/du.c | |||
| @@ -23,11 +23,6 @@ | |||
| 23 | * 4) Fixed busybox bug #1284 involving long overflow with human_readable. | 23 | * 4) Fixed busybox bug #1284 involving long overflow with human_readable. |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include <stdlib.h> | ||
| 27 | #include <limits.h> | ||
| 28 | #include <unistd.h> | ||
| 29 | #include <dirent.h> | ||
| 30 | #include <sys/stat.h> | ||
| 31 | #include "busybox.h" | 26 | #include "busybox.h" |
| 32 | 27 | ||
| 33 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 28 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
| @@ -57,7 +52,7 @@ static int one_file_system; | |||
| 57 | static dev_t dir_dev; | 52 | static dev_t dir_dev; |
| 58 | 53 | ||
| 59 | 54 | ||
| 60 | static void print(long size, char *filename) | 55 | static void print(long size, const char * const filename) |
| 61 | { | 56 | { |
| 62 | /* TODO - May not want to defer error checking here. */ | 57 | /* TODO - May not want to defer error checking here. */ |
| 63 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 58 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
| @@ -73,7 +68,7 @@ static void print(long size, char *filename) | |||
| 73 | } | 68 | } |
| 74 | 69 | ||
| 75 | /* tiny recursive du */ | 70 | /* tiny recursive du */ |
| 76 | static long du(char *filename) | 71 | static long du(const char * const filename) |
| 77 | { | 72 | { |
| 78 | struct stat statbuf; | 73 | struct stat statbuf; |
| 79 | long sum; | 74 | long sum; |
diff --git a/coreutils/expr.c b/coreutils/expr.c index 0a1baa19d..e7fdc5f1e 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c | |||
| @@ -37,11 +37,13 @@ typedef enum valtype TYPE; | |||
| 37 | 37 | ||
| 38 | #if ENABLE_EXPR_MATH_SUPPORT_64 | 38 | #if ENABLE_EXPR_MATH_SUPPORT_64 |
| 39 | typedef int64_t arith_t; | 39 | typedef int64_t arith_t; |
| 40 | |||
| 40 | #define PF_REZ "ll" | 41 | #define PF_REZ "ll" |
| 41 | #define PF_REZ_TYPE (long long) | 42 | #define PF_REZ_TYPE (long long) |
| 42 | #define STRTOL(s, e, b) strtoll(s, e, b) | 43 | #define STRTOL(s, e, b) strtoll(s, e, b) |
| 43 | #else | 44 | #else |
| 44 | typedef long arith_t; | 45 | typedef long arith_t; |
| 46 | |||
| 45 | #define PF_REZ "l" | 47 | #define PF_REZ "l" |
| 46 | #define PF_REZ_TYPE (long) | 48 | #define PF_REZ_TYPE (long) |
| 47 | #define STRTOL(s, e, b) strtol(s, e, b) | 49 | #define STRTOL(s, e, b) strtol(s, e, b) |
| @@ -49,8 +51,8 @@ typedef long arith_t; | |||
| 49 | 51 | ||
| 50 | /* A value is.... */ | 52 | /* A value is.... */ |
| 51 | struct valinfo { | 53 | struct valinfo { |
| 52 | TYPE type; /* Which kind. */ | 54 | TYPE type; /* Which kind. */ |
| 53 | union { /* The value itself. */ | 55 | union { /* The value itself. */ |
| 54 | arith_t i; | 56 | arith_t i; |
| 55 | char *s; | 57 | char *s; |
| 56 | } u; | 58 | } u; |
| @@ -60,17 +62,17 @@ typedef struct valinfo VALUE; | |||
| 60 | /* The arguments given to the program, minus the program name. */ | 62 | /* The arguments given to the program, minus the program name. */ |
| 61 | static char **args; | 63 | static char **args; |
| 62 | 64 | ||
| 63 | static VALUE *docolon (VALUE *sv, VALUE *pv); | 65 | static VALUE *docolon(VALUE * sv, VALUE * pv); |
| 64 | static VALUE *eval (void); | 66 | static VALUE *eval(void); |
| 65 | static VALUE *int_value (arith_t i); | 67 | static VALUE *int_value(arith_t i); |
| 66 | static VALUE *str_value (char *s); | 68 | static VALUE *str_value(char *s); |
| 67 | static int nextarg (char *str); | 69 | static int nextarg(char *str); |
| 68 | static int null (VALUE *v); | 70 | static int null(VALUE * v); |
| 69 | static int toarith (VALUE *v); | 71 | static int toarith(VALUE * v); |
| 70 | static void freev (VALUE *v); | 72 | static void freev(VALUE * v); |
| 71 | static void tostring (VALUE *v); | 73 | static void tostring(VALUE * v); |
| 72 | 74 | ||
| 73 | int expr_main (int argc, char **argv) | 75 | int expr_main(int argc, char **argv) |
| 74 | { | 76 | { |
| 75 | VALUE *v; | 77 | VALUE *v; |
| 76 | 78 | ||
| @@ -80,25 +82,25 @@ int expr_main (int argc, char **argv) | |||
| 80 | 82 | ||
| 81 | args = argv + 1; | 83 | args = argv + 1; |
| 82 | 84 | ||
| 83 | v = eval (); | 85 | v = eval(); |
| 84 | if (*args) | 86 | if (*args) |
| 85 | bb_error_msg_and_die ("syntax error"); | 87 | bb_error_msg_and_die("syntax error"); |
| 86 | 88 | ||
| 87 | if (v->type == integer) | 89 | if (v->type == integer) |
| 88 | printf ("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); | 90 | bb_printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); |
| 89 | else | 91 | else |
| 90 | puts (v->u.s); | 92 | puts(v->u.s); |
| 91 | 93 | ||
| 92 | exit (null (v)); | 94 | exit(null(v)); |
| 93 | } | 95 | } |
| 94 | 96 | ||
| 95 | /* Return a VALUE for I. */ | 97 | /* Return a VALUE for I. */ |
| 96 | 98 | ||
| 97 | static VALUE *int_value (arith_t i) | 99 | static VALUE *int_value(arith_t i) |
| 98 | { | 100 | { |
| 99 | VALUE *v; | 101 | VALUE *v; |
| 100 | 102 | ||
| 101 | v = xmalloc (sizeof(VALUE)); | 103 | v = xmalloc(sizeof(VALUE)); |
| 102 | v->type = integer; | 104 | v->type = integer; |
| 103 | v->u.i = i; | 105 | v->u.i = i; |
| 104 | return v; | 106 | return v; |
| @@ -106,7 +108,7 @@ static VALUE *int_value (arith_t i) | |||
| 106 | 108 | ||
| 107 | /* Return a VALUE for S. */ | 109 | /* Return a VALUE for S. */ |
| 108 | 110 | ||
| 109 | static VALUE *str_value (char *s) | 111 | static VALUE *str_value(char *s) |
| 110 | { | 112 | { |
| 111 | VALUE *v; | 113 | VALUE *v; |
| 112 | 114 | ||
| @@ -118,28 +120,26 @@ static VALUE *str_value (char *s) | |||
| 118 | 120 | ||
| 119 | /* Free VALUE V, including structure components. */ | 121 | /* Free VALUE V, including structure components. */ |
| 120 | 122 | ||
| 121 | static void freev (VALUE *v) | 123 | static void freev(VALUE * v) |
| 122 | { | 124 | { |
| 123 | if (v->type == string) | 125 | if (v->type == string) |
| 124 | free (v->u.s); | 126 | free(v->u.s); |
| 125 | free (v); | 127 | free(v); |
| 126 | } | 128 | } |
| 127 | 129 | ||
| 128 | /* Return nonzero if V is a null-string or zero-number. */ | 130 | /* Return nonzero if V is a null-string or zero-number. */ |
| 129 | 131 | ||
| 130 | static int null (VALUE *v) | 132 | static int null(VALUE * v) |
| 131 | { | 133 | { |
| 132 | switch (v->type) { | 134 | if (v->type == integer) |
| 133 | case integer: | 135 | return v->u.i == 0; |
| 134 | return v->u.i == 0; | 136 | else /* string: */ |
| 135 | default: /* string: */ | 137 | return v->u.s[0] == '\0' || strcmp(v->u.s, "0") == 0; |
| 136 | return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0; | ||
| 137 | } | ||
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | /* Coerce V to a string value (can't fail). */ | 140 | /* Coerce V to a string value (can't fail). */ |
| 141 | 141 | ||
| 142 | static void tostring (VALUE *v) | 142 | static void tostring(VALUE * v) |
| 143 | { | 143 | { |
| 144 | if (v->type == integer) { | 144 | if (v->type == integer) { |
| 145 | v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i); | 145 | v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i); |
| @@ -149,9 +149,9 @@ static void tostring (VALUE *v) | |||
| 149 | 149 | ||
| 150 | /* Coerce V to an integer value. Return 1 on success, 0 on failure. */ | 150 | /* Coerce V to an integer value. Return 1 on success, 0 on failure. */ |
| 151 | 151 | ||
| 152 | static int toarith (VALUE *v) | 152 | static int toarith(VALUE * v) |
| 153 | { | 153 | { |
| 154 | if(v->type == string) { | 154 | if (v->type == string) { |
| 155 | arith_t i; | 155 | arith_t i; |
| 156 | char *e; | 156 | char *e; |
| 157 | 157 | ||
| @@ -160,7 +160,7 @@ static int toarith (VALUE *v) | |||
| 160 | i = STRTOL(v->u.s, &e, 10); | 160 | i = STRTOL(v->u.s, &e, 10); |
| 161 | if ((v->u.s == e) || *e) | 161 | if ((v->u.s == e) || *e) |
| 162 | return 0; | 162 | return 0; |
| 163 | free (v->u.s); | 163 | free(v->u.s); |
| 164 | v->u.i = i; | 164 | v->u.i = i; |
| 165 | v->type = integer; | 165 | v->type = integer; |
| 166 | } | 166 | } |
| @@ -170,221 +170,207 @@ static int toarith (VALUE *v) | |||
| 170 | /* Return nonzero if the next token matches STR exactly. | 170 | /* Return nonzero if the next token matches STR exactly. |
| 171 | STR must not be NULL. */ | 171 | STR must not be NULL. */ |
| 172 | 172 | ||
| 173 | static int | 173 | static int nextarg(char *str) |
| 174 | nextarg (char *str) | ||
| 175 | { | 174 | { |
| 176 | if (*args == NULL) | 175 | if (*args == NULL) |
| 177 | return 0; | 176 | return 0; |
| 178 | return strcmp (*args, str) == 0; | 177 | return strcmp(*args, str) == 0; |
| 179 | } | 178 | } |
| 180 | 179 | ||
| 181 | /* The comparison operator handling functions. */ | 180 | /* The comparison operator handling functions. */ |
| 182 | 181 | ||
| 183 | static int cmp_common (VALUE *l, VALUE *r, int op) | 182 | static int cmp_common(VALUE * l, VALUE * r, int op) |
| 184 | { | 183 | { |
| 185 | int cmpval; | 184 | int cmpval; |
| 186 | 185 | ||
| 187 | if (l->type == string || r->type == string) { | 186 | if (l->type == string || r->type == string) { |
| 188 | tostring (l); | 187 | tostring(l); |
| 189 | tostring (r); | 188 | tostring(r); |
| 190 | cmpval = strcmp (l->u.s, r->u.s); | 189 | cmpval = strcmp(l->u.s, r->u.s); |
| 191 | } | 190 | } else |
| 192 | else | ||
| 193 | cmpval = l->u.i - r->u.i; | 191 | cmpval = l->u.i - r->u.i; |
| 194 | switch(op) { | 192 | if (op == '<') |
| 195 | case '<': | 193 | return cmpval < 0; |
| 196 | return cmpval < 0; | 194 | else if (op == ('L' + 'E')) |
| 197 | case ('L'+'E'): | 195 | return cmpval <= 0; |
| 198 | return cmpval <= 0; | 196 | else if (op == '=') |
| 199 | case '=': | 197 | return cmpval == 0; |
| 200 | return cmpval == 0; | 198 | else if (op == '!') |
| 201 | case '!': | 199 | return cmpval != 0; |
| 202 | return cmpval != 0; | 200 | else if (op == '>') |
| 203 | case '>': | 201 | return cmpval > 0; |
| 204 | return cmpval > 0; | 202 | else /* >= */ |
| 205 | default: /* >= */ | 203 | return cmpval >= 0; |
| 206 | return cmpval >= 0; | ||
| 207 | } | ||
| 208 | } | 204 | } |
| 209 | 205 | ||
| 210 | /* The arithmetic operator handling functions. */ | 206 | /* The arithmetic operator handling functions. */ |
| 211 | 207 | ||
| 212 | static arith_t arithmetic_common (VALUE *l, VALUE *r, int op) | 208 | static arith_t arithmetic_common(VALUE * l, VALUE * r, int op) |
| 213 | { | 209 | { |
| 214 | arith_t li, ri; | 210 | arith_t li, ri; |
| 215 | 211 | ||
| 216 | if (!toarith (l) || !toarith (r)) | 212 | if (!toarith(l) || !toarith(r)) |
| 217 | bb_error_msg_and_die ("non-numeric argument"); | 213 | bb_error_msg_and_die("non-numeric argument"); |
| 218 | li = l->u.i; | 214 | li = l->u.i; |
| 219 | ri = r->u.i; | 215 | ri = r->u.i; |
| 220 | if((op == '/' || op == '%') && ri == 0) | 216 | if ((op == '/' || op == '%') && ri == 0) |
| 221 | bb_error_msg_and_die ( "division by zero"); | 217 | bb_error_msg_and_die("division by zero"); |
| 222 | switch(op) { | 218 | if (op == '+') |
| 223 | case '+': | ||
| 224 | return li + ri; | 219 | return li + ri; |
| 225 | case '-': | 220 | else if (op == '-') |
| 226 | return li - ri; | 221 | return li - ri; |
| 227 | case '*': | 222 | else if (op == '*') |
| 228 | return li * ri; | 223 | return li * ri; |
| 229 | case '/': | 224 | else if (op == '/') |
| 230 | return li / ri; | 225 | return li / ri; |
| 231 | default: | 226 | else |
| 232 | return li % ri; | 227 | return li % ri; |
| 233 | } | ||
| 234 | } | 228 | } |
| 235 | 229 | ||
| 236 | /* Do the : operator. | 230 | /* Do the : operator. |
| 237 | SV is the VALUE for the lhs (the string), | 231 | SV is the VALUE for the lhs (the string), |
| 238 | PV is the VALUE for the rhs (the pattern). */ | 232 | PV is the VALUE for the rhs (the pattern). */ |
| 239 | 233 | ||
| 240 | static VALUE *docolon (VALUE *sv, VALUE *pv) | 234 | static VALUE *docolon(VALUE * sv, VALUE * pv) |
| 241 | { | 235 | { |
| 242 | VALUE *v; | 236 | VALUE *v; |
| 243 | regex_t re_buffer; | 237 | regex_t re_buffer; |
| 244 | const int NMATCH = 2; | 238 | const int NMATCH = 2; |
| 245 | regmatch_t re_regs[NMATCH]; | 239 | regmatch_t re_regs[NMATCH]; |
| 246 | 240 | ||
| 247 | tostring (sv); | 241 | tostring(sv); |
| 248 | tostring (pv); | 242 | tostring(pv); |
| 249 | 243 | ||
| 250 | if (pv->u.s[0] == '^') { | 244 | if (pv->u.s[0] == '^') { |
| 251 | fprintf (stderr, "\ | 245 | fprintf(stderr, "\ |
| 252 | warning: unportable BRE: `%s': using `^' as the first character\n\ | 246 | warning: unportable BRE: `%s': using `^' as the first character\n\ |
| 253 | of a basic regular expression is not portable; it is being ignored", | 247 | of a basic regular expression is not portable; it is being ignored", pv->u.s); |
| 254 | pv->u.s); | ||
| 255 | } | 248 | } |
| 256 | 249 | ||
| 257 | memset (&re_buffer, 0, sizeof (re_buffer)); | 250 | memset(&re_buffer, 0, sizeof(re_buffer)); |
| 258 | memset (re_regs, 0, sizeof (*re_regs)); | 251 | memset(re_regs, 0, sizeof(*re_regs)); |
| 259 | if( regcomp (&re_buffer, pv->u.s, 0) != 0 ) | 252 | if (regcomp(&re_buffer, pv->u.s, 0) != 0) |
| 260 | bb_error_msg_and_die("Invalid regular expression"); | 253 | bb_error_msg_and_die("Invalid regular expression"); |
| 261 | 254 | ||
| 262 | /* expr uses an anchored pattern match, so check that there was a | 255 | /* expr uses an anchored pattern match, so check that there was a |
| 263 | * match and that the match starts at offset 0. */ | 256 | * match and that the match starts at offset 0. */ |
| 264 | if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && | 257 | if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && |
| 265 | re_regs[0].rm_so == 0) { | 258 | re_regs[0].rm_so == 0) { |
| 266 | /* Were \(...\) used? */ | 259 | /* Were \(...\) used? */ |
| 267 | if (re_buffer.re_nsub > 0) { | 260 | if (re_buffer.re_nsub > 0) { |
| 268 | sv->u.s[re_regs[1].rm_eo] = '\0'; | 261 | sv->u.s[re_regs[1].rm_eo] = '\0'; |
| 269 | v = str_value (sv->u.s + re_regs[1].rm_so); | 262 | v = str_value(sv->u.s + re_regs[1].rm_so); |
| 270 | } | 263 | } else |
| 271 | else | 264 | v = int_value(re_regs[0].rm_eo); |
| 272 | v = int_value (re_regs[0].rm_eo); | 265 | } else { |
| 273 | } | ||
| 274 | else { | ||
| 275 | /* Match failed -- return the right kind of null. */ | 266 | /* Match failed -- return the right kind of null. */ |
| 276 | if (re_buffer.re_nsub > 0) | 267 | if (re_buffer.re_nsub > 0) |
| 277 | v = str_value (""); | 268 | v = str_value(""); |
| 278 | else | 269 | else |
| 279 | v = int_value (0); | 270 | v = int_value(0); |
| 280 | } | 271 | } |
| 281 | return v; | 272 | return v; |
| 282 | } | 273 | } |
| 283 | 274 | ||
| 284 | /* Handle bare operands and ( expr ) syntax. */ | 275 | /* Handle bare operands and ( expr ) syntax. */ |
| 285 | 276 | ||
| 286 | static VALUE *eval7 (void) | 277 | static VALUE *eval7(void) |
| 287 | { | 278 | { |
| 288 | VALUE *v; | 279 | VALUE *v; |
| 289 | 280 | ||
| 290 | if (!*args) | 281 | if (!*args) |
| 291 | bb_error_msg_and_die ( "syntax error"); | 282 | bb_error_msg_and_die("syntax error"); |
| 292 | 283 | ||
| 293 | if (nextarg ("(")) { | 284 | if (nextarg("(")) { |
| 294 | args++; | 285 | args++; |
| 295 | v = eval (); | 286 | v = eval(); |
| 296 | if (!nextarg (")")) | 287 | if (!nextarg(")")) |
| 297 | bb_error_msg_and_die ( "syntax error"); | 288 | bb_error_msg_and_die("syntax error"); |
| 298 | args++; | 289 | args++; |
| 299 | return v; | 290 | return v; |
| 300 | } | 291 | } |
| 301 | 292 | ||
| 302 | if (nextarg (")")) | 293 | if (nextarg(")")) |
| 303 | bb_error_msg_and_die ( "syntax error"); | 294 | bb_error_msg_and_die("syntax error"); |
| 304 | 295 | ||
| 305 | return str_value (*args++); | 296 | return str_value(*args++); |
| 306 | } | 297 | } |
| 307 | 298 | ||
| 308 | /* Handle match, substr, index, length, and quote keywords. */ | 299 | /* Handle match, substr, index, length, and quote keywords. */ |
| 309 | 300 | ||
| 310 | static VALUE *eval6 (void) | 301 | static VALUE *eval6(void) |
| 311 | { | 302 | { |
| 312 | VALUE *l, *r, *v, *i1, *i2; | 303 | VALUE *l, *r, *v, *i1, *i2; |
| 313 | 304 | ||
| 314 | if (nextarg ("quote")) { | 305 | if (nextarg("quote")) { |
| 315 | args++; | 306 | args++; |
| 316 | if (!*args) | 307 | if (!*args) |
| 317 | bb_error_msg_and_die ( "syntax error"); | 308 | bb_error_msg_and_die("syntax error"); |
| 318 | return str_value (*args++); | 309 | return str_value(*args++); |
| 319 | } | 310 | } else if (nextarg("length")) { |
| 320 | else if (nextarg ("length")) { | ||
| 321 | args++; | 311 | args++; |
| 322 | r = eval6 (); | 312 | r = eval6(); |
| 323 | tostring (r); | 313 | tostring(r); |
| 324 | v = int_value (strlen (r->u.s)); | 314 | v = int_value(strlen(r->u.s)); |
| 325 | freev (r); | 315 | freev(r); |
| 326 | return v; | 316 | return v; |
| 327 | } | 317 | } else if (nextarg("match")) { |
| 328 | else if (nextarg ("match")) { | ||
| 329 | args++; | 318 | args++; |
| 330 | l = eval6 (); | 319 | l = eval6(); |
| 331 | r = eval6 (); | 320 | r = eval6(); |
| 332 | v = docolon (l, r); | 321 | v = docolon(l, r); |
| 333 | freev (l); | 322 | freev(l); |
| 334 | freev (r); | 323 | freev(r); |
| 335 | return v; | 324 | return v; |
| 336 | } | 325 | } else if (nextarg("index")) { |
| 337 | else if (nextarg ("index")) { | ||
| 338 | args++; | 326 | args++; |
| 339 | l = eval6 (); | 327 | l = eval6(); |
| 340 | r = eval6 (); | 328 | r = eval6(); |
| 341 | tostring (l); | 329 | tostring(l); |
| 342 | tostring (r); | 330 | tostring(r); |
| 343 | v = int_value (strcspn (l->u.s, r->u.s) + 1); | 331 | v = int_value(strcspn(l->u.s, r->u.s) + 1); |
| 344 | if (v->u.i == (arith_t) strlen (l->u.s) + 1) | 332 | if (v->u.i == (arith_t) strlen(l->u.s) + 1) |
| 345 | v->u.i = 0; | 333 | v->u.i = 0; |
| 346 | freev (l); | 334 | freev(l); |
| 347 | freev (r); | 335 | freev(r); |
| 348 | return v; | 336 | return v; |
| 349 | } | 337 | } else if (nextarg("substr")) { |
| 350 | else if (nextarg ("substr")) { | ||
| 351 | args++; | 338 | args++; |
| 352 | l = eval6 (); | 339 | l = eval6(); |
| 353 | i1 = eval6 (); | 340 | i1 = eval6(); |
| 354 | i2 = eval6 (); | 341 | i2 = eval6(); |
| 355 | tostring (l); | 342 | tostring(l); |
| 356 | if (!toarith (i1) || !toarith (i2) | 343 | if (!toarith(i1) || !toarith(i2) |
| 357 | || i1->u.i > (arith_t) strlen (l->u.s) | 344 | || i1->u.i > (arith_t) strlen(l->u.s) |
| 358 | || i1->u.i <= 0 || i2->u.i <= 0) | 345 | || i1->u.i <= 0 || i2->u.i <= 0) |
| 359 | v = str_value (""); | 346 | v = str_value(""); |
| 360 | else { | 347 | else { |
| 361 | v = xmalloc (sizeof(VALUE)); | 348 | v = xmalloc(sizeof(VALUE)); |
| 362 | v->type = string; | 349 | v->type = string; |
| 363 | v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); | 350 | v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); |
| 364 | } | 351 | } |
| 365 | freev (l); | 352 | freev(l); |
| 366 | freev (i1); | 353 | freev(i1); |
| 367 | freev (i2); | 354 | freev(i2); |
| 368 | return v; | 355 | return v; |
| 369 | } | 356 | } else |
| 370 | else | 357 | return eval7(); |
| 371 | return eval7 (); | ||
| 372 | } | 358 | } |
| 373 | 359 | ||
| 374 | /* Handle : operator (pattern matching). | 360 | /* Handle : operator (pattern matching). |
| 375 | Calls docolon to do the real work. */ | 361 | Calls docolon to do the real work. */ |
| 376 | 362 | ||
| 377 | static VALUE *eval5 (void) | 363 | static VALUE *eval5(void) |
| 378 | { | 364 | { |
| 379 | VALUE *l, *r, *v; | 365 | VALUE *l, *r, *v; |
| 380 | 366 | ||
| 381 | l = eval6 (); | 367 | l = eval6(); |
| 382 | while (nextarg (":")) { | 368 | while (nextarg(":")) { |
| 383 | args++; | 369 | args++; |
| 384 | r = eval6 (); | 370 | r = eval6(); |
| 385 | v = docolon (l, r); | 371 | v = docolon(l, r); |
| 386 | freev (l); | 372 | freev(l); |
| 387 | freev (r); | 373 | freev(r); |
| 388 | l = v; | 374 | l = v; |
| 389 | } | 375 | } |
| 390 | return l; | 376 | return l; |
| @@ -392,128 +378,126 @@ static VALUE *eval5 (void) | |||
| 392 | 378 | ||
| 393 | /* Handle *, /, % operators. */ | 379 | /* Handle *, /, % operators. */ |
| 394 | 380 | ||
| 395 | static VALUE *eval4 (void) | 381 | static VALUE *eval4(void) |
| 396 | { | 382 | { |
| 397 | VALUE *l, *r; | 383 | VALUE *l, *r; |
| 398 | int op; | 384 | int op; |
| 399 | arith_t val; | 385 | arith_t val; |
| 400 | 386 | ||
| 401 | l = eval5 (); | 387 | l = eval5(); |
| 402 | while (1) { | 388 | while (1) { |
| 403 | if (nextarg ("*")) | 389 | if (nextarg("*")) |
| 404 | op = '*'; | 390 | op = '*'; |
| 405 | else if (nextarg ("/")) | 391 | else if (nextarg("/")) |
| 406 | op = '/'; | 392 | op = '/'; |
| 407 | else if (nextarg ("%")) | 393 | else if (nextarg("%")) |
| 408 | op = '%'; | 394 | op = '%'; |
| 409 | else | 395 | else |
| 410 | return l; | 396 | return l; |
| 411 | args++; | 397 | args++; |
| 412 | r = eval5 (); | 398 | r = eval5(); |
| 413 | val = arithmetic_common (l, r, op); | 399 | val = arithmetic_common(l, r, op); |
| 414 | freev (l); | 400 | freev(l); |
| 415 | freev (r); | 401 | freev(r); |
| 416 | l = int_value (val); | 402 | l = int_value(val); |
| 417 | } | 403 | } |
| 418 | } | 404 | } |
| 419 | 405 | ||
| 420 | /* Handle +, - operators. */ | 406 | /* Handle +, - operators. */ |
| 421 | 407 | ||
| 422 | static VALUE *eval3 (void) | 408 | static VALUE *eval3(void) |
| 423 | { | 409 | { |
| 424 | VALUE *l, *r; | 410 | VALUE *l, *r; |
| 425 | int op; | 411 | int op; |
| 426 | arith_t val; | 412 | arith_t val; |
| 427 | 413 | ||
| 428 | l = eval4 (); | 414 | l = eval4(); |
| 429 | while (1) { | 415 | while (1) { |
| 430 | if (nextarg ("+")) | 416 | if (nextarg("+")) |
| 431 | op = '+'; | 417 | op = '+'; |
| 432 | else if (nextarg ("-")) | 418 | else if (nextarg("-")) |
| 433 | op = '-'; | 419 | op = '-'; |
| 434 | else | 420 | else |
| 435 | return l; | 421 | return l; |
| 436 | args++; | 422 | args++; |
| 437 | r = eval4 (); | 423 | r = eval4(); |
| 438 | val = arithmetic_common (l, r, op); | 424 | val = arithmetic_common(l, r, op); |
| 439 | freev (l); | 425 | freev(l); |
| 440 | freev (r); | 426 | freev(r); |
| 441 | l = int_value (val); | 427 | l = int_value(val); |
| 442 | } | 428 | } |
| 443 | } | 429 | } |
| 444 | 430 | ||
| 445 | /* Handle comparisons. */ | 431 | /* Handle comparisons. */ |
| 446 | 432 | ||
| 447 | static VALUE *eval2 (void) | 433 | static VALUE *eval2(void) |
| 448 | { | 434 | { |
| 449 | VALUE *l, *r; | 435 | VALUE *l, *r; |
| 450 | int op; | 436 | int op; |
| 451 | arith_t val; | 437 | arith_t val; |
| 452 | 438 | ||
| 453 | l = eval3 (); | 439 | l = eval3(); |
| 454 | while (1) { | 440 | while (1) { |
| 455 | if (nextarg ("<")) | 441 | if (nextarg("<")) |
| 456 | op = '<'; | 442 | op = '<'; |
| 457 | else if (nextarg ("<=")) | 443 | else if (nextarg("<=")) |
| 458 | op = 'L'+'E'; | 444 | op = 'L' + 'E'; |
| 459 | else if (nextarg ("=") || nextarg ("==")) | 445 | else if (nextarg("=") || nextarg("==")) |
| 460 | op = '='; | 446 | op = '='; |
| 461 | else if (nextarg ("!=")) | 447 | else if (nextarg("!=")) |
| 462 | op = '!'; | 448 | op = '!'; |
| 463 | else if (nextarg (">=")) | 449 | else if (nextarg(">=")) |
| 464 | op = 'G'+'E'; | 450 | op = 'G' + 'E'; |
| 465 | else if (nextarg (">")) | 451 | else if (nextarg(">")) |
| 466 | op = '>'; | 452 | op = '>'; |
| 467 | else | 453 | else |
| 468 | return l; | 454 | return l; |
| 469 | args++; | 455 | args++; |
| 470 | r = eval3 (); | 456 | r = eval3(); |
| 471 | toarith (l); | 457 | toarith(l); |
| 472 | toarith (r); | 458 | toarith(r); |
| 473 | val = cmp_common (l, r, op); | 459 | val = cmp_common(l, r, op); |
| 474 | freev (l); | 460 | freev(l); |
| 475 | freev (r); | 461 | freev(r); |
| 476 | l = int_value (val); | 462 | l = int_value(val); |
| 477 | } | 463 | } |
| 478 | } | 464 | } |
| 479 | 465 | ||
| 480 | /* Handle &. */ | 466 | /* Handle &. */ |
| 481 | 467 | ||
| 482 | static VALUE *eval1 (void) | 468 | static VALUE *eval1(void) |
| 483 | { | 469 | { |
| 484 | VALUE *l, *r; | 470 | VALUE *l, *r; |
| 485 | 471 | ||
| 486 | l = eval2 (); | 472 | l = eval2(); |
| 487 | while (nextarg ("&")) { | 473 | while (nextarg("&")) { |
| 488 | args++; | 474 | args++; |
| 489 | r = eval2 (); | 475 | r = eval2(); |
| 490 | if (null (l) || null (r)) { | 476 | if (null(l) || null(r)) { |
| 491 | freev (l); | 477 | freev(l); |
| 492 | freev (r); | 478 | freev(r); |
| 493 | l = int_value (0); | 479 | l = int_value(0); |
| 494 | } | 480 | } else |
| 495 | else | 481 | freev(r); |
| 496 | freev (r); | ||
| 497 | } | 482 | } |
| 498 | return l; | 483 | return l; |
| 499 | } | 484 | } |
| 500 | 485 | ||
| 501 | /* Handle |. */ | 486 | /* Handle |. */ |
| 502 | 487 | ||
| 503 | static VALUE *eval (void) | 488 | static VALUE *eval(void) |
| 504 | { | 489 | { |
| 505 | VALUE *l, *r; | 490 | VALUE *l, *r; |
| 506 | 491 | ||
| 507 | l = eval1 (); | 492 | l = eval1(); |
| 508 | while (nextarg ("|")) { | 493 | while (nextarg("|")) { |
| 509 | args++; | 494 | args++; |
| 510 | r = eval1 (); | 495 | r = eval1(); |
| 511 | if (null (l)) { | 496 | if (null(l)) { |
| 512 | freev (l); | 497 | freev(l); |
| 513 | l = r; | 498 | l = r; |
| 514 | } | 499 | } else |
| 515 | else | 500 | freev(r); |
| 516 | freev (r); | ||
| 517 | } | 501 | } |
| 518 | return l; | 502 | return l; |
| 519 | } | 503 | } |
diff --git a/coreutils/sum.c b/coreutils/sum.c index 2edd92036..d6a76dbbc 100644 --- a/coreutils/sum.c +++ b/coreutils/sum.c | |||
| @@ -13,12 +13,6 @@ | |||
| 13 | * Licensed under the GPL v2, see the file LICENSE in this tarball. | 13 | * Licensed under the GPL v2, see the file LICENSE in this tarball. |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <stdio.h> | ||
| 17 | #include <sys/types.h> | ||
| 18 | #include <sys/stat.h> | ||
| 19 | #include <fcntl.h> | ||
| 20 | #include <unistd.h> | ||
| 21 | |||
| 22 | #include "busybox.h" | 16 | #include "busybox.h" |
| 23 | 17 | ||
| 24 | /* 1 if any of the files read were the standard input */ | 18 | /* 1 if any of the files read were the standard input */ |
| @@ -38,14 +32,15 @@ static int bsd_sum_file(const char *file, int print_name) | |||
| 38 | int checksum = 0; /* The checksum mod 2^16. */ | 32 | int checksum = 0; /* The checksum mod 2^16. */ |
| 39 | uintmax_t total_bytes = 0; /* The number of bytes. */ | 33 | uintmax_t total_bytes = 0; /* The number of bytes. */ |
| 40 | int ch; /* Each character read. */ | 34 | int ch; /* Each character read. */ |
| 35 | int ret = 0; | ||
| 41 | 36 | ||
| 42 | if (IS_STDIN(file)) { | 37 | if (IS_STDIN(file)) { |
| 43 | fp = stdin; | 38 | fp = stdin; |
| 44 | have_read_stdin = 1; | 39 | have_read_stdin++; |
| 45 | } else { | 40 | } else { |
| 46 | fp = bb_wfopen(file, "r"); | 41 | fp = bb_wfopen(file, "r"); |
| 47 | if (fp == NULL) | 42 | if (fp == NULL) |
| 48 | return 0; | 43 | goto out; |
| 49 | } | 44 | } |
| 50 | 45 | ||
| 51 | while ((ch = getc(fp)) != EOF) { | 46 | while ((ch = getc(fp)) != EOF) { |
| @@ -58,21 +53,21 @@ static int bsd_sum_file(const char *file, int print_name) | |||
| 58 | if (ferror(fp)) { | 53 | if (ferror(fp)) { |
| 59 | bb_perror_msg(file); | 54 | bb_perror_msg(file); |
| 60 | bb_fclose_nonstdin(fp); | 55 | bb_fclose_nonstdin(fp); |
| 61 | return 0; | 56 | goto out; |
| 62 | } | 57 | } |
| 63 | 58 | ||
| 64 | if (bb_fclose_nonstdin(fp) == EOF) { | 59 | if (bb_fclose_nonstdin(fp) == EOF) { |
| 65 | bb_perror_msg(file); | 60 | bb_perror_msg(file); |
| 66 | return 0; | 61 | goto out; |
| 67 | } | 62 | } |
| 68 | 63 | ret++; | |
| 69 | printf("%05d %5ju ", checksum, (total_bytes+1023)/1024); | 64 | printf("%05d %5ju ", checksum, (total_bytes+1023)/1024); |
| 70 | if (print_name > 1) | 65 | if (print_name > 1) |
| 71 | puts(file); | 66 | puts(file); |
| 72 | else | 67 | else |
| 73 | printf("\n"); | 68 | printf("\n"); |
| 74 | 69 | out: | |
| 75 | return 1; | 70 | return ret; |
| 76 | } | 71 | } |
| 77 | 72 | ||
| 78 | /* Calculate and print the checksum and the size in 512-byte blocks | 73 | /* Calculate and print the checksum and the size in 512-byte blocks |
diff --git a/coreutils/tail.c b/coreutils/tail.c index 80a66fbf5..49f1bcd6a 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
| @@ -42,20 +42,25 @@ static const struct suffix_mult tail_suffixes[] = { | |||
| 42 | 42 | ||
| 43 | static int status; | 43 | static int status; |
| 44 | 44 | ||
| 45 | static void tail_xprint_header(const char *fmt, const char *filename) | 45 | static void tail_xbb_full_write(const char *buf, size_t len) |
| 46 | { | 46 | { |
| 47 | /* If we get an output error, there is really no sense in continuing. */ | 47 | /* If we get a write error, there is really no sense in continuing. */ |
| 48 | if (dprintf(STDOUT_FILENO, fmt, filename) < 0) { | 48 | if (full_write(STDOUT_FILENO, buf, len) < 0) |
| 49 | bb_perror_nomsg_and_die(); | 49 | bb_perror_nomsg_and_die(); |
| 50 | } | ||
| 51 | } | 50 | } |
| 52 | 51 | ||
| 53 | /* len should probably be size_t */ | 52 | static void tail_xprint_header(const char *fmt, const char *filename) |
| 54 | static void tail_xbb_full_write(const char *buf, size_t len) | ||
| 55 | { | 53 | { |
| 56 | /* If we get a write error, there is really no sense in continuing. */ | 54 | #if defined __GLIBC__ |
| 57 | if (full_write(STDOUT_FILENO, buf, len) < 0) | 55 | if (dprintf(STDOUT_FILENO, fmt, filename) < 0) { |
| 58 | bb_perror_nomsg_and_die(); | 56 | bb_perror_nomsg_and_die(); |
| 57 | } | ||
| 58 | #else | ||
| 59 | int hdr_len = strlen(fmt) + strlen(filename); | ||
| 60 | char *hdr = xzalloc(hdr_len); | ||
| 61 | sprintf(hdr, filename, filename); | ||
| 62 | tail_xbb_full_write(hdr, hdr_len); | ||
| 63 | #endif | ||
| 59 | } | 64 | } |
| 60 | 65 | ||
| 61 | static ssize_t tail_read(int fd, char *buf, size_t count) | 66 | static ssize_t tail_read(int fd, char *buf, size_t count) |
diff --git a/coreutils/tee.c b/coreutils/tee.c index 4d0e6ff85..1f59f0361 100644 --- a/coreutils/tee.c +++ b/coreutils/tee.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */ | 11 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */ |
| 12 | 12 | ||
| 13 | #include "busybox.h" | 13 | #include "busybox.h" |
| 14 | #include <signal.h> | ||
| 14 | 15 | ||
| 15 | int tee_main(int argc, char **argv) | 16 | int tee_main(int argc, char **argv) |
| 16 | { | 17 | { |
| @@ -37,7 +38,7 @@ int tee_main(int argc, char **argv) | |||
| 37 | 38 | ||
| 38 | /* gnu tee ignores SIGPIPE in case one of the output files is a pipe | 39 | /* gnu tee ignores SIGPIPE in case one of the output files is a pipe |
| 39 | * that doesn't consume all its input. Good idea... */ | 40 | * that doesn't consume all its input. Good idea... */ |
| 40 | signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/ | 41 | signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/ |
| 41 | 42 | ||
| 42 | /* Allocate an array of FILE *'s, with one extra for a sentinal. */ | 43 | /* Allocate an array of FILE *'s, with one extra for a sentinal. */ |
| 43 | p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2)); | 44 | p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2)); |
diff --git a/coreutils/watch.c b/coreutils/watch.c index c8b16b908..7b9c6698a 100644 --- a/coreutils/watch.c +++ b/coreutils/watch.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * Mini watch implementation for busybox | 3 | * Mini watch implementation for busybox |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de> | 5 | * Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de> |
| 6 | * Copyrigjt (C) Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
| 6 | * | 7 | * |
| 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
| 8 | */ | 9 | */ |
| @@ -10,14 +11,9 @@ | |||
| 10 | /* BB_AUDIT SUSv3 N/A */ | 11 | /* BB_AUDIT SUSv3 N/A */ |
| 11 | /* BB_AUDIT GNU defects -- only option -n is supported. */ | 12 | /* BB_AUDIT GNU defects -- only option -n is supported. */ |
| 12 | 13 | ||
| 13 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
| 14 | * | ||
| 15 | * Removed dependency on date_main(), added proper error checking, and | ||
| 16 | * reduced size. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include "busybox.h" | 14 | #include "busybox.h" |
| 20 | 15 | ||
| 16 | |||
| 21 | int watch_main(int argc, char **argv) | 17 | int watch_main(int argc, char **argv) |
| 22 | { | 18 | { |
| 23 | int width, len; | 19 | int width, len; |
| @@ -26,19 +22,18 @@ int watch_main(int argc, char **argv) | |||
| 26 | 22 | ||
| 27 | if (argc < 2) bb_show_usage(); | 23 | if (argc < 2) bb_show_usage(); |
| 28 | 24 | ||
| 29 | get_terminal_width_height(1, &width, 0); | 25 | get_terminal_width_height(STDOUT_FILENO, &width, 0); |
| 30 | header = xzalloc(width--); | 26 | header = xzalloc(width--); |
| 31 | 27 | ||
| 32 | /* don't use getopt, because it permutes the arguments */ | 28 | /* don't use getopt, because it permutes the arguments */ |
| 33 | ++argv; | 29 | ++argv; |
| 34 | if ((argc > 3) && !strcmp(*argv, "-n")) { | 30 | if ((argc > 3) && argv[0][0] == '-' && argv[0][1] == 'n') { |
| 35 | period = bb_xgetularg10_bnd(argv[1], 1, UINT_MAX); | 31 | period = bb_xgetularg10_bnd(argv[1], 1, UINT_MAX); |
| 36 | argv += 2; | 32 | argv += 2; |
| 37 | } | 33 | } |
| 38 | watched_argv = argv; | 34 | watched_argv = argv; |
| 39 | 35 | ||
| 40 | /* create header */ | 36 | /* create header */ |
| 41 | |||
| 42 | len = snprintf(header, width, "Every %ds:", period); | 37 | len = snprintf(header, width, "Every %ds:", period); |
| 43 | while (*argv && len<width) | 38 | while (*argv && len<width) |
| 44 | snprintf(header+len, width-len, " %s", *(argv++)); | 39 | snprintf(header+len, width-len, " %s", *(argv++)); |
| @@ -50,11 +45,13 @@ int watch_main(int argc, char **argv) | |||
| 50 | time(&t); | 45 | time(&t); |
| 51 | thyme = ctime(&t); | 46 | thyme = ctime(&t); |
| 52 | len = strlen(thyme); | 47 | len = strlen(thyme); |
| 53 | if (len < width) header[width-len] = 0; | 48 | if (len < width) |
| 54 | 49 | header[width-len] = 0; | |
| 55 | printf("\033[H\033[J%s %s\n", header, thyme); | 50 | bb_printf("\033[H\033[J%s %s\n", header, thyme); |
| 56 | 51 | ||
| 57 | waitpid(xspawn(watched_argv),0,0); | 52 | waitpid(xspawn(watched_argv),0,0); |
| 58 | sleep(period); | 53 | sleep(period); |
| 59 | } | 54 | } |
| 55 | if (ENABLE_FEATURE_CLEAN_UP) | ||
| 56 | free(header); | ||
| 60 | } | 57 | } |
diff --git a/include/libbb.h b/include/libbb.h index 3c563a96f..b94586165 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -60,10 +60,6 @@ | |||
| 60 | #define PATH_MAX 256 | 60 | #define PATH_MAX 256 |
| 61 | #endif | 61 | #endif |
| 62 | 62 | ||
| 63 | #ifdef DMALLOC | ||
| 64 | #include <dmalloc.h> | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /* Some useful definitions */ | 63 | /* Some useful definitions */ |
| 68 | #undef FALSE | 64 | #undef FALSE |
| 69 | #define FALSE ((int) 0) | 65 | #define FALSE ((int) 0) |
| @@ -211,7 +207,9 @@ extern int bb_fprintf(FILE * __restrict stream, const char * __restrict format, | |||
| 211 | extern int bb_printf(const char * __restrict format, ...) | 207 | extern int bb_printf(const char * __restrict format, ...) |
| 212 | __attribute__ ((format (printf, 1, 2))); | 208 | __attribute__ ((format (printf, 1, 2))); |
| 213 | 209 | ||
| 214 | //#warning rename to xferror_filename? | 210 | #if ENABLE_NITPICK |
| 211 | #warning rename to xferror_filename? | ||
| 212 | #endif | ||
| 215 | extern void xferror(FILE *fp, const char *fn); | 213 | extern void xferror(FILE *fp, const char *fn); |
| 216 | extern void xferror_stdout(void); | 214 | extern void xferror_stdout(void); |
| 217 | extern void xfflush_stdout(void); | 215 | extern void xfflush_stdout(void); |
| @@ -265,7 +263,9 @@ extern long bb_xgetlarg_bnd_sfx(const char *arg, int base, | |||
| 265 | extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes); | 263 | extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes); |
| 266 | 264 | ||
| 267 | 265 | ||
| 268 | //#warning pitchable now? | 266 | #if ENABLE_NITPICK |
| 267 | #warning pitchable now? | ||
| 268 | #endif | ||
| 269 | extern unsigned long bb_xparse_number(const char *numstr, | 269 | extern unsigned long bb_xparse_number(const char *numstr, |
| 270 | const struct suffix_mult *suffixes); | 270 | const struct suffix_mult *suffixes); |
| 271 | 271 | ||
| @@ -330,7 +330,9 @@ char *concat_path_file(const char *path, const char *filename); | |||
| 330 | char *concat_subpath_file(const char *path, const char *filename); | 330 | char *concat_subpath_file(const char *path, const char *filename); |
| 331 | char *last_char_is(const char *s, int c); | 331 | char *last_char_is(const char *s, int c); |
| 332 | 332 | ||
| 333 | //#warning yuk! | 333 | #if ENABLE_NITPICK |
| 334 | #warning yuk! | ||
| 335 | #endif | ||
| 334 | char *fgets_str(FILE *file, const char *terminating_string); | 336 | char *fgets_str(FILE *file, const char *terminating_string); |
| 335 | 337 | ||
| 336 | extern int uncompress(int fd_in, int fd_out); | 338 | extern int uncompress(int fd_in, int fd_out); |
| @@ -344,7 +346,9 @@ extern int xconnect(struct sockaddr_in *s_addr); | |||
| 344 | extern unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port); | 346 | extern unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port); |
| 345 | extern void bb_lookup_host(struct sockaddr_in *s_in, const char *host); | 347 | extern void bb_lookup_host(struct sockaddr_in *s_in, const char *host); |
| 346 | 348 | ||
| 347 | //#warning wrap this? | 349 | #if ENABLE_NITPICK |
| 350 | #warning wrap this? | ||
| 351 | #endif | ||
| 348 | char *dirname (char *path); | 352 | char *dirname (char *path); |
| 349 | 353 | ||
| 350 | int bb_make_directory (char *path, long mode, int flags); | 354 | int bb_make_directory (char *path, long mode, int flags); |
| @@ -456,8 +460,10 @@ extern int bb_default_error_retval; | |||
| 456 | # define FB_0 "/dev/fb0" | 460 | # define FB_0 "/dev/fb0" |
| 457 | #endif | 461 | #endif |
| 458 | 462 | ||
| 459 | //#warning put these in .o files | ||
| 460 | 463 | ||
| 464 | #if ENABLE_NITPICK | ||
| 465 | #warning put these in .o files | ||
| 466 | #endif | ||
| 461 | /* The following devices are the same on devfs and non-devfs systems. */ | 467 | /* The following devices are the same on devfs and non-devfs systems. */ |
| 462 | #define CURRENT_TTY "/dev/tty" | 468 | #define CURRENT_TTY "/dev/tty" |
| 463 | #define CONSOLE_DEV "/dev/console" | 469 | #define CONSOLE_DEV "/dev/console" |
| @@ -581,4 +587,8 @@ extern const char BB_BANNER[]; | |||
| 581 | #undef isupper | 587 | #undef isupper |
| 582 | #undef isxdigit | 588 | #undef isxdigit |
| 583 | 589 | ||
| 590 | #ifdef DMALLOC | ||
| 591 | #include <dmalloc.h> | ||
| 592 | #endif | ||
| 593 | |||
| 584 | #endif /* __LIBBUSYBOX_H__ */ | 594 | #endif /* __LIBBUSYBOX_H__ */ |
diff --git a/include/unarchive.h b/include/unarchive.h index 05ab0c16a..1dbbc009d 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
| @@ -10,8 +10,6 @@ | |||
| 10 | #define ARCHIVE_NOPRESERVE_OWN 32 | 10 | #define ARCHIVE_NOPRESERVE_OWN 32 |
| 11 | #define ARCHIVE_NOPRESERVE_PERM 64 | 11 | #define ARCHIVE_NOPRESERVE_PERM 64 |
| 12 | 12 | ||
| 13 | #include <sys/types.h> | ||
| 14 | #include <stdio.h> | ||
| 15 | #include "libbb.h" | 13 | #include "libbb.h" |
| 16 | 14 | ||
| 17 | typedef struct file_headers_s { | 15 | typedef struct file_headers_s { |
diff --git a/include/usage.h b/include/usage.h index ced9f68c7..0f95708c5 100644 --- a/include/usage.h +++ b/include/usage.h | |||
| @@ -1426,12 +1426,12 @@ USE_FEATURE_DATE_ISOFMT( \ | |||
| 1426 | #define ipcrm_trivial_usage \ | 1426 | #define ipcrm_trivial_usage \ |
| 1427 | "[-[MQS] key] [-[mqs] id]" | 1427 | "[-[MQS] key] [-[mqs] id]" |
| 1428 | #define ipcrm_full_usage \ | 1428 | #define ipcrm_full_usage \ |
| 1429 | "The upper-case options MQS are used to remove a shared memory\n" \ | 1429 | "The upper-case options MQS are used to remove a shared memory segment by a\n" \ |
| 1430 | "segment by an shmkey value. The lower-case options mqs are used\n" \ | 1430 | "segment by a shmkey value. The lower-case options mqs are used\n" \ |
| 1431 | "to remove a segment by shmid value.\n" \ | 1431 | "to remove a segment by shmid value.\n" \ |
| 1432 | "\t-m | -M\tRemove the memory segment after the last detach\n" \ | 1432 | "\t-[mM]\tRemove the memory segment after the last detach\n" \ |
| 1433 | "\t-q | -Q\tRemove the message queue\n" \ | 1433 | "\t-[qQ]\tRemove the message queue\n" \ |
| 1434 | "\t-s | -S\tRemove the semaphore" | 1434 | "\t-[sS]\tRemove the semaphore" |
| 1435 | 1435 | ||
| 1436 | #define ipcs_trivial_usage \ | 1436 | #define ipcs_trivial_usage \ |
| 1437 | "[[-smq] -i shmid] | [[-asmq] [-tclup]]" | 1437 | "[[-smq] -i shmid] | [[-asmq] [-tclup]]" |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 4d81fdc28..b2b53a712 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
| @@ -16,8 +16,12 @@ | |||
| 16 | * succeeded. */ | 16 | * succeeded. */ |
| 17 | 17 | ||
| 18 | #ifndef DMALLOC | 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 | */ | ||
| 19 | #ifdef L_xmalloc | 23 | #ifdef L_xmalloc |
| 20 | // Die if we can't allocate size bytes of memory. | 24 | /* Die if we can't allocate size bytes of memory. */ |
| 21 | void *xmalloc(size_t size) | 25 | void *xmalloc(size_t size) |
| 22 | { | 26 | { |
| 23 | void *ptr = malloc(size); | 27 | void *ptr = malloc(size); |
| @@ -28,9 +32,9 @@ void *xmalloc(size_t size) | |||
| 28 | #endif | 32 | #endif |
| 29 | 33 | ||
| 30 | #ifdef L_xrealloc | 34 | #ifdef L_xrealloc |
| 31 | // Die if we can't resize previously allocated memory. (This returns a pointer | 35 | /* Die if we can't resize previously allocated memory. (This returns a pointer |
| 32 | // to the new memory, which may or may not be the same as the old memory. | 36 | * to the new memory, which may or may not be the same as the old memory. |
| 33 | // It'll copy the contents to a new chunk and free the old one if necessary.) | 37 | * It'll copy the contents to a new chunk and free the old one if necessary.) */ |
| 34 | void *xrealloc(void *ptr, size_t size) | 38 | void *xrealloc(void *ptr, size_t size) |
| 35 | { | 39 | { |
| 36 | ptr = realloc(ptr, size); | 40 | ptr = realloc(ptr, size); |
| @@ -39,9 +43,11 @@ void *xrealloc(void *ptr, size_t size) | |||
| 39 | return ptr; | 43 | return ptr; |
| 40 | } | 44 | } |
| 41 | #endif | 45 | #endif |
| 46 | #endif /* DMALLOC */ | ||
| 47 | |||
| 42 | 48 | ||
| 43 | #ifdef L_xzalloc | 49 | #ifdef L_xzalloc |
| 44 | // Die if we can't allocate and zero size bytes of memory. | 50 | /* Die if we can't allocate and zero size bytes of memory. */ |
| 45 | void *xzalloc(size_t size) | 51 | void *xzalloc(size_t size) |
| 46 | { | 52 | { |
| 47 | void *ptr = xmalloc(size); | 53 | void *ptr = xmalloc(size); |
| @@ -50,10 +56,8 @@ void *xzalloc(size_t size) | |||
| 50 | } | 56 | } |
| 51 | #endif | 57 | #endif |
| 52 | 58 | ||
| 53 | #endif /* DMALLOC */ | ||
| 54 | |||
| 55 | #ifdef L_xstrdup | 59 | #ifdef L_xstrdup |
| 56 | // Die if we can't copy a string to freshly allocated memory. | 60 | /* Die if we can't copy a string to freshly allocated memory. */ |
| 57 | char * xstrdup(const char *s) | 61 | char * xstrdup(const char *s) |
| 58 | { | 62 | { |
| 59 | char *t; | 63 | char *t; |
| @@ -71,8 +75,9 @@ char * xstrdup(const char *s) | |||
| 71 | #endif | 75 | #endif |
| 72 | 76 | ||
| 73 | #ifdef L_xstrndup | 77 | #ifdef L_xstrndup |
| 74 | // Die if we can't allocate n+1 bytes (space for the null terminator) and copy | 78 | /* Die if we can't allocate n+1 bytes (space for the null terminator) and copy |
| 75 | // the (possibly truncated to length n) string into it. | 79 | * the (possibly truncated to length n) string into it. |
| 80 | */ | ||
| 76 | char * xstrndup(const char *s, int n) | 81 | char * xstrndup(const char *s, int n) |
| 77 | { | 82 | { |
| 78 | char *t; | 83 | char *t; |
| @@ -87,8 +92,9 @@ char * xstrndup(const char *s, int n) | |||
| 87 | #endif | 92 | #endif |
| 88 | 93 | ||
| 89 | #ifdef L_xfopen | 94 | #ifdef L_xfopen |
| 90 | // Die if we can't open a file and return a FILE * to it. | 95 | /* Die if we can't open a file and return a FILE * to it. |
| 91 | // Notice we haven't got xfread(), This is for use with fscanf() and friends. | 96 | * Notice we haven't got xfread(), This is for use with fscanf() and friends. |
| 97 | */ | ||
| 92 | FILE *xfopen(const char *path, const char *mode) | 98 | FILE *xfopen(const char *path, const char *mode) |
| 93 | { | 99 | { |
| 94 | FILE *fp; | 100 | FILE *fp; |
| @@ -99,7 +105,7 @@ FILE *xfopen(const char *path, const char *mode) | |||
| 99 | #endif | 105 | #endif |
| 100 | 106 | ||
| 101 | #ifdef L_xopen | 107 | #ifdef L_xopen |
| 102 | // Die if we can't open an existing file and return an fd. | 108 | /* Die if we can't open an existing file and return an fd. */ |
| 103 | int xopen(const char *pathname, int flags) | 109 | int xopen(const char *pathname, int flags) |
| 104 | { | 110 | { |
| 105 | if (ENABLE_DEBUG && (flags && O_CREAT)) | 111 | if (ENABLE_DEBUG && (flags && O_CREAT)) |
| @@ -110,7 +116,7 @@ int xopen(const char *pathname, int flags) | |||
| 110 | #endif | 116 | #endif |
| 111 | 117 | ||
| 112 | #ifdef L_xopen3 | 118 | #ifdef L_xopen3 |
| 113 | // Die if we can't open a new file and return an fd. | 119 | /* Die if we can't open a new file and return an fd. */ |
| 114 | int xopen3(const char *pathname, int flags, int mode) | 120 | int xopen3(const char *pathname, int flags, int mode) |
| 115 | { | 121 | { |
| 116 | int ret; | 122 | int ret; |
| @@ -124,7 +130,7 @@ int xopen3(const char *pathname, int flags, int mode) | |||
| 124 | #endif | 130 | #endif |
| 125 | 131 | ||
| 126 | #ifdef L_xread | 132 | #ifdef L_xread |
| 127 | // Die with an error message if we can't read the entire buffer. | 133 | /* Die with an error message if we can't read the entire buffer. */ |
| 128 | void xread(int fd, void *buf, size_t count) | 134 | void xread(int fd, void *buf, size_t count) |
| 129 | { | 135 | { |
| 130 | while (count) { | 136 | while (count) { |
| @@ -139,7 +145,7 @@ void xread(int fd, void *buf, size_t count) | |||
| 139 | #endif | 145 | #endif |
| 140 | 146 | ||
| 141 | #ifdef L_xwrite | 147 | #ifdef L_xwrite |
| 142 | // Die with an error message if we can't write the entire buffer. | 148 | /* Die with an error message if we can't write the entire buffer. */ |
| 143 | void xwrite(int fd, void *buf, size_t count) | 149 | void xwrite(int fd, void *buf, size_t count) |
| 144 | { | 150 | { |
| 145 | while (count) { | 151 | while (count) { |
| @@ -154,7 +160,7 @@ void xwrite(int fd, void *buf, size_t count) | |||
| 154 | #endif | 160 | #endif |
| 155 | 161 | ||
| 156 | #ifdef L_xlseek | 162 | #ifdef L_xlseek |
| 157 | // Die with an error message if we can't lseek to the right spot. | 163 | /* Die with an error message if we can't lseek to the right spot. */ |
| 158 | void xlseek(int fd, off_t offset, int whence) | 164 | void xlseek(int fd, off_t offset, int whence) |
| 159 | { | 165 | { |
| 160 | if (offset != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek"); | 166 | if (offset != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek"); |
| @@ -162,7 +168,7 @@ void xlseek(int fd, off_t offset, int whence) | |||
| 162 | #endif | 168 | #endif |
| 163 | 169 | ||
| 164 | #ifdef L_xread_char | 170 | #ifdef L_xread_char |
| 165 | // Die with an error message if we can't read one character. | 171 | /* Die with an error message if we can't read one character. */ |
| 166 | unsigned char xread_char(int fd) | 172 | unsigned char xread_char(int fd) |
| 167 | { | 173 | { |
| 168 | char tmp; | 174 | char tmp; |
| @@ -174,7 +180,7 @@ unsigned char xread_char(int fd) | |||
| 174 | #endif | 180 | #endif |
| 175 | 181 | ||
| 176 | #ifdef L_xferror | 182 | #ifdef L_xferror |
| 177 | // Die with supplied error message if this FILE * has ferror set. | 183 | /* Die with supplied error message if this FILE * has ferror set. */ |
| 178 | void xferror(FILE *fp, const char *fn) | 184 | void xferror(FILE *fp, const char *fn) |
| 179 | { | 185 | { |
| 180 | if (ferror(fp)) { | 186 | if (ferror(fp)) { |
| @@ -184,7 +190,7 @@ void xferror(FILE *fp, const char *fn) | |||
| 184 | #endif | 190 | #endif |
| 185 | 191 | ||
| 186 | #ifdef L_xferror_stdout | 192 | #ifdef L_xferror_stdout |
| 187 | // Die with an error message if stdout has ferror set. | 193 | /* Die with an error message if stdout has ferror set. */ |
| 188 | void xferror_stdout(void) | 194 | void xferror_stdout(void) |
| 189 | { | 195 | { |
| 190 | xferror(stdout, bb_msg_standard_output); | 196 | xferror(stdout, bb_msg_standard_output); |
| @@ -192,7 +198,7 @@ void xferror_stdout(void) | |||
| 192 | #endif | 198 | #endif |
| 193 | 199 | ||
| 194 | #ifdef L_xfflush_stdout | 200 | #ifdef L_xfflush_stdout |
| 195 | // Die with an error message if we have trouble flushing stdout. | 201 | /* Die with an error message if we have trouble flushing stdout. */ |
| 196 | void xfflush_stdout(void) | 202 | void xfflush_stdout(void) |
| 197 | { | 203 | { |
| 198 | if (fflush(stdout)) { | 204 | if (fflush(stdout)) { |
| @@ -202,24 +208,25 @@ void xfflush_stdout(void) | |||
| 202 | #endif | 208 | #endif |
| 203 | 209 | ||
| 204 | #ifdef L_spawn | 210 | #ifdef L_spawn |
| 205 | // This does a fork/exec in one call, using vfork(). Return PID of new child, | 211 | /* This does a fork/exec in one call, using vfork(). Return PID of new child, |
| 206 | // -1 for failure. Runs argv[0], searching path if that has no / in it. | 212 | * -1 for failure. Runs argv[0], searching path if that has no / in it. |
| 213 | */ | ||
| 207 | pid_t spawn(char **argv) | 214 | pid_t spawn(char **argv) |
| 208 | { | 215 | { |
| 209 | static int failed; | 216 | static int failed; |
| 210 | pid_t pid; | 217 | pid_t pid; |
| 211 | void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0; | 218 | void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0; |
| 212 | 219 | ||
| 213 | // Be nice to nommu machines. | 220 | /* Be nice to nommu machines. */ |
| 214 | failed = 0; | 221 | failed = 0; |
| 215 | pid = vfork(); | 222 | pid = vfork(); |
| 216 | if (pid < 0) return pid; | 223 | if (pid < 0) return pid; |
| 217 | if (!pid) { | 224 | if (!pid) { |
| 218 | execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv); | 225 | execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv); |
| 219 | 226 | ||
| 220 | // We're sharing a stack with blocked parent, let parent know we failed | 227 | /* We're sharing a stack with blocked parent, let parent know we failed |
| 221 | // and then exit to unblock parent (but don't run atexit() stuff, which | 228 | * and then exit to unblock parent (but don't run atexit() stuff, which |
| 222 | // would screw up parent.) | 229 | would screw up parent.) */ |
| 223 | 230 | ||
| 224 | failed = -1; | 231 | failed = -1; |
| 225 | _exit(0); | 232 | _exit(0); |
| @@ -229,7 +236,7 @@ pid_t spawn(char **argv) | |||
| 229 | #endif | 236 | #endif |
| 230 | 237 | ||
| 231 | #ifdef L_xspawn | 238 | #ifdef L_xspawn |
| 232 | // Die with an error message if we can't spawn a child process. | 239 | /* Die with an error message if we can't spawn a child process. */ |
| 233 | pid_t xspawn(char **argv) | 240 | pid_t xspawn(char **argv) |
| 234 | { | 241 | { |
| 235 | pid_t pid = spawn(argv); | 242 | pid_t pid = spawn(argv); |
| @@ -239,7 +246,7 @@ pid_t xspawn(char **argv) | |||
| 239 | #endif | 246 | #endif |
| 240 | 247 | ||
| 241 | #ifdef L_wait4 | 248 | #ifdef L_wait4 |
| 242 | // Wait for the specified child PID to exit, returning child's error return. | 249 | /* Wait for the specified child PID to exit, returning child's error return. */ |
| 243 | int wait4pid(int pid) | 250 | int wait4pid(int pid) |
| 244 | { | 251 | { |
| 245 | int status; | 252 | int status; |
| @@ -252,9 +259,9 @@ int wait4pid(int pid) | |||
| 252 | #endif | 259 | #endif |
| 253 | 260 | ||
| 254 | #ifdef L_itoa | 261 | #ifdef L_itoa |
| 255 | // Convert unsigned integer to ascii, writing into supplied buffer. A | 262 | /* Convert unsigned integer to ascii, writing into supplied buffer. A |
| 256 | // truncated result is always null terminated (unless buflen is 0), and | 263 | * truncated result is always null terminated (unless buflen is 0), and |
| 257 | // contains the first few digits of the result ala strncpy. | 264 | * contains the first few digits of the result ala strncpy. */ |
| 258 | void utoa_to_buf(unsigned n, char *buf, unsigned buflen) | 265 | void utoa_to_buf(unsigned n, char *buf, unsigned buflen) |
| 259 | { | 266 | { |
| 260 | int i, out = 0; | 267 | int i, out = 0; |
| @@ -272,7 +279,7 @@ void utoa_to_buf(unsigned n, char *buf, unsigned buflen) | |||
| 272 | } | 279 | } |
| 273 | } | 280 | } |
| 274 | 281 | ||
| 275 | // Convert signed integer to ascii, like utoa_to_buf() | 282 | /* Convert signed integer to ascii, like utoa_to_buf() */ |
| 276 | void itoa_to_buf(int n, char *buf, unsigned buflen) | 283 | void itoa_to_buf(int n, char *buf, unsigned buflen) |
| 277 | { | 284 | { |
| 278 | if (buflen && n<0) { | 285 | if (buflen && n<0) { |
| @@ -283,16 +290,16 @@ void itoa_to_buf(int n, char *buf, unsigned buflen) | |||
| 283 | utoa_to_buf((unsigned)n, buf, buflen); | 290 | utoa_to_buf((unsigned)n, buf, buflen); |
| 284 | } | 291 | } |
| 285 | 292 | ||
| 286 | // The following two functions use a static buffer, so calling either one a | 293 | /* The following two functions use a static buffer, so calling either one a |
| 287 | // second time will overwrite previous results. | 294 | * second time will overwrite previous results. |
| 288 | // | 295 | * |
| 289 | // The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes. | 296 | * The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes. |
| 290 | // Int should always be 32 bits on any remotely Unix-like system, see | 297 | * Int should always be 32 bits on any remotely Unix-like system, see |
| 291 | // http://www.unix.org/whitepapers/64bit.html for the reasons why. | 298 | * http://www.unix.org/whitepapers/64bit.html for the reasons why. |
| 292 | 299 | */ | |
| 293 | static char local_buf[12]; | 300 | static char local_buf[12]; |
| 294 | 301 | ||
| 295 | // Convert unsigned integer to ascii using a static buffer (returned). | 302 | /* Convert unsigned integer to ascii using a static buffer (returned). */ |
| 296 | char *utoa(unsigned n) | 303 | char *utoa(unsigned n) |
| 297 | { | 304 | { |
| 298 | utoa_to_buf(n, local_buf, sizeof(local_buf)); | 305 | utoa_to_buf(n, local_buf, sizeof(local_buf)); |
| @@ -300,7 +307,7 @@ char *utoa(unsigned n) | |||
| 300 | return local_buf; | 307 | return local_buf; |
| 301 | } | 308 | } |
| 302 | 309 | ||
| 303 | // Convert signed integer to ascii using a static buffer (returned). | 310 | /* Convert signed integer to ascii using a static buffer (returned). */ |
| 304 | char *itoa(int n) | 311 | char *itoa(int n) |
| 305 | { | 312 | { |
| 306 | itoa_to_buf(n, local_buf, sizeof(local_buf)); | 313 | itoa_to_buf(n, local_buf, sizeof(local_buf)); |
| @@ -310,15 +317,15 @@ char *itoa(int n) | |||
| 310 | #endif | 317 | #endif |
| 311 | 318 | ||
| 312 | #ifdef L_setuid | 319 | #ifdef L_setuid |
| 313 | // Die with an error message if we can't set gid. (Because resource limits may | 320 | /* Die with an error message if we can't set gid. (Because resource limits may |
| 314 | // limit this user to a given number of processes, and if that fills up the | 321 | * limit this user to a given number of processes, and if that fills up the |
| 315 | // setgid() will fail and we'll _still_be_root_, which is bad.) | 322 | * setgid() will fail and we'll _still_be_root_, which is bad.) */ |
| 316 | void xsetgid(gid_t gid) | 323 | void xsetgid(gid_t gid) |
| 317 | { | 324 | { |
| 318 | if (setgid(gid)) bb_error_msg_and_die("setgid"); | 325 | if (setgid(gid)) bb_error_msg_and_die("setgid"); |
| 319 | } | 326 | } |
| 320 | 327 | ||
| 321 | // Die with an error message if we cant' set uid. (See xsetgid() for why.) | 328 | /* Die with an error message if we cant' set uid. (See xsetgid() for why.) */ |
| 322 | void xsetuid(uid_t uid) | 329 | void xsetuid(uid_t uid) |
| 323 | { | 330 | { |
| 324 | if (setuid(uid)) bb_error_msg_and_die("setuid"); | 331 | if (setuid(uid)) bb_error_msg_and_die("setuid"); |
| @@ -326,31 +333,31 @@ void xsetuid(uid_t uid) | |||
| 326 | #endif | 333 | #endif |
| 327 | 334 | ||
| 328 | #ifdef L_fdlength | 335 | #ifdef L_fdlength |
| 329 | // Return how long the file at fd is, if there's any way to determine it. | 336 | /* Return how long the file at fd is, if there's any way to determine it. */ |
| 330 | off_t fdlength(int fd) | 337 | off_t fdlength(int fd) |
| 331 | { | 338 | { |
| 332 | off_t bottom = 0, top = 0, pos; | 339 | off_t bottom = 0, top = 0, pos; |
| 333 | long size; | 340 | long size; |
| 334 | 341 | ||
| 335 | // If the ioctl works for this, return it. | 342 | /* If the ioctl works for this, return it. */ |
| 336 | 343 | ||
| 337 | if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512; | 344 | if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512; |
| 338 | 345 | ||
| 339 | // If not, do a binary search for the last location we can read. (Some | 346 | /* If not, do a binary search for the last location we can read. (Some |
| 340 | // block devices don't do BLKGETSIZE right.) | 347 | * block devices don't do BLKGETSIZE right.) */ |
| 341 | 348 | ||
| 342 | do { | 349 | do { |
| 343 | char temp; | 350 | char temp; |
| 344 | 351 | ||
| 345 | pos = bottom + (top - bottom) / 2;; | 352 | pos = bottom + (top - bottom) / 2;; |
| 346 | 353 | ||
| 347 | // If we can read from the current location, it's bigger. | 354 | /* If we can read from the current location, it's bigger. */ |
| 348 | 355 | ||
| 349 | if (lseek(fd, pos, 0)>=0 && safe_read(fd, &temp, 1)==1) { | 356 | if (lseek(fd, pos, 0)>=0 && safe_read(fd, &temp, 1)==1) { |
| 350 | if (bottom == top) bottom = top = (top+1) * 2; | 357 | if (bottom == top) bottom = top = (top+1) * 2; |
| 351 | else bottom = pos; | 358 | else bottom = pos; |
| 352 | 359 | ||
| 353 | // If we can't, it's smaller. | 360 | /* If we can't, it's smaller. */ |
| 354 | 361 | ||
| 355 | } else { | 362 | } else { |
| 356 | if (bottom == top) { | 363 | if (bottom == top) { |
| @@ -366,8 +373,8 @@ off_t fdlength(int fd) | |||
| 366 | #endif | 373 | #endif |
| 367 | 374 | ||
| 368 | #ifdef L_xasprintf | 375 | #ifdef L_xasprintf |
| 369 | // Die with an error message if we can't malloc() enough space and do an | 376 | /* Die with an error message if we can't malloc() enough space and do an |
| 370 | // sprintf() into that space. | 377 | * sprintf() into that space. */ |
| 371 | char *xasprintf(const char *format, ...) | 378 | char *xasprintf(const char *format, ...) |
| 372 | { | 379 | { |
| 373 | va_list p; | 380 | va_list p; |
| @@ -396,8 +403,8 @@ char *xasprintf(const char *format, ...) | |||
| 396 | #endif | 403 | #endif |
| 397 | 404 | ||
| 398 | #ifdef L_xprint_and_close_file | 405 | #ifdef L_xprint_and_close_file |
| 399 | // Die with an error message if we can't copy an entire FILE * to stdout, then | 406 | /* Die with an error message if we can't copy an entire FILE * to stdout, then |
| 400 | // close that file. | 407 | * close that file. */ |
| 401 | void xprint_and_close_file(FILE *file) | 408 | void xprint_and_close_file(FILE *file) |
| 402 | { | 409 | { |
| 403 | // copyfd outputs error messages for us. | 410 | // copyfd outputs error messages for us. |
| @@ -408,7 +415,7 @@ void xprint_and_close_file(FILE *file) | |||
| 408 | #endif | 415 | #endif |
| 409 | 416 | ||
| 410 | #ifdef L_xchdir | 417 | #ifdef L_xchdir |
| 411 | // Die if we can't chdir to a new path. | 418 | /* Die if we can't chdir to a new path. */ |
| 412 | void xchdir(const char *path) | 419 | void xchdir(const char *path) |
| 413 | { | 420 | { |
| 414 | if (chdir(path)) | 421 | if (chdir(path)) |
| @@ -417,7 +424,7 @@ void xchdir(const char *path) | |||
| 417 | #endif | 424 | #endif |
| 418 | 425 | ||
| 419 | #ifdef L_warn_opendir | 426 | #ifdef L_warn_opendir |
| 420 | // Print a warning message if opendir() fails, but don't die. | 427 | /* Print a warning message if opendir() fails, but don't die. */ |
| 421 | DIR *warn_opendir(const char *path) | 428 | DIR *warn_opendir(const char *path) |
| 422 | { | 429 | { |
| 423 | DIR *dp; | 430 | DIR *dp; |
| @@ -431,7 +438,7 @@ DIR *warn_opendir(const char *path) | |||
| 431 | #endif | 438 | #endif |
| 432 | 439 | ||
| 433 | #ifdef L_xopendir | 440 | #ifdef L_xopendir |
| 434 | // Die with an error message if opendir() fails. | 441 | /* Die with an error message if opendir() fails. */ |
| 435 | DIR *xopendir(const char *path) | 442 | DIR *xopendir(const char *path) |
| 436 | { | 443 | { |
| 437 | DIR *dp; | 444 | DIR *dp; |
| @@ -444,7 +451,7 @@ DIR *xopendir(const char *path) | |||
| 444 | 451 | ||
| 445 | #ifdef L_xdaemon | 452 | #ifdef L_xdaemon |
| 446 | #ifndef BB_NOMMU | 453 | #ifndef BB_NOMMU |
| 447 | // Die with an error message if we can't daemonize. | 454 | /* Die with an error message if we can't daemonize. */ |
| 448 | void xdaemon(int nochdir, int noclose) | 455 | void xdaemon(int nochdir, int noclose) |
| 449 | { | 456 | { |
| 450 | if (daemon(nochdir, noclose)) bb_perror_msg_and_die("daemon"); | 457 | if (daemon(nochdir, noclose)) bb_perror_msg_and_die("daemon"); |
| @@ -453,7 +460,7 @@ void xdaemon(int nochdir, int noclose) | |||
| 453 | #endif | 460 | #endif |
| 454 | 461 | ||
| 455 | #ifdef L_xsocket | 462 | #ifdef L_xsocket |
| 456 | // Die with an error message if we can't open a new socket. | 463 | /* Die with an error message if we can't open a new socket. */ |
| 457 | int xsocket(int domain, int type, int protocol) | 464 | int xsocket(int domain, int type, int protocol) |
| 458 | { | 465 | { |
| 459 | int r = socket(domain, type, protocol); | 466 | int r = socket(domain, type, protocol); |
| @@ -465,7 +472,7 @@ int xsocket(int domain, int type, int protocol) | |||
| 465 | #endif | 472 | #endif |
| 466 | 473 | ||
| 467 | #ifdef L_xbind | 474 | #ifdef L_xbind |
| 468 | // Die with an error message if we can't bind a socket to an address. | 475 | /* Die with an error message if we can't bind a socket to an address. */ |
| 469 | void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) | 476 | void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) |
| 470 | { | 477 | { |
| 471 | if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind"); | 478 | if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind"); |
| @@ -473,7 +480,7 @@ void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) | |||
| 473 | #endif | 480 | #endif |
| 474 | 481 | ||
| 475 | #ifdef L_xlisten | 482 | #ifdef L_xlisten |
| 476 | // Die with an error message if we can't listen for connections on a socket. | 483 | /* Die with an error message if we can't listen for connections on a socket. */ |
| 477 | void xlisten(int s, int backlog) | 484 | void xlisten(int s, int backlog) |
| 478 | { | 485 | { |
| 479 | if (listen(s, backlog)) bb_perror_msg_and_die("listen"); | 486 | if (listen(s, backlog)) bb_perror_msg_and_die("listen"); |
diff --git a/testsuite/all_sourcecode.tests b/testsuite/all_sourcecode.tests index 42360eb31..c115878fe 100755 --- a/testsuite/all_sourcecode.tests +++ b/testsuite/all_sourcecode.tests | |||
| @@ -49,6 +49,7 @@ find $srcdir/../ \ | |||
| 49 | -e '\<algorithic\>' \ | 49 | -e '\<algorithic\>' \ |
| 50 | -e '\<deamon\>' \ | 50 | -e '\<deamon\>' \ |
| 51 | -e '\<derefernce\>' \ | 51 | -e '\<derefernce\>' \ |
| 52 | -e '\<acomadate\>' \ | ||
| 52 | | sed -e "s:^$srcdir/\.\./::g" > src.typos | 53 | | sed -e "s:^$srcdir/\.\./::g" > src.typos |
| 53 | testing "Common typos" "cat src.typos" "" "" "" | 54 | testing "Common typos" "cat src.typos" "" "" "" |
| 54 | rm -f src.typos | 55 | rm -f src.typos |
diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c index 2e164b8b3..735a8955b 100644 --- a/util-linux/ipcrm.c +++ b/util-linux/ipcrm.c | |||
| @@ -1,56 +1,22 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
| 2 | /* | 2 | /* |
| 3 | * ipcrm.c -- utility to allow removal of IPC objects and data structures. | 3 | * ipcrm.c - utility to allow removal of IPC objects and data structures. |
| 4 | * | 4 | * |
| 5 | * 01 Sept 2004 - Rodney Radford <rradford@mindspring.com> | 5 | * 01 Sept 2004 - Rodney Radford <rradford@mindspring.com> |
| 6 | * Adapted for busybox from util-linux-2.12a. | 6 | * Adapted for busybox from util-linux-2.12a. |
| 7 | * | 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify | 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | * General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | * | ||
| 22 | * --- Pre-busybox history from util-linux-2.12a ------------------------ | ||
| 23 | * | ||
| 24 | * 1999-04-02 frank zago | ||
| 25 | * - can now remove several id's in the same call | ||
| 26 | * | ||
| 27 | * 1999-02-22 Arkadiusz Miÿkiewicz <misiek@pld.ORG.PL> | ||
| 28 | * - added Native Language Support | ||
| 29 | * | ||
| 30 | * Original author - krishna balasubramanian 1993 | ||
| 31 | */ | 9 | */ |
| 32 | 10 | ||
| 33 | #include <stdio.h> | 11 | #include "busybox.h" |
| 34 | #include <stdlib.h> | ||
| 35 | #include <string.h> | ||
| 36 | #include <errno.h> | ||
| 37 | 12 | ||
| 38 | #include <sys/types.h> | 13 | /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */ |
| 14 | /* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */ | ||
| 39 | #include <sys/ipc.h> | 15 | #include <sys/ipc.h> |
| 40 | #include <sys/shm.h> | 16 | #include <sys/shm.h> |
| 41 | #include <sys/msg.h> | 17 | #include <sys/msg.h> |
| 42 | #include <sys/sem.h> | 18 | #include <sys/sem.h> |
| 43 | 19 | ||
| 44 | /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */ | ||
| 45 | /* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */ | ||
| 46 | /* for getopt */ | ||
| 47 | #include <unistd.h> | ||
| 48 | |||
| 49 | /* for tolower and isupper */ | ||
| 50 | #include <ctype.h> | ||
| 51 | |||
| 52 | #include "busybox.h" | ||
| 53 | |||
| 54 | #if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) | 20 | #if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) |
| 55 | /* union semun is defined by including <sys/sem.h> */ | 21 | /* union semun is defined by including <sys/sem.h> */ |
| 56 | #else | 22 | #else |
| @@ -63,164 +29,149 @@ union semun { | |||
| 63 | }; | 29 | }; |
| 64 | #endif | 30 | #endif |
| 65 | 31 | ||
| 32 | #ifndef CONFIG_IPCRM_DROP_LEGACY | ||
| 33 | |||
| 66 | typedef enum type_id { | 34 | typedef enum type_id { |
| 67 | SHM, | 35 | SHM, |
| 68 | SEM, | 36 | SEM, |
| 69 | MSG | 37 | MSG |
| 70 | } type_id; | 38 | } type_id; |
| 71 | 39 | ||
| 72 | static int | 40 | static int remove_ids(type_id type, int argc, char **argv) |
| 73 | remove_ids(type_id type, int argc, char **argv) { | 41 | { |
| 74 | int id; | 42 | int id; |
| 75 | int ret = 0; /* for gcc */ | 43 | int ret = 0; /* silence gcc */ |
| 76 | char *end; | 44 | char *end; |
| 77 | int nb_errors = 0; | 45 | int nb_errors = 0; |
| 78 | union semun arg; | 46 | union semun arg; |
| 79 | 47 | ||
| 80 | arg.val = 0; | 48 | arg.val = 0; |
| 81 | 49 | ||
| 82 | while(argc) { | 50 | while (argc) { |
| 83 | 51 | ||
| 84 | id = strtoul(argv[0], &end, 10); | 52 | id = strtoul(argv[0], &end, 10); |
| 85 | 53 | ||
| 86 | if (*end != 0) { | 54 | if (*end != 0) { |
| 87 | bb_printf ("invalid id: %s\n", argv[0]); | 55 | bb_error_msg("invalid id: %s", argv[0]); |
| 88 | nb_errors ++; | 56 | nb_errors++; |
| 89 | } else { | 57 | } else { |
| 90 | switch(type) { | 58 | if (type == SEM) |
| 91 | case SEM: | 59 | ret = semctl(id, 0, IPC_RMID, arg); |
| 92 | ret = semctl (id, 0, IPC_RMID, arg); | 60 | else if (type == MSG) |
| 93 | break; | 61 | ret = msgctl(id, IPC_RMID, NULL); |
| 94 | 62 | else if (type == SHM) | |
| 95 | case MSG: | 63 | ret = shmctl(id, IPC_RMID, NULL); |
| 96 | ret = msgctl (id, IPC_RMID, NULL); | ||
| 97 | break; | ||
| 98 | |||
| 99 | case SHM: | ||
| 100 | ret = shmctl (id, IPC_RMID, NULL); | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | 64 | ||
| 104 | if (ret) { | 65 | if (ret) { |
| 105 | bb_printf ("cannot remove id %s (%s)\n", | 66 | bb_perror_msg("cannot remove id %s", argv[0]); |
| 106 | argv[0], strerror(errno)); | 67 | nb_errors++; |
| 107 | nb_errors ++; | ||
| 108 | } | 68 | } |
| 109 | } | 69 | } |
| 110 | argc--; | 70 | argc--; |
| 111 | argv++; | 71 | argv++; |
| 112 | } | 72 | } |
| 113 | 73 | ||
| 114 | return(nb_errors); | 74 | return (nb_errors); |
| 115 | } | ||
| 116 | |||
| 117 | static int deprecated_main(int argc, char **argv) | ||
| 118 | { | ||
| 119 | if (argc < 3) { | ||
| 120 | bb_show_usage(); | ||
| 121 | bb_fflush_stdout_and_exit(1); | ||
| 122 | } | ||
| 123 | |||
| 124 | if (!strcmp(argv[1], "shm")) { | ||
| 125 | if (remove_ids(SHM, argc-2, &argv[2])) | ||
| 126 | bb_fflush_stdout_and_exit(1); | ||
| 127 | } | ||
| 128 | else if (!strcmp(argv[1], "msg")) { | ||
| 129 | if (remove_ids(MSG, argc-2, &argv[2])) | ||
| 130 | bb_fflush_stdout_and_exit(1); | ||
| 131 | } | ||
| 132 | else if (!strcmp(argv[1], "sem")) { | ||
| 133 | if (remove_ids(SEM, argc-2, &argv[2])) | ||
| 134 | bb_fflush_stdout_and_exit(1); | ||
| 135 | } | ||
| 136 | else { | ||
| 137 | bb_printf ("unknown resource type: %s\n", argv[1]); | ||
| 138 | bb_show_usage(); | ||
| 139 | bb_fflush_stdout_and_exit(1); | ||
| 140 | } | ||
| 141 | |||
| 142 | bb_printf ("resource(s) deleted\n"); | ||
| 143 | return 0; | ||
| 144 | } | 75 | } |
| 76 | #endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */ | ||
| 145 | 77 | ||
| 146 | 78 | ||
| 147 | int ipcrm_main(int argc, char **argv) | 79 | int ipcrm_main(int argc, char **argv) |
| 148 | { | 80 | { |
| 149 | int c; | 81 | int c; |
| 150 | int error = 0; | 82 | int error = 0; |
| 151 | char *prog = argv[0]; | ||
| 152 | 83 | ||
| 153 | /* if the command is executed without parameters, do nothing */ | 84 | /* if the command is executed without parameters, do nothing */ |
| 154 | if (argc == 1) | 85 | if (argc == 1) |
| 155 | return 0; | 86 | return 0; |
| 156 | 87 | #ifndef CONFIG_IPCRM_DROP_LEGACY | |
| 157 | /* check to see if the command is being invoked in the old way if so | 88 | /* check to see if the command is being invoked in the old way if so |
| 158 | then run the old code */ | 89 | then run the old code. Valid commands are msg, shm, sem. */ |
| 159 | if (strcmp(argv[1], "shm") == 0 || | 90 | { |
| 160 | strcmp(argv[1], "msg") == 0 || | 91 | type_id what = 0; /* silence gcc */ |
| 161 | strcmp(argv[1], "sem") == 0) | 92 | char w; |
| 162 | return deprecated_main(argc, argv); | 93 | |
| 94 | if ((((w=argv[1][0]) == 'm' && argv[1][1] == 's' && argv[1][2] == 'g') | ||
| 95 | || (argv[1][0] == 's' | ||
| 96 | && ((w=argv[1][1]) == 'h' || w == 'e') | ||
| 97 | && argv[1][2] == 'm')) | ||
| 98 | && argv[1][3] == '\0') { | ||
| 99 | |||
| 100 | if (argc < 3) | ||
| 101 | bb_show_usage(); | ||
| 102 | |||
| 103 | if (w == 'h') | ||
| 104 | what = SHM; | ||
| 105 | else if (w == 'm') | ||
| 106 | what = MSG; | ||
| 107 | else if (w == 'e') | ||
| 108 | what = SEM; | ||
| 109 | |||
| 110 | if (remove_ids(what, argc-2, &argv[2])) | ||
| 111 | bb_fflush_stdout_and_exit(1); | ||
| 112 | bb_printf("resource(s) deleted\n"); | ||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | #endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */ | ||
| 163 | 117 | ||
| 164 | /* process new syntax to conform with SYSV ipcrm */ | 118 | /* process new syntax to conform with SYSV ipcrm */ |
| 165 | while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) { | 119 | while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) { |
| 166 | int result; | 120 | int result; |
| 167 | int id = 0; | 121 | int id = 0; |
| 168 | int iskey = isupper(c); | 122 | int iskey = (isupper)(c); |
| 169 | 123 | ||
| 170 | /* needed to delete semaphores */ | 124 | /* needed to delete semaphores */ |
| 171 | union semun arg; | 125 | union semun arg; |
| 126 | |||
| 172 | arg.val = 0; | 127 | arg.val = 0; |
| 173 | 128 | ||
| 174 | if ((c == '?') || (c == 'h')) | 129 | if ((c == '?') || (c == 'h')) { |
| 175 | { | ||
| 176 | bb_show_usage(); | 130 | bb_show_usage(); |
| 177 | return 0; | ||
| 178 | } | 131 | } |
| 179 | 132 | ||
| 180 | /* we don't need case information any more */ | 133 | /* we don't need case information any more */ |
| 181 | c = tolower(c); | 134 | c = tolower(c); |
| 182 | 135 | ||
| 183 | /* make sure the option is in range */ | 136 | /* make sure the option is in range: allowed are q, m, s */ |
| 184 | if (c != 'q' && c != 'm' && c != 's') { | 137 | if (c != 'q' && c != 'm' && c != 's') { |
| 185 | bb_show_usage(); | 138 | bb_show_usage(); |
| 186 | error++; | ||
| 187 | return error; | ||
| 188 | } | 139 | } |
| 189 | 140 | ||
| 190 | if (iskey) { | 141 | if (iskey) { |
| 191 | /* keys are in hex or decimal */ | 142 | /* keys are in hex or decimal */ |
| 192 | key_t key = strtoul(optarg, NULL, 0); | 143 | key_t key = strtoul(optarg, NULL, 0); |
| 144 | |||
| 193 | if (key == IPC_PRIVATE) { | 145 | if (key == IPC_PRIVATE) { |
| 194 | error++; | 146 | error++; |
| 195 | bb_fprintf(stderr, "%s: illegal key (%s)\n", | 147 | bb_error_msg("illegal key (%s)", optarg); |
| 196 | prog, optarg); | ||
| 197 | continue; | 148 | continue; |
| 198 | } | 149 | } |
| 199 | 150 | ||
| 200 | /* convert key to id */ | 151 | /* convert key to id */ |
| 201 | id = ((c == 'q') ? msgget(key, 0) : | 152 | id = ((c == 'q') ? msgget(key, 0) : |
| 202 | (c == 'm') ? shmget(key, 0, 0) : | 153 | (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0)); |
| 203 | semget(key, 0, 0)); | ||
| 204 | 154 | ||
| 205 | if (id < 0) { | 155 | if (id < 0) { |
| 206 | char *errmsg; | 156 | char *errmsg; |
| 157 | const char * const what = "key"; | ||
| 158 | |||
| 207 | error++; | 159 | error++; |
| 208 | switch(errno) { | 160 | switch (errno) { |
| 209 | case EACCES: | 161 | case EACCES: |
| 210 | errmsg = "permission denied for key"; | 162 | errmsg = "permission denied for"; |
| 211 | break; | 163 | break; |
| 212 | case EIDRM: | 164 | case EIDRM: |
| 213 | errmsg = "already removed key"; | 165 | errmsg = "already removed"; |
| 214 | break; | 166 | break; |
| 215 | case ENOENT: | 167 | case ENOENT: |
| 216 | errmsg = "invalid key"; | 168 | errmsg = "invalid"; |
| 217 | break; | 169 | break; |
| 218 | default: | 170 | default: |
| 219 | errmsg = "unknown error in key"; | 171 | errmsg = "unknown error in"; |
| 220 | break; | 172 | break; |
| 221 | } | 173 | } |
| 222 | bb_fprintf(stderr, "%s: %s (%s)\n", | 174 | bb_error_msg("%s %s (%s)", errmsg, what, optarg); |
| 223 | prog, errmsg, optarg); | ||
| 224 | continue; | 175 | continue; |
| 225 | } | 176 | } |
| 226 | } else { | 177 | } else { |
| @@ -229,37 +180,30 @@ int ipcrm_main(int argc, char **argv) | |||
| 229 | } | 180 | } |
| 230 | 181 | ||
| 231 | result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) : | 182 | result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) : |
| 232 | (c == 'm') ? shmctl(id, IPC_RMID, NULL) : | 183 | (c == 'm') ? shmctl(id, IPC_RMID, NULL) : |
| 233 | semctl(id, 0, IPC_RMID, arg)); | 184 | semctl(id, 0, IPC_RMID, arg)); |
| 234 | 185 | ||
| 235 | if (result < 0) { | 186 | if (result) { |
| 236 | char *errmsg; | 187 | char *errmsg; |
| 188 | const char * const what = iskey ? "key" : "id"; | ||
| 189 | |||
| 237 | error++; | 190 | error++; |
| 238 | switch(errno) { | 191 | switch (errno) { |
| 239 | case EACCES: | 192 | case EACCES: |
| 240 | case EPERM: | 193 | case EPERM: |
| 241 | errmsg = iskey | 194 | errmsg = "permission denied for"; |
| 242 | ? "permission denied for key" | ||
| 243 | : "permission denied for id"; | ||
| 244 | break; | 195 | break; |
| 245 | case EINVAL: | 196 | case EINVAL: |
| 246 | errmsg = iskey | 197 | errmsg = "invalid"; |
| 247 | ? "invalid key" | ||
| 248 | : "invalid id"; | ||
| 249 | break; | 198 | break; |
| 250 | case EIDRM: | 199 | case EIDRM: |
| 251 | errmsg = iskey | 200 | errmsg = "already removed"; |
| 252 | ? "already removed key" | ||
| 253 | : "already removed id"; | ||
| 254 | break; | 201 | break; |
| 255 | default: | 202 | default: |
| 256 | errmsg = iskey | 203 | errmsg = "unknown error in"; |
| 257 | ? "unknown error in key" | ||
| 258 | : "unknown error in id"; | ||
| 259 | break; | 204 | break; |
| 260 | } | 205 | } |
| 261 | bb_fprintf(stderr, "%s: %s (%s)\n", | 206 | bb_error_msg("%s %s (%s)", errmsg, what, optarg); |
| 262 | prog, errmsg, optarg); | ||
| 263 | continue; | 207 | continue; |
| 264 | } | 208 | } |
| 265 | } | 209 | } |
diff --git a/util-linux/ipcs.c b/util-linux/ipcs.c index fbc75cbee..c7c837669 100644 --- a/util-linux/ipcs.c +++ b/util-linux/ipcs.c | |||
| @@ -8,9 +8,7 @@ | |||
| 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <stdio.h> | 11 | #include "busybox.h" |
| 12 | #include <stdlib.h> | ||
| 13 | #include <getopt.h> | ||
| 14 | #include <errno.h> | 12 | #include <errno.h> |
| 15 | #include <time.h> | 13 | #include <time.h> |
| 16 | #include <pwd.h> | 14 | #include <pwd.h> |
| @@ -25,15 +23,15 @@ | |||
| 25 | #include <sys/msg.h> | 23 | #include <sys/msg.h> |
| 26 | #include <sys/shm.h> | 24 | #include <sys/shm.h> |
| 27 | 25 | ||
| 28 | #include "busybox.h" | 26 | |
| 29 | 27 | ||
| 30 | /*-------------------------------------------------------------------*/ | 28 | /*-------------------------------------------------------------------*/ |
| 31 | /* SHM_DEST and SHM_LOCKED are defined in kernel headers, | 29 | /* SHM_DEST and SHM_LOCKED are defined in kernel headers, |
| 32 | but inside #ifdef __KERNEL__ ... #endif */ | 30 | but inside #ifdef __KERNEL__ ... #endif */ |
| 33 | #ifndef SHM_DEST | 31 | #ifndef SHM_DEST |
| 34 | /* shm_mode upper byte flags */ | 32 | /* shm_mode upper byte flags */ |
| 35 | #define SHM_DEST 01000 /* segment will be destroyed on last detach */ | 33 | #define SHM_DEST 01000 /* segment will be destroyed on last detach */ |
| 36 | #define SHM_LOCKED 02000 /* segment will not be swapped */ | 34 | #define SHM_LOCKED 02000 /* segment will not be swapped */ |
| 37 | #endif | 35 | #endif |
| 38 | 36 | ||
| 39 | /* For older kernels the same holds for the defines below */ | 37 | /* For older kernels the same holds for the defines below */ |
| @@ -46,12 +44,12 @@ | |||
| 46 | #define SHM_STAT 13 | 44 | #define SHM_STAT 13 |
| 47 | #define SHM_INFO 14 | 45 | #define SHM_INFO 14 |
| 48 | struct shm_info { | 46 | struct shm_info { |
| 49 | int used_ids; | 47 | int used_ids; |
| 50 | ulong shm_tot; /* total allocated shm */ | 48 | ulong shm_tot; /* total allocated shm */ |
| 51 | ulong shm_rss; /* total resident shm */ | 49 | ulong shm_rss; /* total resident shm */ |
| 52 | ulong shm_swp; /* total swapped shm */ | 50 | ulong shm_swp; /* total swapped shm */ |
| 53 | ulong swap_attempts; | 51 | ulong swap_attempts; |
| 54 | ulong swap_successes; | 52 | ulong swap_successes; |
| 55 | }; | 53 | }; |
| 56 | #endif | 54 | #endif |
| 57 | 55 | ||
| @@ -98,12 +96,14 @@ union semun { | |||
| 98 | #define TIME 4 | 96 | #define TIME 4 |
| 99 | #define PID 5 | 97 | #define PID 5 |
| 100 | 98 | ||
| 99 | static char format; | ||
| 101 | 100 | ||
| 102 | static void print_perms (int id, struct ipc_perm *ipcp) { | 101 | static void print_perms(int id, struct ipc_perm *ipcp) |
| 102 | { | ||
| 103 | struct passwd *pw; | 103 | struct passwd *pw; |
| 104 | struct group *gr; | 104 | struct group *gr; |
| 105 | 105 | ||
| 106 | bb_printf ("%-10d %-10o", id, ipcp->mode & 0777); | 106 | bb_printf("%-10d %-10o", id, ipcp->mode & 0777); |
| 107 | 107 | ||
| 108 | if ((pw = getpwuid(ipcp->cuid))) | 108 | if ((pw = getpwuid(ipcp->cuid))) |
| 109 | bb_printf(" %-10s", pw->pw_name); | 109 | bb_printf(" %-10s", pw->pw_name); |
| @@ -125,7 +125,7 @@ static void print_perms (int id, struct ipc_perm *ipcp) { | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | 127 | ||
| 128 | static void do_shm (char format) | 128 | static void do_shm(void) |
| 129 | { | 129 | { |
| 130 | int maxid, shmid, id; | 130 | int maxid, shmid, id; |
| 131 | struct shmid_ds shmseg; | 131 | struct shmid_ds shmseg; |
| @@ -134,127 +134,125 @@ static void do_shm (char format) | |||
| 134 | struct ipc_perm *ipcp = &shmseg.shm_perm; | 134 | struct ipc_perm *ipcp = &shmseg.shm_perm; |
| 135 | struct passwd *pw; | 135 | struct passwd *pw; |
| 136 | 136 | ||
| 137 | maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info); | 137 | maxid = shmctl(0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info); |
| 138 | if (maxid < 0) { | 138 | if (maxid < 0) { |
| 139 | bb_printf ("kernel not configured for shared memory\n"); | 139 | bb_printf("kernel not configured for shared memory\n"); |
| 140 | return; | 140 | return; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | switch (format) { | 143 | switch (format) { |
| 144 | case LIMITS: | 144 | case LIMITS: |
| 145 | bb_printf ("------ Shared Memory Limits --------\n"); | 145 | bb_printf("------ Shared Memory Limits --------\n"); |
| 146 | if ((shmctl (0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0 ) | 146 | if ((shmctl(0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0) |
| 147 | return; | 147 | return; |
| 148 | /* glibc 2.1.3 and all earlier libc's have ints as fields | 148 | /* glibc 2.1.3 and all earlier libc's have ints as fields |
| 149 | of struct shminfo; glibc 2.1.91 has unsigned long; ach */ | 149 | of struct shminfo; glibc 2.1.91 has unsigned long; ach */ |
| 150 | bb_printf ("max number of segments = %lu\n" | 150 | bb_printf("max number of segments = %lu\n" |
| 151 | "max seg size (kbytes) = %lu\n" | 151 | "max seg size (kbytes) = %lu\n" |
| 152 | "max total shared memory (pages) = %lu\n" | 152 | "max total shared memory (pages) = %lu\n" |
| 153 | "min seg size (bytes) = %lu\n", | 153 | "min seg size (bytes) = %lu\n", |
| 154 | (unsigned long) shminfo.shmmni, | 154 | (unsigned long) shminfo.shmmni, |
| 155 | (unsigned long) (shminfo.shmmax >> 10), | 155 | (unsigned long) (shminfo.shmmax >> 10), |
| 156 | (unsigned long) shminfo.shmall, | 156 | (unsigned long) shminfo.shmall, |
| 157 | (unsigned long) shminfo.shmmin); | 157 | (unsigned long) shminfo.shmmin); |
| 158 | return; | 158 | return; |
| 159 | 159 | ||
| 160 | case STATUS: | 160 | case STATUS: |
| 161 | bb_printf ("------ Shared Memory Status --------\n" | 161 | bb_printf("------ Shared Memory Status --------\n" |
| 162 | "segments allocated %d\n" | 162 | "segments allocated %d\n" |
| 163 | "pages allocated %ld\n" | 163 | "pages allocated %ld\n" |
| 164 | "pages resident %ld\n" | 164 | "pages resident %ld\n" |
| 165 | "pages swapped %ld\n" | 165 | "pages swapped %ld\n" |
| 166 | "Swap performance: %ld attempts\t %ld successes\n", | 166 | "Swap performance: %ld attempts\t %ld successes\n", |
| 167 | shm_info.used_ids, | 167 | shm_info.used_ids, |
| 168 | shm_info.shm_tot, | 168 | shm_info.shm_tot, |
| 169 | shm_info.shm_rss, | 169 | shm_info.shm_rss, |
| 170 | shm_info.shm_swp, | 170 | shm_info.shm_swp, |
| 171 | shm_info.swap_attempts, shm_info.swap_successes); | 171 | shm_info.swap_attempts, shm_info.swap_successes); |
| 172 | return; | 172 | return; |
| 173 | 173 | ||
| 174 | case CREATOR: | 174 | case CREATOR: |
| 175 | bb_printf ("------ Shared Memory Segment Creators/Owners --------\n" | 175 | bb_printf("------ Shared Memory Segment Creators/Owners --------\n" |
| 176 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", | 176 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", |
| 177 | "shmid","perms","cuid","cgid","uid","gid"); | 177 | "shmid", "perms", "cuid", "cgid", "uid", "gid"); |
| 178 | break; | 178 | break; |
| 179 | 179 | ||
| 180 | case TIME: | 180 | case TIME: |
| 181 | bb_printf ("------ Shared Memory Attach/Detach/Change Times --------\n" | 181 | bb_printf("------ Shared Memory Attach/Detach/Change Times --------\n" |
| 182 | "%-10s %-10s %-20s %-20s %-20s\n", | 182 | "%-10s %-10s %-20s %-20s %-20s\n", |
| 183 | "shmid","owner","attached","detached","changed"); | 183 | "shmid", "owner", "attached", "detached", "changed"); |
| 184 | break; | 184 | break; |
| 185 | 185 | ||
| 186 | case PID: | 186 | case PID: |
| 187 | bb_printf ("------ Shared Memory Creator/Last-op --------\n" | 187 | bb_printf("------ Shared Memory Creator/Last-op --------\n" |
| 188 | "%-10s %-10s %-10s %-10s\n", | 188 | "%-10s %-10s %-10s %-10s\n", |
| 189 | "shmid","owner","cpid","lpid"); | 189 | "shmid", "owner", "cpid", "lpid"); |
| 190 | break; | 190 | break; |
| 191 | 191 | ||
| 192 | default: | 192 | default: |
| 193 | bb_printf ("------ Shared Memory Segments --------\n" | 193 | bb_printf("------ Shared Memory Segments --------\n" |
| 194 | "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n", | 194 | "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n", |
| 195 | "key","shmid","owner","perms","bytes","nattch","status"); | 195 | "key", "shmid", "owner", "perms", "bytes", "nattch", |
| 196 | "status"); | ||
| 196 | break; | 197 | break; |
| 197 | } | 198 | } |
| 198 | 199 | ||
| 199 | for (id = 0; id <= maxid; id++) { | 200 | for (id = 0; id <= maxid; id++) { |
| 200 | shmid = shmctl (id, SHM_STAT, &shmseg); | 201 | shmid = shmctl(id, SHM_STAT, &shmseg); |
| 201 | if (shmid < 0) | 202 | if (shmid < 0) |
| 202 | continue; | 203 | continue; |
| 203 | if (format == CREATOR) { | 204 | if (format == CREATOR) { |
| 204 | print_perms (shmid, ipcp); | 205 | print_perms(shmid, ipcp); |
| 205 | continue; | 206 | continue; |
| 206 | } | 207 | } |
| 207 | pw = getpwuid(ipcp->uid); | 208 | pw = getpwuid(ipcp->uid); |
| 208 | switch (format) { | 209 | switch (format) { |
| 209 | case TIME: | 210 | case TIME: |
| 210 | if (pw) | 211 | if (pw) |
| 211 | bb_printf ("%-10d %-10.10s", shmid, pw->pw_name); | 212 | bb_printf("%-10d %-10.10s", shmid, pw->pw_name); |
| 212 | else | 213 | else |
| 213 | bb_printf ("%-10d %-10d", shmid, ipcp->uid); | 214 | bb_printf("%-10d %-10d", shmid, ipcp->uid); |
| 214 | /* ctime uses static buffer: use separate calls */ | 215 | /* ctime uses static buffer: use separate calls */ |
| 215 | bb_printf(" %-20.16s", shmseg.shm_atime | 216 | bb_printf(" %-20.16s", shmseg.shm_atime |
| 216 | ? ctime(&shmseg.shm_atime) + 4 : "Not set"); | 217 | ? ctime(&shmseg.shm_atime) + 4 : "Not set"); |
| 217 | bb_printf(" %-20.16s", shmseg.shm_dtime | 218 | bb_printf(" %-20.16s", shmseg.shm_dtime |
| 218 | ? ctime(&shmseg.shm_dtime) + 4 : "Not set"); | 219 | ? ctime(&shmseg.shm_dtime) + 4 : "Not set"); |
| 219 | bb_printf(" %-20.16s\n", shmseg.shm_ctime | 220 | bb_printf(" %-20.16s\n", shmseg.shm_ctime |
| 220 | ? ctime(&shmseg.shm_ctime) + 4 : "Not set"); | 221 | ? ctime(&shmseg.shm_ctime) + 4 : "Not set"); |
| 221 | break; | 222 | break; |
| 222 | case PID: | 223 | case PID: |
| 223 | if (pw) | 224 | if (pw) |
| 224 | bb_printf ("%-10d %-10.10s", shmid, pw->pw_name); | 225 | bb_printf("%-10d %-10.10s", shmid, pw->pw_name); |
| 225 | else | 226 | else |
| 226 | bb_printf ("%-10d %-10d", shmid, ipcp->uid); | 227 | bb_printf("%-10d %-10d", shmid, ipcp->uid); |
| 227 | bb_printf (" %-10d %-10d\n", | 228 | bb_printf(" %-10d %-10d\n", shmseg.shm_cpid, shmseg.shm_lpid); |
| 228 | shmseg.shm_cpid, shmseg.shm_lpid); | ||
| 229 | break; | 229 | break; |
| 230 | 230 | ||
| 231 | default: | 231 | default: |
| 232 | bb_printf("0x%08x ",ipcp->KEY ); | 232 | bb_printf("0x%08x ", ipcp->KEY); |
| 233 | if (pw) | 233 | if (pw) |
| 234 | bb_printf ("%-10d %-10.10s", shmid, pw->pw_name); | 234 | bb_printf("%-10d %-10.10s", shmid, pw->pw_name); |
| 235 | else | 235 | else |
| 236 | bb_printf ("%-10d %-10d", shmid, ipcp->uid); | 236 | bb_printf("%-10d %-10d", shmid, ipcp->uid); |
| 237 | bb_printf ("%-10o %-10lu %-10ld %-6s %-6s\n", | 237 | bb_printf("%-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777, |
| 238 | ipcp->mode & 0777, | 238 | /* |
| 239 | /* | 239 | * earlier: int, Austin has size_t |
| 240 | * earlier: int, Austin has size_t | 240 | */ |
| 241 | */ | 241 | (unsigned long) shmseg.shm_segsz, |
| 242 | (unsigned long) shmseg.shm_segsz, | 242 | /* |
| 243 | /* | 243 | * glibc-2.1.3 and earlier has unsigned short; |
| 244 | * glibc-2.1.3 and earlier has unsigned short; | 244 | * Austin has shmatt_t |
| 245 | * Austin has shmatt_t | 245 | */ |
| 246 | */ | 246 | (long) shmseg.shm_nattch, |
| 247 | (long) shmseg.shm_nattch, | 247 | ipcp->mode & SHM_DEST ? "dest" : " ", |
| 248 | ipcp->mode & SHM_DEST ? "dest" : " ", | 248 | ipcp->mode & SHM_LOCKED ? "locked" : " "); |
| 249 | ipcp->mode & SHM_LOCKED ? "locked" : " "); | ||
| 250 | break; | 249 | break; |
| 251 | } | 250 | } |
| 252 | } | 251 | } |
| 253 | return; | ||
| 254 | } | 252 | } |
| 255 | 253 | ||
| 256 | 254 | ||
| 257 | static void do_sem (char format) | 255 | static void do_sem(void) |
| 258 | { | 256 | { |
| 259 | int maxid, semid, id; | 257 | int maxid, semid, id; |
| 260 | struct semid_ds semary; | 258 | struct semid_ds semary; |
| @@ -263,107 +261,104 @@ static void do_sem (char format) | |||
| 263 | struct passwd *pw; | 261 | struct passwd *pw; |
| 264 | union semun arg; | 262 | union semun arg; |
| 265 | 263 | ||
| 266 | arg.array = (ushort *) (void *) &seminfo; | 264 | arg.array = (ushort *) (void *) &seminfo; |
| 267 | maxid = semctl (0, 0, SEM_INFO, arg); | 265 | maxid = semctl(0, 0, SEM_INFO, arg); |
| 268 | if (maxid < 0) { | 266 | if (maxid < 0) { |
| 269 | bb_printf ("kernel not configured for semaphores\n"); | 267 | bb_printf("kernel not configured for semaphores\n"); |
| 270 | return; | 268 | return; |
| 271 | } | 269 | } |
| 272 | 270 | ||
| 273 | switch (format) { | 271 | switch (format) { |
| 274 | case LIMITS: | 272 | case LIMITS: |
| 275 | bb_printf ("------ Semaphore Limits --------\n"); | 273 | bb_printf("------ Semaphore Limits --------\n"); |
| 276 | arg.array = (ushort *) (void *) &seminfo; /* damn union */ | 274 | arg.array = (ushort *) (void *) &seminfo; /* damn union */ |
| 277 | if ((semctl (0, 0, IPC_INFO, arg)) < 0 ) | 275 | if ((semctl(0, 0, IPC_INFO, arg)) < 0) |
| 278 | return; | 276 | return; |
| 279 | bb_printf ("max number of arrays = %d\n" | 277 | bb_printf("max number of arrays = %d\n" |
| 280 | "max semaphores per array = %d\n" | 278 | "max semaphores per array = %d\n" |
| 281 | "max semaphores system wide = %d\n" | 279 | "max semaphores system wide = %d\n" |
| 282 | "max ops per semop call = %d\n" | 280 | "max ops per semop call = %d\n" |
| 283 | "semaphore max value = %d\n", | 281 | "semaphore max value = %d\n", |
| 284 | seminfo.semmni, | 282 | seminfo.semmni, |
| 285 | seminfo.semmsl, | 283 | seminfo.semmsl, |
| 286 | seminfo.semmns, | 284 | seminfo.semmns, seminfo.semopm, seminfo.semvmx); |
| 287 | seminfo.semopm, | ||
| 288 | seminfo.semvmx); | ||
| 289 | return; | 285 | return; |
| 290 | 286 | ||
| 291 | case STATUS: | 287 | case STATUS: |
| 292 | bb_printf ("------ Semaphore Status --------\n" | 288 | bb_printf("------ Semaphore Status --------\n" |
| 293 | "used arrays = %d\n" | 289 | "used arrays = %d\n" |
| 294 | "allocated semaphores = %d\n", | 290 | "allocated semaphores = %d\n", |
| 295 | seminfo.semusz, | 291 | seminfo.semusz, seminfo.semaem); |
| 296 | seminfo.semaem); | ||
| 297 | return; | 292 | return; |
| 298 | 293 | ||
| 299 | case CREATOR: | 294 | case CREATOR: |
| 300 | bb_printf ("------ Semaphore Arrays Creators/Owners --------\n" | 295 | bb_printf("------ Semaphore Arrays Creators/Owners --------\n" |
| 301 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", | 296 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", |
| 302 | "semid","perms","cuid","cgid","uid","gid"); | 297 | "semid", "perms", "cuid", "cgid", "uid", "gid"); |
| 303 | break; | 298 | break; |
| 304 | 299 | ||
| 305 | case TIME: | 300 | case TIME: |
| 306 | bb_printf ("------ Shared Memory Operation/Change Times --------\n" | 301 | bb_printf("------ Shared Memory Operation/Change Times --------\n" |
| 307 | "%-8s %-10s %-26.24s %-26.24s\n", | 302 | "%-8s %-10s %-26.24s %-26.24s\n", |
| 308 | "shmid","owner","last-op","last-changed"); | 303 | "shmid", "owner", "last-op", "last-changed"); |
| 309 | break; | 304 | break; |
| 310 | 305 | ||
| 311 | case PID: | 306 | case PID: |
| 312 | break; | 307 | break; |
| 313 | 308 | ||
| 314 | default: | 309 | default: |
| 315 | bb_printf ("------ Semaphore Arrays --------\n" | 310 | bb_printf("------ Semaphore Arrays --------\n" |
| 316 | "%-10s %-10s %-10s %-10s %-10s\n", | 311 | "%-10s %-10s %-10s %-10s %-10s\n", |
| 317 | "key","semid","owner","perms","nsems"); | 312 | "key", "semid", "owner", "perms", "nsems"); |
| 318 | break; | 313 | break; |
| 319 | } | 314 | } |
| 320 | 315 | ||
| 321 | for (id = 0; id <= maxid; id++) { | 316 | for (id = 0; id <= maxid; id++) { |
| 322 | arg.buf = (struct semid_ds *) &semary; | 317 | arg.buf = (struct semid_ds *) &semary; |
| 323 | semid = semctl (id, 0, SEM_STAT, arg); | 318 | semid = semctl(id, 0, SEM_STAT, arg); |
| 324 | if (semid < 0) | 319 | if (semid < 0) |
| 325 | continue; | 320 | continue; |
| 326 | if (format == CREATOR) { | 321 | if (format == CREATOR) { |
| 327 | print_perms (semid, ipcp); | 322 | print_perms(semid, ipcp); |
| 328 | continue; | 323 | continue; |
| 329 | } | 324 | } |
| 330 | pw = getpwuid(ipcp->uid); | 325 | pw = getpwuid(ipcp->uid); |
| 331 | switch (format) { | 326 | switch (format) { |
| 332 | case TIME: | 327 | case TIME: |
| 333 | if (pw) | 328 | if (pw) |
| 334 | bb_printf ("%-8d %-10.10s", semid, pw->pw_name); | 329 | bb_printf("%-8d %-10.10s", semid, pw->pw_name); |
| 335 | else | 330 | else |
| 336 | bb_printf ("%-8d %-10d", semid, ipcp->uid); | 331 | bb_printf("%-8d %-10d", semid, ipcp->uid); |
| 337 | bb_printf (" %-26.24s", semary.sem_otime | 332 | /* ctime uses static buffer: use separate calls */ |
| 338 | ? ctime(&semary.sem_otime) : "Not set"); | 333 | bb_printf(" %-26.24s", semary.sem_otime |
| 339 | bb_printf (" %-26.24s\n", semary.sem_ctime | 334 | ? ctime(&semary.sem_otime) : "Not set"); |
| 340 | ? ctime(&semary.sem_ctime) : "Not set"); | 335 | bb_printf(" %-26.24s\n", semary.sem_ctime |
| 336 | ? ctime(&semary.sem_ctime) : "Not set"); | ||
| 341 | break; | 337 | break; |
| 342 | case PID: | 338 | case PID: |
| 343 | break; | 339 | break; |
| 344 | 340 | ||
| 345 | default: | 341 | default: |
| 346 | bb_printf("0x%08x ", ipcp->KEY); | 342 | bb_printf("0x%08x ", ipcp->KEY); |
| 347 | if (pw) | 343 | if (pw) |
| 348 | bb_printf ("%-10d %-10.9s", semid, pw->pw_name); | 344 | bb_printf("%-10d %-10.9s", semid, pw->pw_name); |
| 349 | else | 345 | else |
| 350 | bb_printf ("%-10d %-9d", semid, ipcp->uid); | 346 | bb_printf("%-10d %-9d", semid, ipcp->uid); |
| 351 | bb_printf ("%-10o %-10ld\n", | 347 | bb_printf("%-10o %-10ld\n", ipcp->mode & 0777, |
| 352 | ipcp->mode & 0777, | 348 | /* |
| 353 | /* | 349 | * glibc-2.1.3 and earlier has unsigned short; |
| 354 | * glibc-2.1.3 and earlier has unsigned short; | 350 | * glibc-2.1.91 has variation between |
| 355 | * glibc-2.1.91 has variation between | 351 | * unsigned short and unsigned long |
| 356 | * unsigned short and unsigned long | 352 | * Austin prescribes unsigned short. |
| 357 | * Austin prescribes unsigned short. | 353 | */ |
| 358 | */ | 354 | (long) semary.sem_nsems); |
| 359 | (long) semary.sem_nsems); | ||
| 360 | break; | 355 | break; |
| 361 | } | 356 | } |
| 362 | } | 357 | } |
| 363 | } | 358 | } |
| 364 | 359 | ||
| 365 | 360 | ||
| 366 | static void do_msg (char format) | 361 | static void do_msg(void) |
| 367 | { | 362 | { |
| 368 | int maxid, msqid, id; | 363 | int maxid, msqid, id; |
| 369 | struct msqid_ds msgque; | 364 | struct msqid_ds msgque; |
| @@ -371,178 +366,165 @@ static void do_msg (char format) | |||
| 371 | struct ipc_perm *ipcp = &msgque.msg_perm; | 366 | struct ipc_perm *ipcp = &msgque.msg_perm; |
| 372 | struct passwd *pw; | 367 | struct passwd *pw; |
| 373 | 368 | ||
| 374 | maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo); | 369 | maxid = msgctl(0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo); |
| 375 | if (maxid < 0) { | 370 | if (maxid < 0) { |
| 376 | bb_printf ("kernel not configured for message queues\n"); | 371 | bb_printf("kernel not configured for message queues\n"); |
| 377 | return; | 372 | return; |
| 378 | } | 373 | } |
| 379 | 374 | ||
| 380 | switch (format) { | 375 | switch (format) { |
| 381 | case LIMITS: | 376 | case LIMITS: |
| 382 | if ((msgctl (0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0 ) | 377 | if ((msgctl(0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0) |
| 383 | return; | 378 | return; |
| 384 | bb_printf ("------ Messages: Limits --------\n" | 379 | bb_printf("------ Messages: Limits --------\n" |
| 385 | "max queues system wide = %d\n" | 380 | "max queues system wide = %d\n" |
| 386 | "max size of message (bytes) = %d\n" | 381 | "max size of message (bytes) = %d\n" |
| 387 | "default max size of queue (bytes) = %d\n", | 382 | "default max size of queue (bytes) = %d\n", |
| 388 | msginfo.msgmni, | 383 | msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb); |
| 389 | msginfo.msgmax, | ||
| 390 | msginfo.msgmnb); | ||
| 391 | return; | 384 | return; |
| 392 | 385 | ||
| 393 | case STATUS: | 386 | case STATUS: |
| 394 | bb_printf ("------ Messages: Status --------\n" | 387 | bb_printf("------ Messages: Status --------\n" |
| 395 | "allocated queues = %d\n" | 388 | "allocated queues = %d\n" |
| 396 | "used headers = %d\n" | 389 | "used headers = %d\n" |
| 397 | "used space = %d bytes\n", | 390 | "used space = %d bytes\n", |
| 398 | msginfo.msgpool, | 391 | msginfo.msgpool, msginfo.msgmap, msginfo.msgtql); |
| 399 | msginfo.msgmap, | ||
| 400 | msginfo.msgtql); | ||
| 401 | return; | 392 | return; |
| 402 | 393 | ||
| 403 | case CREATOR: | 394 | case CREATOR: |
| 404 | bb_printf ("------ Message Queues: Creators/Owners --------\n" | 395 | bb_printf("------ Message Queues: Creators/Owners --------\n" |
| 405 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", | 396 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", |
| 406 | "msqid","perms","cuid","cgid","uid","gid"); | 397 | "msqid", "perms", "cuid", "cgid", "uid", "gid"); |
| 407 | break; | 398 | break; |
| 408 | 399 | ||
| 409 | case TIME: | 400 | case TIME: |
| 410 | bb_printf ("------ Message Queues Send/Recv/Change Times --------\n" | 401 | bb_printf("------ Message Queues Send/Recv/Change Times --------\n" |
| 411 | "%-8s %-10s %-20s %-20s %-20s\n", | 402 | "%-8s %-10s %-20s %-20s %-20s\n", |
| 412 | "msqid","owner","send","recv","change"); | 403 | "msqid", "owner", "send", "recv", "change"); |
| 413 | break; | 404 | break; |
| 414 | 405 | ||
| 415 | case PID: | 406 | case PID: |
| 416 | bb_printf ("------ Message Queues PIDs --------\n" | 407 | bb_printf("------ Message Queues PIDs --------\n" |
| 417 | "%-10s %-10s %-10s %-10s\n", | 408 | "%-10s %-10s %-10s %-10s\n", |
| 418 | "msqid","owner","lspid","lrpid"); | 409 | "msqid", "owner", "lspid", "lrpid"); |
| 419 | break; | 410 | break; |
| 420 | 411 | ||
| 421 | default: | 412 | default: |
| 422 | bb_printf ("------ Message Queues --------\n" | 413 | bb_printf("------ Message Queues --------\n" |
| 423 | "%-10s %-10s %-10s %-10s %-12s %-12s\n", | 414 | "%-10s %-10s %-10s %-10s %-12s %-12s\n", |
| 424 | "key","msqid","owner","perms","used-bytes","messages"); | 415 | "key", "msqid", "owner", "perms", "used-bytes", "messages"); |
| 425 | break; | 416 | break; |
| 426 | } | 417 | } |
| 427 | 418 | ||
| 428 | for (id = 0; id <= maxid; id++) { | 419 | for (id = 0; id <= maxid; id++) { |
| 429 | msqid = msgctl (id, MSG_STAT, &msgque); | 420 | msqid = msgctl(id, MSG_STAT, &msgque); |
| 430 | if (msqid < 0) | 421 | if (msqid < 0) |
| 431 | continue; | 422 | continue; |
| 432 | if (format == CREATOR) { | 423 | if (format == CREATOR) { |
| 433 | print_perms (msqid, ipcp); | 424 | print_perms(msqid, ipcp); |
| 434 | continue; | 425 | continue; |
| 435 | } | 426 | } |
| 436 | pw = getpwuid(ipcp->uid); | 427 | pw = getpwuid(ipcp->uid); |
| 437 | switch (format) { | 428 | switch (format) { |
| 438 | case TIME: | 429 | case TIME: |
| 439 | if (pw) | 430 | if (pw) |
| 440 | bb_printf ("%-8d %-10.10s", msqid, pw->pw_name); | 431 | bb_printf("%-8d %-10.10s", msqid, pw->pw_name); |
| 441 | else | 432 | else |
| 442 | bb_printf ("%-8d %-10d", msqid, ipcp->uid); | 433 | bb_printf("%-8d %-10d", msqid, ipcp->uid); |
| 443 | bb_printf (" %-20.16s", msgque.msg_stime | 434 | bb_printf(" %-20.16s", msgque.msg_stime |
| 444 | ? ctime(&msgque.msg_stime) + 4 : "Not set"); | 435 | ? ctime(&msgque.msg_stime) + 4 : "Not set"); |
| 445 | bb_printf (" %-20.16s", msgque.msg_rtime | 436 | bb_printf(" %-20.16s", msgque.msg_rtime |
| 446 | ? ctime(&msgque.msg_rtime) + 4 : "Not set"); | 437 | ? ctime(&msgque.msg_rtime) + 4 : "Not set"); |
| 447 | bb_printf (" %-20.16s\n", msgque.msg_ctime | 438 | bb_printf(" %-20.16s\n", msgque.msg_ctime |
| 448 | ? ctime(&msgque.msg_ctime) + 4 : "Not set"); | 439 | ? ctime(&msgque.msg_ctime) + 4 : "Not set"); |
| 449 | break; | 440 | break; |
| 450 | case PID: | 441 | case PID: |
| 451 | if (pw) | 442 | if (pw) |
| 452 | bb_printf ("%-8d %-10.10s", msqid, pw->pw_name); | 443 | bb_printf("%-8d %-10.10s", msqid, pw->pw_name); |
| 453 | else | 444 | else |
| 454 | bb_printf ("%-8d %-10d", msqid, ipcp->uid); | 445 | bb_printf("%-8d %-10d", msqid, ipcp->uid); |
| 455 | bb_printf (" %5d %5d\n", | 446 | bb_printf(" %5d %5d\n", msgque.msg_lspid, msgque.msg_lrpid); |
| 456 | msgque.msg_lspid, msgque.msg_lrpid); | ||
| 457 | break; | 447 | break; |
| 458 | 448 | ||
| 459 | default: | 449 | default: |
| 460 | bb_printf( "0x%08x ",ipcp->KEY ); | 450 | bb_printf("0x%08x ", ipcp->KEY); |
| 461 | if (pw) | 451 | if (pw) |
| 462 | bb_printf ("%-10d %-10.10s", msqid, pw->pw_name); | 452 | bb_printf("%-10d %-10.10s", msqid, pw->pw_name); |
| 463 | else | 453 | else |
| 464 | bb_printf ("%-10d %-10d", msqid, ipcp->uid); | 454 | bb_printf("%-10d %-10d", msqid, ipcp->uid); |
| 465 | bb_printf (" %-10o %-12ld %-12ld\n", | 455 | bb_printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777, |
| 466 | ipcp->mode & 0777, | 456 | /* |
| 467 | /* | 457 | * glibc-2.1.3 and earlier has unsigned short; |
| 468 | * glibc-2.1.3 and earlier has unsigned short; | 458 | * glibc-2.1.91 has variation between |
| 469 | * glibc-2.1.91 has variation between | 459 | * unsigned short, unsigned long |
| 470 | * unsigned short, unsigned long | 460 | * Austin has msgqnum_t |
| 471 | * Austin has msgqnum_t | 461 | */ |
| 472 | */ | 462 | (long) msgque.msg_cbytes, (long) msgque.msg_qnum); |
| 473 | (long) msgque.msg_cbytes, | ||
| 474 | (long) msgque.msg_qnum); | ||
| 475 | break; | 463 | break; |
| 476 | } | 464 | } |
| 477 | } | 465 | } |
| 478 | return; | ||
| 479 | } | 466 | } |
| 480 | 467 | ||
| 481 | 468 | ||
| 482 | static void print_shm (int shmid) | 469 | static void print_shm(int shmid) |
| 483 | { | 470 | { |
| 484 | struct shmid_ds shmds; | 471 | struct shmid_ds shmds; |
| 485 | struct ipc_perm *ipcp = &shmds.shm_perm; | 472 | struct ipc_perm *ipcp = &shmds.shm_perm; |
| 486 | 473 | ||
| 487 | if (shmctl (shmid, IPC_STAT, &shmds) == -1) { | 474 | if (shmctl(shmid, IPC_STAT, &shmds) == -1) { |
| 488 | perror ("shmctl "); | 475 | bb_perror_msg("shmctl"); |
| 489 | return; | 476 | return; |
| 490 | } | 477 | } |
| 491 | 478 | ||
| 492 | bb_printf ("\nShared memory Segment shmid=%d\n" | 479 | bb_printf("\nShared memory Segment shmid=%d\n" |
| 493 | "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n" | 480 | "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n" |
| 494 | "mode=%#o\taccess_perms=%#o\n" | 481 | "mode=%#o\taccess_perms=%#o\n" |
| 495 | "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n" | 482 | "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n", |
| 496 | "att_time=%-26.24s\n" | 483 | shmid, |
| 497 | "det_time=%-26.24s\n" | 484 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, |
| 498 | "change_time=%-26.24s\n" | 485 | ipcp->mode, ipcp->mode & 0777, |
| 499 | "\n", | 486 | (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid, |
| 500 | shmid, | 487 | (long) shmds.shm_nattch); |
| 501 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, | 488 | bb_printf("att_time=%-26.24s\n", |
| 502 | ipcp->mode, ipcp->mode & 0777, | 489 | shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set"); |
| 503 | (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid, | 490 | bb_printf("det_time=%-26.24s\n", |
| 504 | (long) shmds.shm_nattch, | 491 | shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set"); |
| 505 | shmds.shm_atime ? ctime (&shmds.shm_atime) : "Not set", | 492 | bb_printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime)); |
| 506 | shmds.shm_dtime ? ctime (&shmds.shm_dtime) : "Not set", | ||
| 507 | ctime (&shmds.shm_ctime)); | ||
| 508 | return; | ||
| 509 | } | 493 | } |
| 510 | 494 | ||
| 511 | 495 | ||
| 512 | static void print_msg (int msqid) | 496 | static void print_msg(int msqid) |
| 513 | { | 497 | { |
| 514 | struct msqid_ds buf; | 498 | struct msqid_ds buf; |
| 515 | struct ipc_perm *ipcp = &buf.msg_perm; | 499 | struct ipc_perm *ipcp = &buf.msg_perm; |
| 516 | 500 | ||
| 517 | if (msgctl (msqid, IPC_STAT, &buf) == -1) { | 501 | if (msgctl(msqid, IPC_STAT, &buf) == -1) { |
| 518 | perror ("msgctl "); | 502 | bb_perror_msg("msgctl"); |
| 519 | return; | 503 | return; |
| 520 | } | 504 | } |
| 521 | 505 | ||
| 522 | bb_printf ("\nMessage Queue msqid=%d\n" | 506 | bb_printf("\nMessage Queue msqid=%d\n" |
| 523 | "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n" | 507 | "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n" |
| 524 | "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n" | 508 | "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n", |
| 525 | "send_time=%-26.24s\n" | 509 | msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode, |
| 526 | "rcv_time=%-26.24s\n" | 510 | /* |
| 527 | "change_time=%-26.24s\n" | 511 | * glibc-2.1.3 and earlier has unsigned short; |
| 528 | "\n", | 512 | * glibc-2.1.91 has variation between |
| 529 | msqid, | 513 | * unsigned short, unsigned long |
| 530 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode, | 514 | * Austin has msgqnum_t (for msg_qbytes) |
| 531 | /* | 515 | */ |
| 532 | * glibc-2.1.3 and earlier has unsigned short; | 516 | (long) buf.msg_cbytes, (long) buf.msg_qbytes, |
| 533 | * glibc-2.1.91 has variation between | 517 | (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid); |
| 534 | * unsigned short, unsigned long | 518 | |
| 535 | * Austin has msgqnum_t (for msg_qbytes) | 519 | bb_printf("send_time=%-26.24s\n", |
| 536 | */ | 520 | buf.msg_stime ? ctime(&buf.msg_stime) : "Not set"); |
| 537 | (long) buf.msg_cbytes, (long) buf.msg_qbytes, | 521 | bb_printf("rcv_time=%-26.24s\n", |
| 538 | (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid, | 522 | buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set"); |
| 539 | buf.msg_stime ? ctime (&buf.msg_stime) : "Not set", | 523 | bb_printf("change_time=%-26.24s\n\n", |
| 540 | buf.msg_rtime ? ctime (&buf.msg_rtime) : "Not set", | 524 | buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set"); |
| 541 | buf.msg_ctime ? ctime (&buf.msg_ctime) : "Not set"); | ||
| 542 | return; | ||
| 543 | } | 525 | } |
| 544 | 526 | ||
| 545 | static void print_sem (int semid) | 527 | static void print_sem(int semid) |
| 546 | { | 528 | { |
| 547 | struct semid_ds semds; | 529 | struct semid_ds semds; |
| 548 | struct ipc_perm *ipcp = &semds.sem_perm; | 530 | struct ipc_perm *ipcp = &semds.sem_perm; |
| @@ -550,66 +532,69 @@ static void print_sem (int semid) | |||
| 550 | unsigned int i; | 532 | unsigned int i; |
| 551 | 533 | ||
| 552 | arg.buf = &semds; | 534 | arg.buf = &semds; |
| 553 | if (semctl (semid, 0, IPC_STAT, arg) < 0) { | 535 | if (semctl(semid, 0, IPC_STAT, arg)) { |
| 554 | perror ("semctl "); | 536 | bb_perror_msg("semctl"); |
| 555 | return; | 537 | return; |
| 556 | } | 538 | } |
| 557 | 539 | ||
| 558 | bb_printf ("\nSemaphore Array semid=%d\n" | 540 | bb_printf("\nSemaphore Array semid=%d\n" |
| 559 | "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n" | 541 | "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n" |
| 560 | "mode=%#o, access_perms=%#o\n" | 542 | "mode=%#o, access_perms=%#o\n" |
| 561 | "nsems = %ld\n" | 543 | "nsems = %ld\n" |
| 562 | "otime = %-26.24s\n" | 544 | "otime = %-26.24s\n", |
| 563 | "ctime = %-26.24s\n" | 545 | semid, |
| 564 | "%-10s %-10s %-10s %-10s %-10s\n", | 546 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, |
| 565 | semid, | 547 | ipcp->mode, ipcp->mode & 0777, |
| 566 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, | 548 | (long) semds.sem_nsems, |
| 567 | ipcp->mode, ipcp->mode & 0777, | 549 | semds.sem_otime ? ctime(&semds.sem_otime) : "Not set"); |
| 568 | (long) semds.sem_nsems, | 550 | bb_printf("ctime = %-26.24s\n" |
| 569 | semds.sem_otime ? ctime (&semds.sem_otime) : "Not set", | 551 | "%-10s %-10s %-10s %-10s %-10s\n", |
| 570 | ctime (&semds.sem_ctime), | 552 | ctime(&semds.sem_ctime), |
| 571 | "semnum","value","ncount","zcount","pid"); | 553 | "semnum", "value", "ncount", "zcount", "pid"); |
| 572 | 554 | ||
| 573 | arg.val = 0; | 555 | arg.val = 0; |
| 574 | for (i=0; i < semds.sem_nsems; i++) { | 556 | for (i = 0; i < semds.sem_nsems; i++) { |
| 575 | int val, ncnt, zcnt, pid; | 557 | int val, ncnt, zcnt, pid; |
| 576 | val = semctl (semid, i, GETVAL, arg); | 558 | |
| 577 | ncnt = semctl (semid, i, GETNCNT, arg); | 559 | val = semctl(semid, i, GETVAL, arg); |
| 578 | zcnt = semctl (semid, i, GETZCNT, arg); | 560 | ncnt = semctl(semid, i, GETNCNT, arg); |
| 579 | pid = semctl (semid, i, GETPID, arg); | 561 | zcnt = semctl(semid, i, GETZCNT, arg); |
| 562 | pid = semctl(semid, i, GETPID, arg); | ||
| 580 | if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) { | 563 | if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) { |
| 581 | perror ("semctl "); | 564 | bb_perror_msg_and_die("semctl"); |
| 582 | bb_fflush_stdout_and_exit (1); | ||
| 583 | } | 565 | } |
| 584 | bb_printf ("%-10d %-10d %-10d %-10d %-10d\n", | 566 | bb_printf("%-10d %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid); |
| 585 | i, val, ncnt, zcnt, pid); | ||
| 586 | } | 567 | } |
| 587 | bb_printf ("\n"); | 568 | bb_printf("\n"); |
| 588 | return; | ||
| 589 | } | 569 | } |
| 590 | 570 | ||
| 591 | int ipcs_main (int argc, char **argv) { | 571 | int ipcs_main(int argc, char **argv) |
| 592 | int opt, msg = 0, sem = 0, shm = 0, id=0, print=0; | 572 | { |
| 593 | char format = 0; | 573 | int opt, id = 0; |
| 594 | char options[] = "atclupsmqi:ih?"; | 574 | unsigned flags = 0; |
| 595 | 575 | #define flag_print (1<<0) | |
| 596 | while ((opt = getopt (argc, argv, options)) != -1) { | 576 | #define flag_msg (1<<1) |
| 577 | #define flag_sem (1<<2) | ||
| 578 | #define flag_shm (1<<3) | ||
| 579 | const char *const options = "atclupsmqi:ih?"; | ||
| 580 | |||
| 581 | while ((opt = getopt(argc, argv, options)) != -1) { | ||
| 597 | switch (opt) { | 582 | switch (opt) { |
| 598 | case 'i': | 583 | case 'i': |
| 599 | id = atoi (optarg); | 584 | id = atoi(optarg); |
| 600 | print = 1; | 585 | flags |= flag_print; |
| 601 | break; | 586 | break; |
| 602 | case 'a': | 587 | case 'a': |
| 603 | msg = shm = sem = 1; | 588 | flags |= flag_msg | flag_sem | flag_shm; |
| 604 | break; | 589 | break; |
| 605 | case 'q': | 590 | case 'q': |
| 606 | msg = 1; | 591 | flags |= flag_msg; |
| 607 | break; | 592 | break; |
| 608 | case 's': | 593 | case 's': |
| 609 | sem = 1; | 594 | flags |= flag_sem; |
| 610 | break; | 595 | break; |
| 611 | case 'm': | 596 | case 'm': |
| 612 | shm = 1; | 597 | flags |= flag_shm; |
| 613 | break; | 598 | break; |
| 614 | case 't': | 599 | case 't': |
| 615 | format = TIME; | 600 | format = TIME; |
| @@ -629,43 +614,40 @@ int ipcs_main (int argc, char **argv) { | |||
| 629 | case 'h': | 614 | case 'h': |
| 630 | case '?': | 615 | case '?': |
| 631 | bb_show_usage(); | 616 | bb_show_usage(); |
| 632 | bb_fflush_stdout_and_exit (0); | ||
| 633 | } | 617 | } |
| 634 | } | 618 | } |
| 635 | 619 | ||
| 636 | if (print) { | 620 | if (flags & flag_print) { |
| 637 | if (shm) { | 621 | if (flags & flag_shm) { |
| 638 | print_shm (id); | 622 | print_shm(id); |
| 639 | bb_fflush_stdout_and_exit (0); | 623 | bb_fflush_stdout_and_exit(0); |
| 640 | } | 624 | } |
| 641 | if (sem) { | 625 | if (flags & flag_sem) { |
| 642 | print_sem (id); | 626 | print_sem(id); |
| 643 | bb_fflush_stdout_and_exit (0); | 627 | bb_fflush_stdout_and_exit(0); |
| 644 | } | 628 | } |
| 645 | if (msg) { | 629 | if (flags & flag_msg) { |
| 646 | print_msg (id); | 630 | print_msg(id); |
| 647 | bb_fflush_stdout_and_exit (0); | 631 | bb_fflush_stdout_and_exit(0); |
| 648 | } | 632 | } |
| 649 | bb_show_usage(); | 633 | bb_show_usage(); |
| 650 | bb_fflush_stdout_and_exit (0); | ||
| 651 | } | 634 | } |
| 652 | 635 | ||
| 653 | if ( !shm && !msg && !sem) | 636 | if (!(flags & (flag_shm | flag_msg | flag_sem))) |
| 654 | msg = sem = shm = 1; | 637 | flags |= flag_msg | flag_shm | flag_sem; |
| 655 | bb_printf ("\n"); | 638 | bb_printf("\n"); |
| 656 | 639 | ||
| 657 | if (shm) { | 640 | if (flags & flag_shm) { |
| 658 | do_shm (format); | 641 | do_shm(); |
| 659 | bb_printf ("\n"); | 642 | bb_printf("\n"); |
| 660 | } | 643 | } |
| 661 | if (sem) { | 644 | if (flags & flag_sem) { |
| 662 | do_sem (format); | 645 | do_sem(); |
| 663 | bb_printf ("\n"); | 646 | bb_printf("\n"); |
| 664 | } | 647 | } |
| 665 | if (msg) { | 648 | if (flags & flag_msg) { |
| 666 | do_msg (format); | 649 | do_msg(); |
| 667 | bb_printf ("\n"); | 650 | bb_printf("\n"); |
| 668 | } | 651 | } |
| 669 | return 0; | 652 | return EXIT_SUCCESS; |
| 670 | } | 653 | } |
| 671 | |||
