diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-06 12:04:42 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-06 12:04:42 +0000 |
commit | bfbc971f9f96861abd80b977fb86e2791541bea8 (patch) | |
tree | 7319cf070d58a3a27623432657cac8017be3cb9f | |
parent | b0a6478eefe3894d16a15f8a23908135e7c97aa7 (diff) | |
download | busybox-w32-bfbc971f9f96861abd80b977fb86e2791541bea8.tar.gz busybox-w32-bfbc971f9f96861abd80b977fb86e2791541bea8.tar.bz2 busybox-w32-bfbc971f9f96861abd80b977fb86e2791541bea8.zip |
hush: print cd error to stderr; use fopen_or_warn in builtin_source;
prepare builtin_unset for function support
libbb: do not clear errno in fopen_or_warn
function old new delta
builtin_unset 242 271 +29
fopen_or_warn 42 31 -11
builtin_cd 90 74 -16
builtin_source 89 72 -17
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/3 up/down: 29/-44) Total: -15 bytes
-rw-r--r-- | libbb/wfopen.c | 2 | ||||
-rw-r--r-- | shell/hush.c | 62 |
2 files changed, 39 insertions, 25 deletions
diff --git a/libbb/wfopen.c b/libbb/wfopen.c index 4c84b3ba9..1cb871ef5 100644 --- a/libbb/wfopen.c +++ b/libbb/wfopen.c | |||
@@ -14,7 +14,7 @@ FILE* FAST_FUNC fopen_or_warn(const char *path, const char *mode) | |||
14 | FILE *fp = fopen(path, mode); | 14 | FILE *fp = fopen(path, mode); |
15 | if (!fp) { | 15 | if (!fp) { |
16 | bb_simple_perror_msg(path); | 16 | bb_simple_perror_msg(path); |
17 | errno = 0; | 17 | //errno = 0; /* why? */ |
18 | } | 18 | } |
19 | return fp; | 19 | return fp; |
20 | } | 20 | } |
diff --git a/shell/hush.c b/shell/hush.c index 3cf651b33..bad2c8044 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -5457,17 +5457,16 @@ static int builtin_eval(char **argv) | |||
5457 | 5457 | ||
5458 | static int builtin_cd(char **argv) | 5458 | static int builtin_cd(char **argv) |
5459 | { | 5459 | { |
5460 | const char *newdir; | 5460 | const char *newdir = argv[1]; |
5461 | if (*++argv == NULL) { | 5461 | if (newdir == NULL) { |
5462 | /* bash does nothing (exitcode 0) if HOME is ""; if it's unset, | 5462 | /* bash does nothing (exitcode 0) if HOME is ""; if it's unset, |
5463 | * bash says "bash: cd: HOME not set" and does nothing (exitcode 1) | 5463 | * bash says "bash: cd: HOME not set" and does nothing (exitcode 1) |
5464 | */ | 5464 | */ |
5465 | newdir = getenv("HOME") ? : "/"; | 5465 | newdir = getenv("HOME") ? : "/"; |
5466 | } else { | ||
5467 | newdir = *argv; | ||
5468 | } | 5466 | } |
5469 | if (chdir(newdir)) { | 5467 | if (chdir(newdir)) { |
5470 | printf("cd: %s: %s\n", newdir, strerror(errno)); | 5468 | /* Mimic bash message exactly */ |
5469 | bb_perror_msg("cd: %s", newdir); | ||
5471 | return EXIT_FAILURE; | 5470 | return EXIT_FAILURE; |
5472 | } | 5471 | } |
5473 | set_cwd(); | 5472 | set_cwd(); |
@@ -5763,18 +5762,19 @@ static int builtin_source(char **argv) | |||
5763 | { | 5762 | { |
5764 | FILE *input; | 5763 | FILE *input; |
5765 | 5764 | ||
5766 | if (argv[1] == NULL) | 5765 | if (*++argv == NULL) |
5767 | return EXIT_FAILURE; | 5766 | return EXIT_FAILURE; |
5768 | 5767 | ||
5769 | /* XXX search through $PATH is missing */ | 5768 | /* XXX search through $PATH is missing */ |
5770 | input = fopen_for_read(argv[1]); | 5769 | input = fopen_or_warn(*argv, "r"); |
5771 | if (!input) { | 5770 | if (!input) { |
5772 | bb_error_msg("can't open '%s'", argv[1]); | 5771 | /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ |
5773 | return EXIT_FAILURE; | 5772 | return EXIT_FAILURE; |
5774 | } | 5773 | } |
5775 | close_on_exec_on(fileno(input)); | 5774 | close_on_exec_on(fileno(input)); |
5776 | 5775 | ||
5777 | /* Now run the file */ | 5776 | /* Now run the file */ |
5777 | //TODO: | ||
5778 | /* XXX argv and argc are broken; need to save old G.global_argv | 5778 | /* XXX argv and argc are broken; need to save old G.global_argv |
5779 | * (pointer only is OK!) on this stack frame, | 5779 | * (pointer only is OK!) on this stack frame, |
5780 | * set G.global_argv=argv+1, recurse, and restore. */ | 5780 | * set G.global_argv=argv+1, recurse, and restore. */ |
@@ -5788,12 +5788,18 @@ static int builtin_umask(char **argv) | |||
5788 | mode_t new_umask; | 5788 | mode_t new_umask; |
5789 | const char *arg = argv[1]; | 5789 | const char *arg = argv[1]; |
5790 | if (arg) { | 5790 | if (arg) { |
5791 | //TODO: umask may take chmod-like symbolic masks | ||
5791 | new_umask = bb_strtou(arg, NULL, 8); | 5792 | new_umask = bb_strtou(arg, NULL, 8); |
5792 | if (errno) | 5793 | if (errno) { |
5794 | //Message? bash examples: | ||
5795 | //bash: umask: 'q': invalid symbolic mode operator | ||
5796 | //bash: umask: 999: octal number out of range | ||
5793 | return EXIT_FAILURE; | 5797 | return EXIT_FAILURE; |
5798 | } | ||
5794 | } else { | 5799 | } else { |
5795 | new_umask = umask(0); | 5800 | new_umask = umask(0); |
5796 | printf("%.3o\n", (unsigned) new_umask); | 5801 | printf("%.3o\n", (unsigned) new_umask); |
5802 | /* fall through and restore new_umask which we set to 0 */ | ||
5797 | } | 5803 | } |
5798 | umask(new_umask); | 5804 | umask(new_umask); |
5799 | return EXIT_SUCCESS; | 5805 | return EXIT_SUCCESS; |
@@ -5802,35 +5808,43 @@ static int builtin_umask(char **argv) | |||
5802 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */ | 5808 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */ |
5803 | static int builtin_unset(char **argv) | 5809 | static int builtin_unset(char **argv) |
5804 | { | 5810 | { |
5805 | size_t i; | ||
5806 | int ret; | 5811 | int ret; |
5807 | bool var = true; | 5812 | char var; |
5808 | 5813 | ||
5809 | if (!argv[1]) | 5814 | if (!*++argv) |
5810 | return EXIT_SUCCESS; | 5815 | return EXIT_SUCCESS; |
5811 | 5816 | ||
5812 | i = 0; | 5817 | var = 'v'; |
5813 | if (argv[1][0] == '-') { | 5818 | if (argv[0][0] == '-') { |
5814 | switch (argv[1][1]) { | 5819 | switch (argv[0][1]) { |
5815 | case 'v': break; | 5820 | case 'v': |
5816 | case 'f': if (ENABLE_HUSH_FUNCTIONS) { var = false; break; } | 5821 | case 'f': |
5822 | var = argv[0][1]; | ||
5823 | break; | ||
5817 | default: | 5824 | default: |
5818 | bb_error_msg("unset: %s: invalid option", argv[1]); | 5825 | bb_error_msg("unset: %s: invalid option", *argv); |
5819 | return EXIT_FAILURE; | 5826 | return EXIT_FAILURE; |
5820 | } | 5827 | } |
5821 | ++i; | 5828 | //TODO: disallow "unset -vf ..." too |
5829 | argv++; | ||
5822 | } | 5830 | } |
5823 | 5831 | ||
5824 | ret = EXIT_SUCCESS; | 5832 | ret = EXIT_SUCCESS; |
5825 | while (argv[++i]) { | 5833 | while (*argv) { |
5826 | if (var) { | 5834 | if (var == 'v') { |
5827 | if (unset_local_var(argv[i])) | 5835 | if (unset_local_var(*argv)) { |
5836 | /* unset <nonexistent_var> doesn't fail. | ||
5837 | * Error is when one tries to unset RO var. | ||
5838 | * Message was printed by unset_local_var. */ | ||
5828 | ret = EXIT_FAILURE; | 5839 | ret = EXIT_FAILURE; |
5840 | } | ||
5829 | } | 5841 | } |
5830 | #if ENABLE_HUSH_FUNCTIONS | 5842 | #if ENABLE_HUSH_FUNCTIONS |
5831 | else | 5843 | else { |
5832 | unset_local_func(argv[i]); | 5844 | unset_local_func(*argv); |
5845 | } | ||
5833 | #endif | 5846 | #endif |
5847 | argv++; | ||
5834 | } | 5848 | } |
5835 | return ret; | 5849 | return ret; |
5836 | } | 5850 | } |