1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009,2010 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
);
77 read_ptr
= buffer_ptr
;
79 max
= buffer_size
- used_size
;
80 if (max
< BUFFER_SIZE
/ 4)
82 buffer_size
= used_size
+ BUFFER_SIZE
;
83 read_ptr
= realloc(buffer_ptr
, buffer_size
);
86 log_error("realloc failed to allocate buffer with size %zu", buffer_size
);
92 buffer_ptr
= read_ptr
;
93 read_ptr
= buffer_ptr
+ used_size
;
97 ret
= read(fd
, read_ptr
, max
);
103 ASSERT(used_size
<= buffer_size
);
115 if (used_size
== buffer_size
)
117 read_ptr
= realloc(buffer_ptr
, buffer_size
+ 1);
118 if (read_ptr
== NULL
)
120 log_error("realloc failed to allocate buffer with size %zu", buffer_size
+ 1);
125 buffer_ptr
= read_ptr
;
128 buffer_ptr
[used_size
] = 0;
130 *buffer_ptr_ptr
= buffer_ptr
;
131 *size_ptr
= used_size
;
138 procfs_get_process_link(
139 unsigned long long pid
,
140 const char * filename
)
146 sprintf(g_buffer
, "/proc/%llu/%s", pid
, filename
);
148 fd
= open(g_buffer
, O_RDONLY
);
154 ret
= readlink(g_buffer
, g_buffer
, sizeof(g_buffer
));
158 buffer_ptr
= strdup(g_buffer
);
159 log_debug("process %llu %s symlink points to \"%s\"", pid
, filename
, buffer_ptr
);
173 procfs_get_process_cmdline(
174 unsigned long long pid
,
185 if (!procfs_get_process_file(pid
, "cmdline", &cmdline_ptr
, &cmdline_size
))
191 temp_ptr
= cmdline_ptr
;
193 while (temp_ptr
- cmdline_ptr
< cmdline_size
)
203 ASSERT(*(temp_ptr
- 1) == 0); /* the last nul char */
205 argv
= malloc((argc
+ 1) * sizeof(char *));
212 temp_ptr
= cmdline_ptr
;
214 for (i
= 0; i
< argc
; i
++)
216 ASSERT(temp_ptr
- cmdline_ptr
< cmdline_size
);
218 argv
[i
] = strdup(temp_ptr
);
233 temp_ptr
+= strlen(temp_ptr
) + 1;
236 /* Make sure that the array is NULL terminated */
248 procfs_get_process_cwd(
249 unsigned long long pid
)
251 return procfs_get_process_link(pid
, "cwd");
255 procfs_get_process_parent(
256 unsigned long long pid
)
262 unsigned long long ppid
;
264 if (!procfs_get_process_file(pid
, "status", &buffer_ptr
, &buffer_size
))
269 begin
= strstr(buffer_ptr
, "\nPPid:\t");
272 log_error("parent pid not parsed for %llu", pid
);
273 log_error("-----------------------------");
274 log_error("%s", buffer_ptr
);
275 log_error("-----------------------------");
282 end
= strchr(begin
, '\n');
285 log_error("parent pid not parsed for %llu (end)", pid
);
286 log_error("-----------------------------");
287 log_error("%s", buffer_ptr
);
288 log_error("-----------------------------");
294 //log_info("parent pid is %s", begin);
297 ppid
= strtoull(begin
, &end
, 10);
300 log_error("strtoull failed to convert '%s' to integer", begin
);
305 //log_info("parent pid is %llu", ppid);
308 /* avoid infinite cycles (should not happen because init has pid 1 and parent 0) */