Get process status from procfs
[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 int proc_get_cmdline(pid_t pid, char *cmdline)
42 {
43         char buf[PROC_BUF_MAX];
44         char cmdline_buf[PROC_NAME_MAX];
45         char *filename;
46         FILE *fp;
47
48         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
49         fp = fopen(buf, "r");
50         if (fp == NULL)
51                 return STC_ERROR_FAIL;
52
53         if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) {
54                 fclose(fp);
55                 return STC_ERROR_FAIL;
56         }
57         fclose(fp);
58
59         filename = strrchr(cmdline_buf, '/');
60         if (filename == NULL)
61                 filename = cmdline_buf;
62         else
63                 filename = filename + 1;
64
65         strncpy(cmdline, filename, PROC_NAME_MAX-1);
66
67         return STC_ERROR_NONE;
68 }
69
70 pid_t find_pid_from_cmdline(char *cmdline)
71 {
72         pid_t pid = -1, foundpid = -1;
73         int ret = 0;
74         DIR *dp;
75         struct dirent *dentry;
76         char appname[PROC_NAME_MAX];
77
78         dp = opendir("/proc");
79         if (!dp) {
80                 STC_LOGE("BACKGRD MANAGE : fail to open /proc");
81                 return STC_ERROR_FAIL;
82         }
83
84         while ((dentry = readdir(dp)) != NULL) {
85                 if (!isdigit(dentry->d_name[0]))
86                         continue;
87
88                 pid = atoi(dentry->d_name);
89                 if (!pid)
90                         continue;
91                 ret = proc_get_cmdline(pid, appname);
92                 if (ret == STC_ERROR_NONE) {
93                         if (!strncmp(cmdline, appname, strlen(appname)+1)) {
94                                 foundpid = pid;
95                                 break;
96                         }
97                 }
98         }
99         closedir(dp);
100         return foundpid;
101 }
102
103 int proc_get_label(pid_t pid, char *label)
104 {
105         char buf[PROC_BUF_MAX];
106         FILE *fp;
107
108         snprintf(buf, sizeof(buf), "/proc/%d/attr/current", pid);
109         fp = fopen(buf, "r");
110         if (fp == NULL)
111                 return STC_ERROR_FAIL;
112
113         if (fgets(label, PROC_NAME_MAX-1, fp) == NULL) {
114                 fclose(fp);
115                 return STC_ERROR_FAIL;
116         }
117         fclose(fp);
118         return STC_ERROR_NONE;
119 }
120
121 int proc_get_exepath(pid_t pid, char *buf, int len)
122 {
123         char path[PROC_BUF_MAX];
124         int ret = 0;
125
126         snprintf(path, sizeof(path), "/proc/%d/exe", pid);
127         ret = readlink(path, buf, len-1);
128         if (ret > 0)
129                 buf[ret] = '\0';
130         else
131                 buf[0] = '\0';
132         return STC_ERROR_NONE;
133 }
134
135 static int proc_get_data(char *path, char *buf, int len)
136 {
137         _cleanup_close_ int fd = -1;
138         int ret;
139
140         fd = open(path, O_RDONLY);
141         if (fd < 0)
142                 return STC_ERROR_FAIL;
143
144         ret = read(fd, buf, len-1);
145         if (ret < 0) {
146                 buf[0] = '\0';
147                 return STC_ERROR_FAIL;
148         }
149         buf[ret] = '\0';
150         return STC_ERROR_NONE;
151 }
152
153 int proc_get_raw_cmdline(pid_t pid, char *buf, int len)
154 {
155         char path[PROC_BUF_MAX];
156         snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
157         return proc_get_data(path, buf, len);
158 }
159
160 int proc_get_status(pid_t pid, char status[][PROC_BUF_MAX])
161 {
162         unsigned int i;
163         char path[PROC_BUF_MAX];
164         char status_buf[PROC_BUF_MAX];
165         FILE *fp;
166
167         snprintf(path, sizeof(path), "/proc/%d/status", pid);
168         fp = fopen(path, "r");
169         if (fp == NULL)
170                 return STC_ERROR_FAIL;
171
172         for (i = 0; i < PROC_STATUS_CNT; ++i) {
173                 char *token = NULL;
174                 char *saveptr = NULL;
175
176                 if (fgets(status_buf, sizeof(status_buf), fp) == NULL) {
177                         fclose(fp);
178                         return STC_ERROR_FAIL;
179                 }
180
181                 token = strtok_r(status_buf, ":", &saveptr);
182                 if (token != NULL) {
183                         token = strtok_r(NULL, "\n", &saveptr);
184                         if (token != NULL) {
185                                 while (isspace((unsigned char)*token))
186                                         token++;
187                                 strncpy(status[i], token, sizeof(status[i]));
188                         }
189                 }
190         }
191         fclose(fp);
192
193         return STC_ERROR_NONE;
194 }