New command: ! (drop to shell)
Adds a new command, !, that drops to an interactive OS shell, or (optionally) executes specified commands using the OS shell. Signed-off-by: Tamas TEVESZ <ice@extreme.hu>
This commit is contained in:
parent
16a25f206a
commit
47065b685b
2
Makefile
2
Makefile
|
@ -56,7 +56,7 @@ ifeq ($(OS),Windows_NT)
|
||||||
|
|
||||||
ifneq ($(UNAME_O),Cygwin)
|
ifneq ($(UNAME_O),Cygwin)
|
||||||
OS_LIBS = -lws2_32 -lregex
|
OS_LIBS = -lws2_32 -lregex
|
||||||
OS_CFLAGS = -D__Windows__
|
OS_CFLAGS = -D__Windows__ -DNO_SHELLCMD
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
MSPDEBUG_CC = $(CC)
|
MSPDEBUG_CC = $(CC)
|
||||||
|
|
|
@ -211,6 +211,12 @@ Commands can be specified by giving the first few characters of the
|
||||||
command name, provided that the prefix is unambiguous. Some commands
|
command name, provided that the prefix is unambiguous. Some commands
|
||||||
support automatic repeat. For these commands, pressing enter at the
|
support automatic repeat. For these commands, pressing enter at the
|
||||||
reader prompt without typing anything will cause repeat execution.
|
reader prompt without typing anything will cause repeat execution.
|
||||||
|
.IP "\fB!\fR [\fIcommand\fR [\fIargs ...\fR]]"
|
||||||
|
Invoke an interactive operating system shell. If any arguments
|
||||||
|
are specified, the first one is taken as a command to execute, with the
|
||||||
|
rest of the arguments as the arguments to the command.
|
||||||
|
|
||||||
|
This command is not yet available on non-POSIX systems.
|
||||||
.IP "\fB=\fR \fIexpression\fR"
|
.IP "\fB=\fR \fIexpression\fR"
|
||||||
Evaluate an address expression and show both its value, and the result
|
Evaluate an address expression and show both its value, and the result
|
||||||
when the value is looked up in reverse in the current symbol
|
when the value is looked up in reverse in the current symbol
|
||||||
|
|
11
ui/cmddb.c
11
ui/cmddb.c
|
@ -354,7 +354,16 @@ const struct cmddb_record commands[] = {
|
||||||
" Write session data for the given session to a CSV file.\n"
|
" Write session data for the given session to a CSV file.\n"
|
||||||
"power profile\n"
|
"power profile\n"
|
||||||
" List power profile data by symbol.\n"
|
" List power profile data by symbol.\n"
|
||||||
}
|
},
|
||||||
|
#ifndef NO_SHELLCMD
|
||||||
|
{
|
||||||
|
.name = "!",
|
||||||
|
.func = cmd_shellcmd,
|
||||||
|
.help =
|
||||||
|
"! [command [args ...]]\n"
|
||||||
|
" Invoke an interactive shell, optionally execute command.\n"
|
||||||
|
},
|
||||||
|
#endif /* !NO_SHELLCMD */
|
||||||
};
|
};
|
||||||
|
|
||||||
int cmddb_get(const char *name, struct cmddb_record *ret)
|
int cmddb_get(const char *name, struct cmddb_record *ret)
|
||||||
|
|
71
ui/stdcmd.c
71
ui/stdcmd.c
|
@ -16,6 +16,15 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef NO_SHELLCMD
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "ctrlc.h"
|
||||||
|
#endif /* !NO_SHELLCMD */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -215,3 +224,65 @@ int cmd_exit(char **arg)
|
||||||
reader_exit();
|
reader_exit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_SHELLCMD
|
||||||
|
int cmd_shellcmd(char **arg)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
pid_t pid;
|
||||||
|
char *sh, *p;
|
||||||
|
static char *shell = NULL;
|
||||||
|
static char shell_name[16];
|
||||||
|
|
||||||
|
if (shell == NULL) {
|
||||||
|
sh = getenv("SHELL");
|
||||||
|
if (sh == NULL) {
|
||||||
|
sh = "/bin/sh";
|
||||||
|
}
|
||||||
|
|
||||||
|
shell = strdup(sh);
|
||||||
|
p = strdup(sh);
|
||||||
|
if (shell == NULL || p == NULL) {
|
||||||
|
pr_error("!: error: strdup");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(shell_name, 0, sizeof(shell_name));
|
||||||
|
*shell_name = '-';
|
||||||
|
strncpy(shell_name + 1, basename(p), sizeof(shell_name) - 2);
|
||||||
|
shell_name[sizeof(shell_name) - 1] = '\0';
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
|
||||||
|
if (pid == -1) {
|
||||||
|
pr_error("!: error: fork");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == 0) {
|
||||||
|
ctrlc_exit();
|
||||||
|
|
||||||
|
for (fd = 3; fd < 1024; fd++) {
|
||||||
|
(void)close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg && *arg[0]) {
|
||||||
|
execl(shell, shell_name, "-c", *arg, NULL);
|
||||||
|
} else {
|
||||||
|
execl(shell, shell_name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
printc_err("!: error: execl(\"%s\")", shell);
|
||||||
|
pr_error("");
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (waitpid(-1, NULL, 0) != pid) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* !NO_SHELLCMD */
|
||||||
|
|
|
@ -24,5 +24,8 @@ int cmd_help(char **arg);
|
||||||
int cmd_read(char **arg);
|
int cmd_read(char **arg);
|
||||||
int cmd_opt(char **arg);
|
int cmd_opt(char **arg);
|
||||||
int cmd_exit(char **arg);
|
int cmd_exit(char **arg);
|
||||||
|
#ifndef NO_SHELLCMD
|
||||||
|
int cmd_shellcmd(char **arg);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue