tizen 2.3 release
[framework/system/deviced.git] / src / core / execute.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
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
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <limits.h>
24 #include <unistd.h>
25 #include <signal.h>
26 #include <errno.h>
27
28 #include "log.h"
29
30 static int parent(pid_t pid)
31 {
32         int status;
33
34         /* wait for child */
35         if (waitpid(pid, &status, 0) != -1) {
36                 /* terminated normally */
37                 if (WIFEXITED(status)) {
38                         _I("%d terminated by exit(%d)", pid, WEXITSTATUS(status));
39                         return WEXITSTATUS(status);
40                 } else if (WIFSIGNALED(status))
41                         _I("%d terminated by signal %d", pid, WTERMSIG(status));
42                 else if (WIFSTOPPED(status))
43                         _I("%d stopped by signal %d", pid, WSTOPSIG(status));
44         } else
45                 _I("%d waitpid() failed : %s", pid, strerror(errno));
46
47         return -EAGAIN;
48 }
49
50 static void child(int argc, const char *argv[])
51 {
52         int i, r;
53
54         for (i = 0; i < _NSIG; ++i)
55                 signal(i, SIG_DFL);
56
57         r = execv(argv[0], (char **)argv);
58         if (r < 0)
59                 exit(EXIT_FAILURE);
60 }
61
62 int run_child(int argc, const char *argv[])
63 {
64         pid_t pid;
65         struct sigaction act, oldact;
66         int r;
67         FILE *fp;
68
69         if (!argv)
70                 return -EINVAL;
71
72         fp = fopen(argv[0], "r");
73         if (fp == NULL) {
74                 _E("fail %s (%s)", argv[0], strerror(errno));
75                 return -errno;
76         }
77         fclose(fp);
78
79         /* Use default signal handler */
80         act.sa_handler = SIG_DFL;
81         act.sa_sigaction = NULL;
82         act.sa_flags = 0;
83         sigemptyset(&act.sa_mask);
84
85         if (sigaction(SIGCHLD, &act, &oldact) < 0)
86                 return -errno;
87
88         pid = fork();
89         if (pid < 0) {
90                 _E("failed to fork");
91                 r = -errno;
92         } else if (pid == 0) {
93                 child(argc, argv);
94         } else
95                 r = parent(pid);
96
97         if (sigaction(SIGCHLD, &oldact, NULL) < 0)
98                 _E("failed to restore sigaction");
99
100         return r;
101 }