Moved procfs for app lifecycle to plugin and separate plugins
[platform/core/connectivity/stc-manager.git] / src / helper / helper-procfs.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 /**
19  * @file procfs.c
20  * @desc wrapper for reading profs information.
21  *
22  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
23  *
24  */
25
26 #include <ctype.h>
27 #include <stdio.h>
28 #include <stdbool.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <dirent.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36
37 #include "stc-error.h"
38 #include "stc-manager-util.h"
39 #include "helper-procfs.h"
40
41 #define USRAPPS "/usr/apps/"
42
43 API int proc_get_cmdline(pid_t pid, char *cmdline)
44 {
45         char buf[PROC_BUF_MAX];
46         char cmdline_buf[PROC_NAME_MAX];
47         char *filename;
48         FILE *fp;
49         char *token = NULL;
50         char *saveptr = NULL;
51
52         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
53         fp = fopen(buf, "r");
54         if (fp == NULL)
55                 return STC_ERROR_FAIL;
56
57         if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) {
58                 fclose(fp);
59                 return STC_ERROR_FAIL;
60         }
61         fclose(fp);
62
63         if (g_strstr_len(cmdline_buf, strlen(USRAPPS), USRAPPS) != NULL) {
64                 /* Application */
65                 filename = cmdline_buf + strlen(USRAPPS);
66                 token = strtok_r(filename, "/", &saveptr);
67                 if (token != NULL)
68                         filename = token;
69         } else {
70                 token = strtok_r(cmdline_buf, " ", &saveptr);
71                 if (token != NULL)
72                         filename = strrchr(token, '/');
73                 else
74                         filename = strrchr(cmdline_buf, '/');
75
76                 if (filename == NULL)
77                         filename = cmdline_buf;
78                 else
79                         filename = filename + 1;
80         }
81
82         strncpy(cmdline, filename, PROC_NAME_MAX-1);
83
84         return STC_ERROR_NONE;
85 }
86
87 pid_t find_pid_from_cmdline(char *cmdline)
88 {
89         pid_t pid = -1, foundpid = -1;
90         int ret = 0;
91         DIR *dp;
92         struct dirent *dentry;
93         char appname[PROC_NAME_MAX];
94
95         dp = opendir("/proc");
96         if (!dp) {
97                 STC_LOGE("BACKGRD MANAGE : fail to open /proc");
98                 return STC_ERROR_FAIL;
99         }
100
101         while ((dentry = readdir(dp)) != NULL) {
102                 if (!isdigit(dentry->d_name[0]))
103                         continue;
104
105                 pid = atoi(dentry->d_name);
106                 if (!pid)
107                         continue;
108                 ret = proc_get_cmdline(pid, appname);
109                 if (ret == STC_ERROR_NONE) {
110                         if (!strncmp(cmdline, appname, strlen(appname)+1)) {
111                                 foundpid = pid;
112                                 break;
113                         }
114                 }
115         }
116         closedir(dp);
117         return foundpid;
118 }
119
120 int proc_get_label(pid_t pid, char *label)
121 {
122         char buf[PROC_BUF_MAX];
123         FILE *fp;
124
125         snprintf(buf, sizeof(buf), "/proc/%d/attr/current", pid);
126         fp = fopen(buf, "r");
127         if (fp == NULL)
128                 return STC_ERROR_FAIL;
129
130         if (fgets(label, PROC_NAME_MAX-1, fp) == NULL) {
131                 fclose(fp);
132                 return STC_ERROR_FAIL;
133         }
134         fclose(fp);
135         return STC_ERROR_NONE;
136 }
137
138 int proc_get_exepath(pid_t pid, char *buf, int len)
139 {
140         char path[PROC_BUF_MAX];
141         int ret = 0;
142
143         snprintf(path, sizeof(path), "/proc/%d/exe", pid);
144         ret = readlink(path, buf, len-1);
145         if (ret > 0)
146                 buf[ret] = '\0';
147         else
148                 buf[0] = '\0';
149         return STC_ERROR_NONE;
150 }
151
152 static int proc_get_data(char *path, char *buf, int len)
153 {
154         _cleanup_close_ int fd = -1;
155         int ret;
156
157         fd = open(path, O_RDONLY);
158         if (fd < 0)
159                 return STC_ERROR_FAIL;
160
161         ret = read(fd, buf, len-1);
162         if (ret < 0) {
163                 buf[0] = '\0';
164                 return STC_ERROR_FAIL;
165         }
166         buf[ret] = '\0';
167         return STC_ERROR_NONE;
168 }
169
170 int proc_get_raw_cmdline(pid_t pid, char *buf, int len)
171 {
172         char path[PROC_BUF_MAX];
173         snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
174         return proc_get_data(path, buf, len);
175 }
176
177 API int proc_get_status(pid_t pid, char status[][PROC_BUF_MAX])
178 {
179         unsigned int i;
180         unsigned int index = 0;
181         char path[PROC_BUF_MAX];
182         char status_buf[PROC_BUF_MAX];
183         bool updated[PROC_STATUS_CNT] = {FALSE, };
184         FILE *fp;
185
186         snprintf(path, sizeof(path), "/proc/%d/status", pid);
187         fp = fopen(path, "r");
188         if (fp == NULL)
189                 return STC_ERROR_FAIL;
190
191         for (i = 0; i < PROC_STATUS_CNT; ++i) {
192                 char *token = NULL;
193                 char *saveptr = NULL;
194
195                 if (fgets(status_buf, sizeof(status_buf), fp) == NULL) {
196                         fclose(fp);
197                         return STC_ERROR_FAIL;
198                 }
199
200                 if (!updated[PROC_STATUS_NAME] && strstr(status_buf,
201                                                          PROC_STATUS_NAME_STR))
202                         index = PROC_STATUS_NAME;
203                 else if (!updated[PROC_STATUS_STATE] && strstr(status_buf,
204                                                                PROC_STATUS_STATE_STR))
205                         index = PROC_STATUS_STATE;
206                 else if (!updated[PROC_STATUS_TGID] && strstr(status_buf,
207                                                               PROC_STATUS_TGID_STR))
208                         index = PROC_STATUS_TGID;
209                 else if (!updated[PROC_STATUS_NGID] && strstr(status_buf,
210                                                               PROC_STATUS_NGID_STR))
211                         index = PROC_STATUS_NGID;
212                 else if (!updated[PROC_STATUS_PID] && strstr(status_buf,
213                                                              PROC_STATUS_PID_STR))
214                         index = PROC_STATUS_PID;
215                 else if (!updated[PROC_STATUS_PPID] && strstr(status_buf,
216                                                               PROC_STATUS_PPID_STR))
217                         index = PROC_STATUS_PPID;
218                 else if (!updated[PROC_STATUS_TRACERPID] && strstr(status_buf,
219                                                                    PROC_STATUS_TRACERPID_STR))
220                         index = PROC_STATUS_TRACERPID;
221                 else
222                         continue;
223
224                 token = strtok_r(status_buf, ":", &saveptr);
225                 if (token != NULL) {
226                         token = strtok_r(NULL, "\n", &saveptr);
227                         if (token != NULL) {
228                                 while (isspace((unsigned char)*token))
229                                         token++;
230                                 strncpy(status[index], token,
231                                         sizeof(status[index]));
232                                 updated[index] = TRUE;
233                         }
234                 }
235         }
236         fclose(fp);
237
238         return STC_ERROR_NONE;
239 }