Tizen 2.0 Release
[framework/system/sync-agent.git] / src / framework / utility / sync_util.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23
24 #include "utility/sync_util.h"
25
26 #ifndef EXPORT_API
27 #define EXPORT_API __attribute__ ((visibility("default")))
28 #endif
29
30 #ifndef SYNC_AGENT_LOG
31 #undef LOG_TAG
32 #define LOG_TAG "AF_SYNC_UTIL"
33 #endif
34
35 EXPORT_API int sync_agent_daemonize(void)
36 {
37         _EXTERN_FUNC_ENTER;
38
39         pid_t pid, sid;
40
41         /* 1. if already a daemon running, return */
42         if (getppid() == 1) {
43                 _DEBUG_WARNING("daemon is already running");
44                 _EXTERN_FUNC_EXIT;
45                 return 0;
46         }
47
48         /* 2. Fork off the parent process */
49         pid = fork();
50
51         if (pid < 0) {          // if error
52                 _DEBUG_ERROR("fork() error");
53                 _EXTERN_FUNC_EXIT;
54                 return -1;
55         }
56         /* If we got a good PID, then we can exit the parent process,
57          * so that PPID can be the one of init process(1).
58          */
59         if (pid > 0) {          // if parent process
60                 exit(0);
61         }
62
63         /* At this point we are executing as the child process */
64
65         /* 3. Change the file mode mask (022 : permission = 644) */
66         umask(022);
67
68         /* 4. Create a new SID for the child process,
69          * so that PGID can be the one of PID of child process.
70          */
71         sid = setsid();
72         if (sid < 0) {
73                 _DEBUG_ERROR("setsid() error");
74                 _EXTERN_FUNC_EXIT;
75                 return -1;
76         }
77
78         /* 5. Change the current working directory.
79          * This prevents the current directory from being locked; hence not being able to remove it.
80          */
81         if ((chdir("/")) < 0) {
82                 _DEBUG_ERROR("chdir() error");
83                 _EXTERN_FUNC_EXIT;
84                 return -1;
85         }
86
87         /* 6. Redirect standard files to /dev/null */
88         FILE *fp;
89         fp = freopen("/dev/null", "r", stdin);
90         if (fp == NULL) {
91                 _DEBUG_ERROR("freopen() error");
92         }
93         fp = freopen("/dev/null", "w", stdout);
94         if (fp == NULL) {
95                 _DEBUG_ERROR("freopen() error");
96         }
97         fp = freopen("/dev/null", "w", stderr);
98         if (fp == NULL) {
99                 _DEBUG_ERROR("freopen() error");
100         }
101
102         _EXTERN_FUNC_EXIT;
103
104         return 0;
105 }