Fix roslyn install with AOT disabled.
[mono-project.git] / mono / metadata / w32process-unix-default.c
blob2bb37261ef65c85ce9001ab012c0deade9d52415
2 #include "w32process.h"
3 #include "w32process-unix-internals.h"
5 #ifdef USE_DEFAULT_BACKEND
7 #include <unistd.h>
9 #ifdef PLATFORM_SOLARIS
10 /* procfs.h cannot be included if this define is set, but it seems to work fine if it is undefined */
11 #if _FILE_OFFSET_BITS == 64
12 #undef _FILE_OFFSET_BITS
13 #include <procfs.h>
14 #define _FILE_OFFSET_BITS 64
15 #else
16 #include <procfs.h>
17 #endif
18 #endif
20 /* makedev() macro */
21 #ifdef MAJOR_IN_MKDEV
22 #include <sys/mkdev.h>
23 #elif defined MAJOR_IN_SYSMACROS
24 #include <sys/sysmacros.h>
25 #endif
27 #include "utils/mono-logger-internals.h"
29 #ifndef MAXPATHLEN
30 #define MAXPATHLEN 242
31 #endif
33 gchar*
34 mono_w32process_get_name (pid_t pid)
36 FILE *fp;
37 gchar *filename;
38 gchar buf[256];
39 gchar *ret = NULL;
41 #if defined(PLATFORM_SOLARIS)
42 filename = g_strdup_printf ("/proc/%d/psinfo", pid);
43 if ((fp = fopen (filename, "r")) != NULL) {
44 struct psinfo info;
45 int nread;
47 nread = fread (&info, sizeof (info), 1, fp);
48 if (nread == 1) {
49 ret = g_strdup (info.pr_fname);
52 fclose (fp);
54 g_free (filename);
55 #else
56 memset (buf, '\0', sizeof(buf));
57 filename = g_strdup_printf ("/proc/%d/exe", pid);
58 if (readlink (filename, buf, 255) > 0) {
59 ret = g_strdup (buf);
61 g_free (filename);
63 if (ret != NULL) {
64 return(ret);
67 filename = g_strdup_printf ("/proc/%d/cmdline", pid);
68 if ((fp = fopen (filename, "r")) != NULL) {
69 if (fgets (buf, 256, fp) != NULL) {
70 ret = g_strdup (buf);
73 fclose (fp);
75 g_free (filename);
77 if (ret != NULL) {
78 return(ret);
81 filename = g_strdup_printf ("/proc/%d/stat", pid);
82 if ((fp = fopen (filename, "r")) != NULL) {
83 if (fgets (buf, 256, fp) != NULL) {
84 char *start, *end;
86 start = strchr (buf, '(');
87 if (start != NULL) {
88 end = strchr (start + 1, ')');
90 if (end != NULL) {
91 ret = g_strndup (start + 1,
92 end - start - 1);
97 fclose (fp);
99 g_free (filename);
100 #endif
102 return ret;
105 gchar*
106 mono_w32process_get_path (pid_t pid)
108 return mono_w32process_get_name (pid);
111 static FILE *
112 open_process_map (int pid, const char *mode)
114 gint i;
115 const gchar *proc_path[] = {
116 "/proc/%d/maps", /* GNU/Linux */
117 "/proc/%d/map", /* FreeBSD */
118 NULL
121 for (i = 0; proc_path [i]; i++) {
122 gchar *filename;
123 FILE *fp;
125 filename = g_strdup_printf (proc_path[i], pid);
126 fp = fopen (filename, mode);
127 g_free (filename);
129 if (fp)
130 return fp;
133 return NULL;
137 GSList*
138 mono_w32process_get_modules (pid_t pid)
140 GSList *ret = NULL;
141 FILE *fp;
142 MonoW32ProcessModule *mod;
143 gchar buf[MAXPATHLEN + 1], *p, *endp;
144 gchar *start_start, *end_start, *prot_start, *offset_start;
145 gchar *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5];
146 gpointer address_start, address_end, address_offset;
147 guint32 maj_dev, min_dev;
148 guint64 inode;
149 guint64 device;
151 fp = open_process_map (pid, "r");
152 if (!fp)
153 return NULL;
155 while (fgets (buf, sizeof(buf), fp)) {
156 p = buf;
157 while (g_ascii_isspace (*p)) ++p;
158 start_start = p;
159 if (!g_ascii_isxdigit (*start_start)) {
160 continue;
162 address_start = (gpointer)strtoul (start_start, &endp, 16);
163 p = endp;
164 if (*p != '-') {
165 continue;
168 ++p;
169 end_start = p;
170 if (!g_ascii_isxdigit (*end_start)) {
171 continue;
173 address_end = (gpointer)strtoul (end_start, &endp, 16);
174 p = endp;
175 if (!g_ascii_isspace (*p)) {
176 continue;
179 while (g_ascii_isspace (*p)) ++p;
180 prot_start = p;
181 if (*prot_start != 'r' && *prot_start != '-') {
182 continue;
184 memcpy (prot_buf, prot_start, 4);
185 prot_buf[4] = '\0';
186 while (!g_ascii_isspace (*p)) ++p;
188 while (g_ascii_isspace (*p)) ++p;
189 offset_start = p;
190 if (!g_ascii_isxdigit (*offset_start)) {
191 continue;
193 address_offset = (gpointer)strtoul (offset_start, &endp, 16);
194 p = endp;
195 if (!g_ascii_isspace (*p)) {
196 continue;
199 while(g_ascii_isspace (*p)) ++p;
200 maj_dev_start = p;
201 if (!g_ascii_isxdigit (*maj_dev_start)) {
202 continue;
204 maj_dev = strtoul (maj_dev_start, &endp, 16);
205 p = endp;
206 if (*p != ':') {
207 continue;
210 ++p;
211 min_dev_start = p;
212 if (!g_ascii_isxdigit (*min_dev_start)) {
213 continue;
215 min_dev = strtoul (min_dev_start, &endp, 16);
216 p = endp;
217 if (!g_ascii_isspace (*p)) {
218 continue;
221 while (g_ascii_isspace (*p)) ++p;
222 inode_start = p;
223 if (!g_ascii_isxdigit (*inode_start)) {
224 continue;
226 inode = (guint64)strtol (inode_start, &endp, 10);
227 p = endp;
228 if (!g_ascii_isspace (*p)) {
229 continue;
232 device = makedev ((int)maj_dev, (int)min_dev);
233 if ((device == 0) && (inode == 0)) {
234 continue;
237 while(g_ascii_isspace (*p)) ++p;
238 /* p now points to the filename */
240 mod = g_new0 (MonoW32ProcessModule, 1);
241 mod->address_start = address_start;
242 mod->address_end = address_end;
243 mod->perms = g_strdup (prot_buf);
244 mod->address_offset = address_offset;
245 mod->device = device;
246 mod->inode = inode;
247 mod->filename = g_strdup (g_strstrip (p));
249 if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
250 ret = g_slist_prepend (ret, mod);
251 } else {
252 mono_w32process_module_free (mod);
256 ret = g_slist_reverse (ret);
258 fclose (fp);
260 return(ret);
263 #endif