Fix a few cppcheck errors (#4281)
[mono.git] / mono / metadata / w32process-unix-bsd.c
1
2 #include "w32process.h"
3 #include "w32process-unix-internals.h"
4
5 #ifdef USE_BSD_BACKEND
6
7 #include <errno.h>
8 #include <sys/proc.h>
9 #include <sys/sysctl.h>
10 #if !defined(__OpenBSD__)
11 #include <sys/utsname.h>
12 #endif
13 #if defined(__FreeBSD__)
14 #include <sys/user.h> /* struct kinfo_proc */
15 #endif
16
17 #include <link.h>
18
19 #include "utils/mono-logger-internals.h"
20
21 gchar*
22 mono_w32process_get_name (pid_t pid)
23 {
24         gint mib [6];
25         gsize size;
26         struct kinfo_proc *pi;
27         gchar *ret = NULL;
28
29 #if defined(__FreeBSD__)
30         mib [0] = CTL_KERN;
31         mib [1] = KERN_PROC;
32         mib [2] = KERN_PROC_PID;
33         mib [3] = pid;
34         if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) {
35                 mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sysctl() failed: %d", __func__, errno);
36                 return NULL;
37         }
38
39         if ((pi = g_malloc (size)) == NULL)
40                 return NULL;
41
42         if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) {
43                 if (errno == ENOMEM) {
44                         g_free (pi);
45                         mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't allocate enough memory for kproc info", __func__);
46                 }
47                 return NULL;
48         }
49
50         ret = strlen (pi->ki_comm) > 0 ? g_strdup (pi->ki_comm) : NULL;
51
52         g_free (pi);
53 #elif defined(__OpenBSD__)
54         mib [0] = CTL_KERN;
55         mib [1] = KERN_PROC;
56         mib [2] = KERN_PROC_PID;
57         mib [3] = pid;
58         mib [4] = sizeof(struct kinfo_proc);
59         mib [5] = 0;
60
61 retry:
62         if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) {
63                 mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sysctl() failed: %d", __func__, errno);
64                 return NULL;
65         }
66
67         if ((pi = g_malloc (size)) == NULL)
68                 return NULL;
69
70         mib[5] = (int)(size / sizeof(struct kinfo_proc));
71
72         if ((sysctl (mib, 6, pi, &size, NULL, 0) < 0) ||
73                 (size != sizeof (struct kinfo_proc))) {
74                 if (errno == ENOMEM) {
75                         g_free (pi);
76                         goto retry;
77                 }
78                 return NULL;
79         }
80
81         ret = strlen (pi->p_comm) > 0 ? g_strdup (pi->p_comm) : NULL;
82
83         g_free (pi);
84 #endif
85
86         return ret;
87 }
88
89 gchar*
90 mono_w32process_get_path (pid_t pid)
91 {
92         return mono_w32process_get_name (pid);
93 }
94
95 static gint
96 mono_w32process_get_modules_callback (struct dl_phdr_info *info, gsize size, gpointer ptr)
97 {
98         if (size < offsetof (struct dl_phdr_info, dlpi_phnum) + sizeof (info->dlpi_phnum))
99                 return (-1);
100
101         struct dl_phdr_info *cpy = g_calloc (1, sizeof(struct dl_phdr_info));
102         if (!cpy)
103                 return (-1);
104
105         memcpy(cpy, info, sizeof(*info));
106
107         g_ptr_array_add ((GPtrArray *)ptr, cpy);
108
109         return (0);
110 }
111
112 GSList*
113 mono_w32process_get_modules (pid_t pid)
114 {
115         GSList *ret = NULL;
116         MonoW32ProcessModule *mod;
117         GPtrArray *dlarray = g_ptr_array_new();
118         gint i;
119
120         if (dl_iterate_phdr (mono_w32process_get_modules_callback, dlarray) < 0)
121                 return NULL;
122
123         for (i = 0; i < dlarray->len; i++) {
124                 struct dl_phdr_info *info = g_ptr_array_index (dlarray, i);
125
126                 mod = g_new0 (MonoW32ProcessModule, 1);
127                 mod->address_start = (gpointer)(info->dlpi_addr + info->dlpi_phdr[0].p_vaddr);
128                 mod->address_end = (gpointer)(info->dlpi_addr + info->dlpi_phdr[info->dlpi_phnum - 1].p_vaddr);
129                 mod->perms = g_strdup ("r--p");
130                 mod->address_offset = 0;
131                 mod->inode = i;
132                 mod->filename = g_strdup (info->dlpi_name);
133
134                 mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: inode=%d, filename=%s, address_start=%p, address_end=%p",
135                         __func__, mod->inode, mod->filename, mod->address_start, mod->address_end);
136
137                 g_free (info);
138
139                 if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
140                         ret = g_slist_prepend (ret, mod);
141                 } else {
142                         mono_w32process_module_free (mod);
143                 }
144         }
145
146         g_ptr_array_free (dlarray, TRUE);
147
148         return g_slist_reverse (ret);
149 }
150
151 #endif