mirror of
https://github.com/tio/tio.git
synced 2026-05-01 14:57:59 +02:00
Add option '--exec <command>' for running shell command
Runs shell command with I/O redirected to device.
This commit is contained in:
parent
545d473220
commit
e75e19eb00
9 changed files with 89 additions and 10 deletions
|
|
@ -45,6 +45,7 @@ _tio()
|
|||
--script \
|
||||
--script-file \
|
||||
--script-run \
|
||||
--exec \
|
||||
-v --version \
|
||||
-h --help"
|
||||
|
||||
|
|
@ -179,6 +180,10 @@ _tio()
|
|||
COMPREPLY=( $(compgen -W "once always never" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
--exec)
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
-v | --version)
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ static void config_parse_keys(GKeyFile *key_file, char *group)
|
|||
g_free((void *)string);
|
||||
string = NULL;
|
||||
}
|
||||
config_get_string(key_file, group, "exec", &option.exec, NULL);
|
||||
config_get_string(key_file, group, "prefix-ctrl-key", &string, NULL);
|
||||
if (string != NULL)
|
||||
{
|
||||
|
|
|
|||
59
src/misc.c
59
src/misc.c
|
|
@ -33,6 +33,7 @@
|
|||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/wait.h>
|
||||
#include <termios.h>
|
||||
#include <fnmatch.h>
|
||||
#include "error.h"
|
||||
|
|
@ -199,3 +200,61 @@ bool match_patterns(const char *string, const char *patterns)
|
|||
free(patterns_copy);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Function that forks subprocess, redirects its stdin and stdout to the
|
||||
// specified filedescriptor, and runs command.
|
||||
int execute_shell_command(int fd, const char *command)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
// Fork a child process
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
{
|
||||
// Error occurred
|
||||
tio_error_print("fork() failed (%s)", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if (pid == 0)
|
||||
{
|
||||
// Child process
|
||||
|
||||
tio_printf("Executing shell command '%s'", command);
|
||||
|
||||
// Redirect stdout and stderr to the file descriptor
|
||||
if (dup2(fd, STDOUT_FILENO) == -1 || dup2(fd, STDERR_FILENO) == -1)
|
||||
{
|
||||
tio_error_print("dup2() failed (%s)", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Execute the shell command
|
||||
execl("/bin/sh", "sh", "-c", command, (char *)NULL);
|
||||
|
||||
// If execlp() returns, it means an error occurred
|
||||
perror("execlp");
|
||||
tio_error_print("execlp() failed (%s)", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parent process
|
||||
|
||||
// Wait for the child process to finish
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
tio_printf("Command exited with status %d", WEXITSTATUS(status));
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
else
|
||||
{
|
||||
tio_error_printf("Child process exited abnormally\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,3 +34,4 @@ char *base62_encode(unsigned long num);
|
|||
int read_poll(int fd, void *data, size_t len, int timeout);
|
||||
double get_current_time(void);
|
||||
bool match_patterns(const char *string, const char *patterns);
|
||||
int execute_shell_command(int fd, const char *command);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ enum opt_t
|
|||
OPT_EXCLUDE_DEVICES,
|
||||
OPT_EXCLUDE_DRIVERS,
|
||||
OPT_EXCLUDE_TIDS,
|
||||
OPT_EXEC,
|
||||
};
|
||||
|
||||
/* Default options */
|
||||
|
|
@ -121,6 +122,7 @@ struct option_t option =
|
|||
.exclude_tids = NULL,
|
||||
.hex_n_value = 0,
|
||||
.vt100 = false,
|
||||
.exec = NULL,
|
||||
};
|
||||
|
||||
void option_print_help(char *argv[])
|
||||
|
|
@ -167,6 +169,7 @@ void option_print_help(char *argv[])
|
|||
printf(" --script <string> Run script from string\n");
|
||||
printf(" --script-file <filename> Run script from file\n");
|
||||
printf(" --script-run once|always|never Run script on connect (default: always)\n");
|
||||
printf(" --exec <command> Execute shell command with I/O redirected to device\n");
|
||||
printf(" -v, --version Display version\n");
|
||||
printf(" -h, --help Display help\n");
|
||||
printf("\n");
|
||||
|
|
@ -815,6 +818,7 @@ void options_parse(int argc, char *argv[])
|
|||
{"script", required_argument, 0, OPT_SCRIPT },
|
||||
{"script-file", required_argument, 0, OPT_SCRIPT_FILE },
|
||||
{"script-run", required_argument, 0, OPT_SCRIPT_RUN },
|
||||
{"exec", required_argument, 0, OPT_EXEC },
|
||||
{"version", no_argument, 0, 'v' },
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{"complete-profiles", no_argument, 0, OPT_COMPLETE_PROFILES },
|
||||
|
|
@ -985,6 +989,10 @@ void options_parse(int argc, char *argv[])
|
|||
option_parse_script_run(optarg, &option.script_run);
|
||||
break;
|
||||
|
||||
case OPT_EXEC:
|
||||
option.exec = optarg;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
printf("tio v%s\n", VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ struct option_t
|
|||
char *exclude_tids;
|
||||
int hex_n_value;
|
||||
bool vt100;
|
||||
char *exec;
|
||||
};
|
||||
|
||||
extern struct option_t option;
|
||||
|
|
|
|||
|
|
@ -2277,6 +2277,12 @@ int tty_connect(void)
|
|||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (option.exec != NULL)
|
||||
{
|
||||
int status = execute_shell_command(device_fd, option.exec);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/* Input loop */
|
||||
while (true)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue