aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-06 12:04:42 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-06 12:04:42 +0000
commitbfbc971f9f96861abd80b977fb86e2791541bea8 (patch)
tree7319cf070d58a3a27623432657cac8017be3cb9f
parentb0a6478eefe3894d16a15f8a23908135e7c97aa7 (diff)
downloadbusybox-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.c2
-rw-r--r--shell/hush.c62
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
5458static int builtin_cd(char **argv) 5458static 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 */
5803static int builtin_unset(char **argv) 5809static 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}