Mount USB storage
[platform/core/system/system-recovery.git] / src / system-recovery / process-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /*
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #define _POSIX_SOURCE
20
21 #include <errno.h>
22 #include <stdio.h>
23 #include <signal.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 #include <sys/wait.h>
29 #include <sys/types.h>
30
31 #include "process-util.h"
32 #include "system-recovery.h" /* For LOGD */
33
34 int process_exec(process_exec_type sync, char *argv[])
35 {
36         pid_t pid;
37         struct sigaction act, oldact;
38         int r = 0;
39
40         if (!argv)
41                 return -EINVAL;
42
43         /* Use default signal handler */
44         act.sa_handler = SIG_DFL;
45         act.sa_flags = 0;
46         sigemptyset(&act.sa_mask);
47
48         if (sigaction(SIGCHLD, &act, &oldact) < 0)
49                 return -errno;
50
51         pid = fork();
52         if (pid < 0) { /* Error */
53                 LOGD("Failed to fork\n");
54                 r = -errno;
55         } else if (!pid) { /* Child */
56                 int i;
57
58                 for (i = 0; i < _NSIG; i++)
59                         signal(i, SIG_DFL);
60
61                 r = execv(argv[0], (char **)argv);
62                 if (r < 0)
63                         exit(EXIT_FAILURE);
64         } else { /* Parent */
65                 int status;
66
67                 if (sync == PROCESS_NON_WAIT)
68                         return pid;
69
70                 /* Wait for child */
71                 if (waitpid(pid, &status, 0) != -1) {
72                         if (WIFEXITED(status)) { /* Terminated normally */
73                                 LOGD("%d terminated by exit(%d)\n", pid,
74                                                 WEXITSTATUS(status));
75                                 return WEXITSTATUS(status);
76                         } else if (WIFSIGNALED(status))
77                                 LOGD("%d terminated by signal %d\n", pid,
78                                                 WTERMSIG(status));
79                         else if (WIFSTOPPED(status))
80                                 LOGD("%d stopped by signal %d\n", pid,
81                                                 WSTOPSIG(status));
82                 } else
83                         LOGD("%d waitpid() failed - %d\n", pid, errno);
84         }
85
86         if (sigaction(SIGCHLD, &oldact, NULL) < 0)
87                 LOGD("failed to restore sigaction\n");
88
89         return r;
90 }