Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b101f879 authored by Elliott Hughes's avatar Elliott Hughes Committed by Gerrit Code Review
Browse files

Merge "init: Implement 'exec' command."

parents 46adfa69 429721c5
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -205,6 +205,68 @@ int do_exec(int nargs, char **args)
    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)
{
    return add_environment(args[1], args[2]);
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ int add_environment(const char *key, const char *val)
    return -1;
}

static void zap_stdio(void)
void zap_stdio(void)
{
    int fd;
    fd = open("/dev/null", O_RDWR);
+1 −0
Original line number Diff line number Diff line
@@ -149,5 +149,6 @@ void property_changed(const char *name, const char *value);
extern struct selabel_handle *sehandle;
extern struct selabel_handle *sehandle_prop;
extern int selinux_reload_policy(void);
void zap_stdio(void);

#endif	/* _INIT_INIT_H */
+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ static int lookup_keyword(const char *s)
    case 'e':
        if (!strcmp(s, "nable")) return K_enable;
        if (!strcmp(s, "xec")) return K_exec;
        if (!strcmp(s, "xeconce")) return K_execonce;
        if (!strcmp(s, "xport")) return K_export;
        break;
    case 'g':
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ int do_class_reset(int nargs, char **args);
int do_domainname(int nargs, char **args);
int do_enable(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_hostname(int nargs, char **args);
int do_ifup(int nargs, char **args);
@@ -59,6 +60,7 @@ enum {
    KEYWORD(domainname,  COMMAND, 1, do_domainname)
    KEYWORD(enable,      COMMAND, 1, do_enable)
    KEYWORD(exec,        COMMAND, 1, do_exec)
    KEYWORD(execonce,    COMMAND, 1, do_execonce)
    KEYWORD(export,      COMMAND, 2, do_export)
    KEYWORD(group,       OPTION,  0, 0)
    KEYWORD(hostname,    COMMAND, 1, do_hostname)
Loading