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);
125 buffer_ptr
[buffer_size
] = 0;
127 *buffer_ptr_ptr
= buffer_ptr
;
128 *size_ptr
= used_size
;
135 procfs_get_process_link(
136 unsigned long long pid
,
137 const char * filename
)
143 sprintf(g_buffer
, "/proc/%llu/%s", pid
, filename
);
145 fd
= open(g_buffer
, O_RDONLY
);
151 ret
= readlink(g_buffer
, g_buffer
, sizeof(g_buffer
));
155 buffer_ptr
= strdup(g_buffer
);
156 log_debug("process %llu %s symlink points to \"%s\"", pid
, filename
, buffer_ptr
);
170 procfs_get_process_cmdline(
171 unsigned long long pid
,
182 if (!procfs_get_process_file(pid
, "cmdline", &cmdline_ptr
, &cmdline_size
))
188 temp_ptr
= cmdline_ptr
;
190 while (temp_ptr
- cmdline_ptr
< cmdline_size
)
200 ASSERT(*(temp_ptr
- 1) == 0); /* the last nul char */
202 argv
= malloc((argc
+ 1) * sizeof(char *));
209 temp_ptr
= cmdline_ptr
;
211 for (i
= 0; i
< argc
; i
++)
213 ASSERT(temp_ptr
- cmdline_ptr
< cmdline_size
);
215 argv
[i
] = strdup(temp_ptr
);
230 temp_ptr
+= strlen(temp_ptr
) + 1;
233 /* Make sure that the array is NULL terminated */
245 procfs_get_process_cwd(
246 unsigned long long pid
)
248 return procfs_get_process_link(pid
, "cwd");
252 procfs_get_process_parent(
253 unsigned long long pid
)
259 unsigned long long ppid
;
261 if (!procfs_get_process_file(pid
, "status", &buffer_ptr
, &buffer_size
))
266 begin
= strstr(buffer_ptr
, "\nPPid:\t");
269 log_error("parent pid not parsed for %llu", pid
);
270 log_error("-----------------------------");
271 log_error("%s", buffer_ptr
);
272 log_error("-----------------------------");
278 end
= strchr(begin
, '\n');
281 log_error("parent pid not parsed for %llu (end)", pid
);
282 log_error("-----------------------------");
283 log_error("%s", buffer_ptr
);
284 log_error("-----------------------------");
289 //log_info("parent pid is %s", begin);
292 ppid
= strtoull(begin
, &end
, 10);
295 log_error("strtoull failed to convert '%s' to integer", begin
);
300 //log_info("parent pid is %llu", ppid);
303 /* avoid infinite cycles (should not happen because init has pid 1 and parent 0) */