am b101f879: Merge "init: Implement \'exec\' command."
* commit 'b101f8795a3d3d1c1f5c403bafec93f3d90d0360': init: Implement 'exec' command.
This commit is contained in:
commit
cf5ddf5938
6 changed files with 74 additions and 4 deletions
|
|
@ -205,6 +205,68 @@ int do_exec(int nargs, char **args)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int do_execonce(int nargs, char **args)
|
||||||
|
{
|
||||||
|
pid_t child;
|
||||||
|
int child_status = 0;
|
||||||
|
static int already_done;
|
||||||
|
|
||||||
|
if (already_done) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
already_done = 1;
|
||||||
|
if (!(child = fork())) {
|
||||||
|
/*
|
||||||
|
* Child process.
|
||||||
|
*/
|
||||||
|
zap_stdio();
|
||||||
|
char *exec_args[100];
|
||||||
|
int i;
|
||||||
|
int num_process_args = nargs;
|
||||||
|
|
||||||
|
memset(exec_args, 0, sizeof(exec_args));
|
||||||
|
if (num_process_args > ARRAY_SIZE(exec_args) - 1) {
|
||||||
|
ERROR("exec called with %d args, limit is %d", num_process_args,
|
||||||
|
ARRAY_SIZE(exec_args) - 1);
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
for (i = 1; i < num_process_args; i++)
|
||||||
|
exec_args[i - 1] = args[i];
|
||||||
|
|
||||||
|
if (execv(exec_args[0], exec_args) == -1) {
|
||||||
|
ERROR("Failed to execv '%s' (%s)", exec_args[0], strerror(errno));
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
ERROR("Returned from execv()!");
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parent process.
|
||||||
|
*/
|
||||||
|
if (child == -1) {
|
||||||
|
ERROR("Fork failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TEMP_FAILURE_RETRY(waitpid(child, &child_status, 0)) == -1) {
|
||||||
|
ERROR("waitpid(): failed (%s)\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIFSIGNALED(child_status)) {
|
||||||
|
INFO("Child exited due to signal %d\n", WTERMSIG(child_status));
|
||||||
|
return -1;
|
||||||
|
} else if (WIFEXITED(child_status)) {
|
||||||
|
INFO("Child exited normally (exit code %d)\n", WEXITSTATUS(child_status));
|
||||||
|
return WEXITSTATUS(child_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
ERROR("Abnormal child process exit\n");
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int do_export(int nargs, char **args)
|
int do_export(int nargs, char **args)
|
||||||
{
|
{
|
||||||
return add_environment(args[1], args[2]);
|
return add_environment(args[1], args[2]);
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ int add_environment(const char *key, const char *val)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zap_stdio(void)
|
void zap_stdio(void)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
fd = open("/dev/null", O_RDWR);
|
fd = open("/dev/null", O_RDWR);
|
||||||
|
|
|
||||||
|
|
@ -149,5 +149,6 @@ void property_changed(const char *name, const char *value);
|
||||||
extern struct selabel_handle *sehandle;
|
extern struct selabel_handle *sehandle;
|
||||||
extern struct selabel_handle *sehandle_prop;
|
extern struct selabel_handle *sehandle_prop;
|
||||||
extern int selinux_reload_policy(void);
|
extern int selinux_reload_policy(void);
|
||||||
|
void zap_stdio(void);
|
||||||
|
|
||||||
#endif /* _INIT_INIT_H */
|
#endif /* _INIT_INIT_H */
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ static int lookup_keyword(const char *s)
|
||||||
case 'e':
|
case 'e':
|
||||||
if (!strcmp(s, "nable")) return K_enable;
|
if (!strcmp(s, "nable")) return K_enable;
|
||||||
if (!strcmp(s, "xec")) return K_exec;
|
if (!strcmp(s, "xec")) return K_exec;
|
||||||
|
if (!strcmp(s, "xeconce")) return K_execonce;
|
||||||
if (!strcmp(s, "xport")) return K_export;
|
if (!strcmp(s, "xport")) return K_export;
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ int do_class_reset(int nargs, char **args);
|
||||||
int do_domainname(int nargs, char **args);
|
int do_domainname(int nargs, char **args);
|
||||||
int do_enable(int nargs, char **args);
|
int do_enable(int nargs, char **args);
|
||||||
int do_exec(int nargs, char **args);
|
int do_exec(int nargs, char **args);
|
||||||
|
int do_execonce(int nargs, char **args);
|
||||||
int do_export(int nargs, char **args);
|
int do_export(int nargs, char **args);
|
||||||
int do_hostname(int nargs, char **args);
|
int do_hostname(int nargs, char **args);
|
||||||
int do_ifup(int nargs, char **args);
|
int do_ifup(int nargs, char **args);
|
||||||
|
|
@ -59,6 +60,7 @@ enum {
|
||||||
KEYWORD(domainname, COMMAND, 1, do_domainname)
|
KEYWORD(domainname, COMMAND, 1, do_domainname)
|
||||||
KEYWORD(enable, COMMAND, 1, do_enable)
|
KEYWORD(enable, COMMAND, 1, do_enable)
|
||||||
KEYWORD(exec, COMMAND, 1, do_exec)
|
KEYWORD(exec, COMMAND, 1, do_exec)
|
||||||
|
KEYWORD(execonce, COMMAND, 1, do_execonce)
|
||||||
KEYWORD(export, COMMAND, 2, do_export)
|
KEYWORD(export, COMMAND, 2, do_export)
|
||||||
KEYWORD(group, OPTION, 0, 0)
|
KEYWORD(group, OPTION, 0, 0)
|
||||||
KEYWORD(hostname, COMMAND, 1, do_hostname)
|
KEYWORD(hostname, COMMAND, 1, do_hostname)
|
||||||
|
|
|
||||||
|
|
@ -136,10 +136,14 @@ Commands
|
||||||
--------
|
--------
|
||||||
|
|
||||||
exec <path> [ <argument> ]*
|
exec <path> [ <argument> ]*
|
||||||
|
This command is not implemented.
|
||||||
|
|
||||||
|
execonce <path> [ <argument> ]*
|
||||||
Fork and execute a program (<path>). This will block until
|
Fork and execute a program (<path>). This will block until
|
||||||
the program completes execution. It is best to avoid exec
|
the program completes execution. This command can be run at most
|
||||||
as unlike the builtin commands, it runs the risk of getting
|
once during init's lifetime. Subsequent invocations are ignored.
|
||||||
init "stuck". (??? maybe there should be a timeout?)
|
It is best to avoid exec as unlike the builtin commands, it runs
|
||||||
|
the risk of getting init "stuck".
|
||||||
|
|
||||||
export <name> <value>
|
export <name> <value>
|
||||||
Set the environment variable <name> equal to <value> in the
|
Set the environment variable <name> equal to <value> in the
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue