1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains the code that interfaces procfs
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <sys/types.h>
39 #define BUFFER_SIZE 4096
41 static char g_buffer
[BUFFER_SIZE
];
45 procfs_get_process_file(
46 unsigned long long pid
,
47 const char * filename
,
48 char ** buffer_ptr_ptr
,
59 sprintf(g_buffer
, "/proc/%llu/%s", pid
, filename
);
61 fd
= open(g_buffer
, O_RDONLY
);
67 buffer_size
= BUFFER_SIZE
;
68 buffer_ptr
= malloc(buffer_size
);
69 if (buffer_ptr
== NULL
)
71 log_error("malloc failed to allocate buffer with size %zu", buffer_size
);
76 read_ptr
= buffer_ptr
;
78 max
= buffer_size
- used_size
;
79 if (max
< BUFFER_SIZE
/ 4)
81 buffer_size
= used_size
+ BUFFER_SIZE
;
82 read_ptr
= realloc(buffer_ptr
, buffer_size
);
85 log_error("realloc failed to allocate buffer with size %zu", buffer_size
);
91 buffer_ptr
= read_ptr
;
92 read_ptr
= buffer_ptr
+ used_size
;
96 ret
= read(fd
, read_ptr
, max
);
102 ASSERT(used_size
<= buffer_size
);
115 if (used_size
== buffer_size
)
117 buffer_ptr
= realloc(buffer_ptr
, buffer_size
+ 1);
118 if (buffer_ptr
== NULL
)
120 log_error("realloc failed to allocate buffer with size %zu", buffer_size
+ 1);
126 buffer_ptr
[buffer_size
] = 0;
128 *buffer_ptr_ptr
= buffer_ptr
;
129 *size_ptr
= used_size
;
136 procfs_get_process_link(
137 unsigned long long pid
,
138 const char * filename
)
144 sprintf(g_buffer
, "/proc/%llu/%s", pid
, filename
);
146 fd
= open(g_buffer
, O_RDONLY
);
152 ret
= readlink(g_buffer
, g_buffer
, sizeof(g_buffer
));
156 buffer_ptr
= strdup(g_buffer
);
157 log_debug("process %llu %s symlink points to \"%s\"", pid
, filename
, buffer_ptr
);
171 procfs_get_process_cmdline(
172 unsigned long long pid
,
183 if (!procfs_get_process_file(pid
, "cmdline", &cmdline_ptr
, &cmdline_size
))
189 temp_ptr
= cmdline_ptr
;
191 while (temp_ptr
- cmdline_ptr
< cmdline_size
)
201 ASSERT(*(temp_ptr
- 1) == 0); /* the last nul char */
203 argv
= malloc((argc
+ 1) * sizeof(char *));
210 temp_ptr
= cmdline_ptr
;
212 for (i
= 0; i
< argc
; i
++)
214 ASSERT(temp_ptr
- cmdline_ptr
< cmdline_size
);
216 argv
[i
] = strdup(temp_ptr
);
231 temp_ptr
+= strlen(temp_ptr
) + 1;
234 /* Make sure that the array is NULL terminated */
246 procfs_get_process_cwd(
247 unsigned long long pid
)
249 return procfs_get_process_link(pid
, "cwd");
253 procfs_get_process_parent(
254 unsigned long long pid
)
260 unsigned long long ppid
;
262 if (!procfs_get_process_file(pid
, "status", &buffer_ptr
, &buffer_size
))
267 begin
= strstr(buffer_ptr
, "\nPPid:\t");
270 log_error("parent pid not parsed for %llu", pid
);
271 log_error("-----------------------------");
272 log_error("%s", buffer_ptr
);
273 log_error("-----------------------------");
280 end
= strchr(begin
, '\n');
283 log_error("parent pid not parsed for %llu (end)", pid
);
284 log_error("-----------------------------");
285 log_error("%s", buffer_ptr
);
286 log_error("-----------------------------");
292 //log_info("parent pid is %s", begin);
295 ppid
= strtoull(begin
, &end
, 10);
298 log_error("strtoull failed to convert '%s' to integer", begin
);
303 //log_info("parent pid is %llu", ppid);
306 /* avoid infinite cycles (should not happen because init has pid 1 and parent 0) */