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.
31 #include <sys/types.h>
38 #include "../common/debug.h"
40 #define BUFFER_SIZE 4096
42 static char g_buffer
[BUFFER_SIZE
];
46 procfs_get_process_file(
47 unsigned long long pid
,
48 const char * filename
,
49 char ** buffer_ptr_ptr
,
60 sprintf(g_buffer
, "/proc/%llu/%s", pid
, filename
);
62 fd
= open(g_buffer
, O_RDONLY
);
68 buffer_size
= BUFFER_SIZE
;
69 buffer_ptr
= malloc(buffer_size
);
70 if (buffer_ptr
== NULL
)
72 lash_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 lash_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
);
116 *buffer_ptr_ptr
= buffer_ptr
;
117 *size_ptr
= used_size
;
124 procfs_get_process_link(
125 unsigned long long pid
,
126 const char * filename
)
132 sprintf(g_buffer
, "/proc/%llu/%s", pid
, filename
);
134 fd
= open(g_buffer
, O_RDONLY
);
140 ret
= readlink(g_buffer
, g_buffer
, sizeof(g_buffer
));
144 buffer_ptr
= strdup(g_buffer
);
145 lash_debug("process %llu %s symlink points to \"%s\"", pid
, filename
, buffer_ptr
);
159 procfs_get_process_cmdline(
160 unsigned long long pid
,
171 if (!procfs_get_process_file(pid
, "cmdline", &cmdline_ptr
, &cmdline_size
))
177 temp_ptr
= cmdline_ptr
;
179 while (temp_ptr
- cmdline_ptr
< cmdline_size
)
189 assert(*(temp_ptr
- 1) == 0); /* the last nul char */
191 argv
= malloc((argc
+ 1) * sizeof(char *));
198 temp_ptr
= cmdline_ptr
;
200 for (i
= 0; i
< argc
; i
++)
202 assert(temp_ptr
- cmdline_ptr
< cmdline_size
);
204 argv
[i
] = strdup(temp_ptr
);
219 temp_ptr
+= strlen(temp_ptr
) + 1;
222 /* Make sure that the array is NULL terminated */
234 procfs_get_process_cwd(
235 unsigned long long pid
)
237 return procfs_get_process_link(pid
, "cwd");