Make cli_start_program handle arguments to scripts.

This commit is contained in:
Kristofer Hallin 2024-07-01 10:50:45 +00:00 committed by Olof Hagsand
parent 419e8312f9
commit 703114f64b

View file

@ -786,12 +786,15 @@ cli_set_mode(clixon_handle h,
* *
* Example usage: * Example usage:
* @code * @code
* run_program_err("Run program"), cli_start_program(); * python3_args("Run program"), cli_start_program("python3"); {
* run_program_python3("Run program"), cli_start_program("python3"); * <argument:string>("Single shell command"), cli_start_program("python3", "/tmp/test.py");
* run_program_python3_source_arg("Run program"), cli_start_program("python3", "/tmp/test.py"); * }
* run_program_python3_source_arg_vector("Run program") <source:rest>("Path program"), cli_start_program("python3"); *
* run_program_python3_source_arg_vector_err("Run program") <source:rest>("Path program"), cli_start_program("python3", "/tmp/test2.py"); * python3_single("Run program"), cli_start_program("python3"); {
* run_program_bash("Run program"), cli_start_program("bash"); * <source:rest>("Single shell command"), cli_start_program("python3");
* }
*
* python3_script("Run program") <source:rest>("Path program"), cli_start_program("python3");
* @endcode * @endcode
* *
* @warning Please note that the usage of this function consists of executing an arbitrary command given to * @warning Please note that the usage of this function consists of executing an arbitrary command given to
@ -808,98 +811,113 @@ cli_set_mode(clixon_handle h,
*/ */
int int
cli_start_program(clixon_handle h, cli_start_program(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int pid = 0; int pid = 0;
int retval = -1; int retval = -1;
char *script_path = NULL; int s = 0;
char *runner = NULL; int arg_count = 0;
char *buf = NULL; int cvv_count = 0;
char *work_dir = NULL, *reserve_path = NULL; int i = 0;
int status = 0;
char *script_path = NULL;
char *runner = NULL;
char *buf = NULL;
char *work_dir = NULL;
char *reserve_path = NULL;
char **args = NULL;
size_t bufsize = 0;
struct passwd pw, *pwresult = NULL; struct passwd pw, *pwresult = NULL;
size_t bufsize;
int s;
/* Check parameters */ /* Check parameters */
if (cvec_len(argv) == 0){ if (cvec_len(argv) == 0){
clixon_err(OE_PLUGIN, EINVAL, "Can not found argument in a function"); clixon_err(OE_PLUGIN, EINVAL, "Can not find argument");
goto done; goto done;
}
if ((cvec_len(argv) >= 2) && (cvec_len(cvv) >= 2)){
clixon_err(OE_PLUGIN, EINVAL, "A lot of arguments");
goto done;
}
if ((cvec_len(argv) == 2) && (cvec_len(cvv) == 2)){
clixon_err(OE_PLUGIN, EINVAL, "You cannot use 2 arguments in a function and 1 argument in a vector");
goto done;
} }
/* get data */ /* get data */
if (cvec_len(argv) == 1){ arg_count = cvec_len(argv);
runner = cv_string_get(cvec_i(argv, 0)); cvv_count = cvec_len(cvv);
}
if (cvec_len(argv) == 2){ runner = cv_string_get(cvec_i(argv, 0));
runner = cv_string_get(cvec_i(argv, 0));
script_path = cv_string_get(cvec_i(argv, 1)); if (arg_count > 1) {
} script_path = cv_string_get(cvec_i(argv, 1));
if (cvec_len(cvv) == 2){
script_path = cv_string_get(cvec_i(cvv, 1));
} }
if (script_path){ if (script_path){
reserve_path = strdup(script_path); reserve_path = strdup(script_path);
work_dir = dirname(reserve_path); work_dir = dirname(reserve_path);
} }
bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (bufsize == -1){ if (bufsize == -1){
bufsize = 16384; bufsize = 16384;
} }
buf = malloc(bufsize); buf = malloc(bufsize);
if (buf == NULL) { if (buf == NULL) {
perror("malloc"); perror("malloc");
goto done; goto done;
} }
s = getpwuid_r(getuid(), &pw, buf, bufsize, &pwresult); s = getpwuid_r(getuid(), &pw, buf, bufsize, &pwresult);
if (pwresult == NULL) { if (pwresult == NULL) {
if (s == 0) if (s == 0)
clixon_err(OE_PLUGIN, errno, "getpwuid_r"); clixon_err(OE_PLUGIN, errno, "getpwuid_r");
else else
perror("getpwuid_r"); perror("getpwuid_r");
goto done; goto done;
}
/* Prepare arguments for execlp */
args = malloc((arg_count + cvv_count) * sizeof(char *));
if (args == NULL) {
perror("malloc");
goto done;
}
for (i = 0; i < arg_count; i++) {
args[i] = cv_string_get(cvec_i(argv, i));
}
for (i = 0; i < cvv_count; i++) {
args[arg_count + i] = cv_string_get(cvec_i(cvv, i + 1));
} }
/* main run */ /* main run */
if ((pid = fork()) == 0) { if ((pid = fork()) == 0) {
/* child process */ /* child process */
if ((work_dir ? chdir(work_dir) : chdir(pw.pw_dir)) < 0) { if ((work_dir ? chdir(work_dir) : chdir(pw.pw_dir)) < 0) {
clixon_err(OE_PLUGIN, errno, "chdir"); clixon_err(OE_PLUGIN, errno, "chdir");
} }
execlp(runner, runner, script_path, NULL); execvp(runner, args);
clixon_err(OE_PLUGIN, errno, "Error run script"); clixon_err(OE_PLUGIN, errno, "Error running script");
return -1; goto done;
} }
else if(pid == -1){ else if(pid == -1){
clixon_err(OE_PLUGIN, errno, "fork"); clixon_err(OE_PLUGIN, errno, "fork");
} }
else{ else{
/* parent process */ /* parent process */
int status; if (waitpid(pid, &status, 0) != pid ){
if (waitpid(pid, &status, 0) != pid ){ clixon_err(OE_PLUGIN, errno, "waitpid error");
clixon_err(OE_PLUGIN, errno, "waitpid error"); goto done;
goto done; }
} else {
else { retval = WEXITSTATUS(status);
return WEXITSTATUS(status); goto done;
} }
} }
retval = 0;
done: done:
if(buf) if(buf)
free(buf); free(buf);
if(reserve_path) if(reserve_path)
free(reserve_path); free(reserve_path);
return retval; if(args)
free(args);
return retval;
} }
/*! Start bash from cli callback /*! Start bash from cli callback