mirror of
https://github.com/sheumann/hush.git
synced 2024-08-20 04:28:57 +00:00
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
This commit is contained in:
parent
b0a6478eef
commit
bfbc971f9f
@ -14,7 +14,7 @@ FILE* FAST_FUNC fopen_or_warn(const char *path, const char *mode)
|
|||||||
FILE *fp = fopen(path, mode);
|
FILE *fp = fopen(path, mode);
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
bb_simple_perror_msg(path);
|
bb_simple_perror_msg(path);
|
||||||
errno = 0;
|
//errno = 0; /* why? */
|
||||||
}
|
}
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
62
shell/hush.c
62
shell/hush.c
@ -5457,17 +5457,16 @@ static int builtin_eval(char **argv)
|
|||||||
|
|
||||||
static int builtin_cd(char **argv)
|
static int builtin_cd(char **argv)
|
||||||
{
|
{
|
||||||
const char *newdir;
|
const char *newdir = argv[1];
|
||||||
if (*++argv == NULL) {
|
if (newdir == NULL) {
|
||||||
/* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
|
/* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
|
||||||
* bash says "bash: cd: HOME not set" and does nothing (exitcode 1)
|
* bash says "bash: cd: HOME not set" and does nothing (exitcode 1)
|
||||||
*/
|
*/
|
||||||
newdir = getenv("HOME") ? : "/";
|
newdir = getenv("HOME") ? : "/";
|
||||||
} else {
|
|
||||||
newdir = *argv;
|
|
||||||
}
|
}
|
||||||
if (chdir(newdir)) {
|
if (chdir(newdir)) {
|
||||||
printf("cd: %s: %s\n", newdir, strerror(errno));
|
/* Mimic bash message exactly */
|
||||||
|
bb_perror_msg("cd: %s", newdir);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
set_cwd();
|
set_cwd();
|
||||||
@ -5763,18 +5762,19 @@ static int builtin_source(char **argv)
|
|||||||
{
|
{
|
||||||
FILE *input;
|
FILE *input;
|
||||||
|
|
||||||
if (argv[1] == NULL)
|
if (*++argv == NULL)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
/* XXX search through $PATH is missing */
|
/* XXX search through $PATH is missing */
|
||||||
input = fopen_for_read(argv[1]);
|
input = fopen_or_warn(*argv, "r");
|
||||||
if (!input) {
|
if (!input) {
|
||||||
bb_error_msg("can't open '%s'", argv[1]);
|
/* bb_perror_msg("%s", *argv); - done by fopen_or_warn */
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
close_on_exec_on(fileno(input));
|
close_on_exec_on(fileno(input));
|
||||||
|
|
||||||
/* Now run the file */
|
/* Now run the file */
|
||||||
|
//TODO:
|
||||||
/* XXX argv and argc are broken; need to save old G.global_argv
|
/* XXX argv and argc are broken; need to save old G.global_argv
|
||||||
* (pointer only is OK!) on this stack frame,
|
* (pointer only is OK!) on this stack frame,
|
||||||
* set G.global_argv=argv+1, recurse, and restore. */
|
* set G.global_argv=argv+1, recurse, and restore. */
|
||||||
@ -5788,12 +5788,18 @@ static int builtin_umask(char **argv)
|
|||||||
mode_t new_umask;
|
mode_t new_umask;
|
||||||
const char *arg = argv[1];
|
const char *arg = argv[1];
|
||||||
if (arg) {
|
if (arg) {
|
||||||
|
//TODO: umask may take chmod-like symbolic masks
|
||||||
new_umask = bb_strtou(arg, NULL, 8);
|
new_umask = bb_strtou(arg, NULL, 8);
|
||||||
if (errno)
|
if (errno) {
|
||||||
|
//Message? bash examples:
|
||||||
|
//bash: umask: 'q': invalid symbolic mode operator
|
||||||
|
//bash: umask: 999: octal number out of range
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
new_umask = umask(0);
|
new_umask = umask(0);
|
||||||
printf("%.3o\n", (unsigned) new_umask);
|
printf("%.3o\n", (unsigned) new_umask);
|
||||||
|
/* fall through and restore new_umask which we set to 0 */
|
||||||
}
|
}
|
||||||
umask(new_umask);
|
umask(new_umask);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
@ -5802,35 +5808,43 @@ static int builtin_umask(char **argv)
|
|||||||
/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
|
/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
|
||||||
static int builtin_unset(char **argv)
|
static int builtin_unset(char **argv)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
int ret;
|
int ret;
|
||||||
bool var = true;
|
char var;
|
||||||
|
|
||||||
if (!argv[1])
|
if (!*++argv)
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
i = 0;
|
var = 'v';
|
||||||
if (argv[1][0] == '-') {
|
if (argv[0][0] == '-') {
|
||||||
switch (argv[1][1]) {
|
switch (argv[0][1]) {
|
||||||
case 'v': break;
|
case 'v':
|
||||||
case 'f': if (ENABLE_HUSH_FUNCTIONS) { var = false; break; }
|
case 'f':
|
||||||
|
var = argv[0][1];
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
bb_error_msg("unset: %s: invalid option", argv[1]);
|
bb_error_msg("unset: %s: invalid option", *argv);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
++i;
|
//TODO: disallow "unset -vf ..." too
|
||||||
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = EXIT_SUCCESS;
|
ret = EXIT_SUCCESS;
|
||||||
while (argv[++i]) {
|
while (*argv) {
|
||||||
if (var) {
|
if (var == 'v') {
|
||||||
if (unset_local_var(argv[i]))
|
if (unset_local_var(*argv)) {
|
||||||
|
/* unset <nonexistent_var> doesn't fail.
|
||||||
|
* Error is when one tries to unset RO var.
|
||||||
|
* Message was printed by unset_local_var. */
|
||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if ENABLE_HUSH_FUNCTIONS
|
#if ENABLE_HUSH_FUNCTIONS
|
||||||
else
|
else {
|
||||||
unset_local_func(argv[i]);
|
unset_local_func(*argv);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
argv++;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user