[runtime] Rename most System.Reflection.MonoX classes to RuntimeX for consistency...
[mono-project.git] / mono / metadata / w32process-unix-osx.c
blobf51e9c0799488dbec2c3f601ca95ea4f789d4d85
1 /**
2 * \file
3 */
5 #include "w32process.h"
6 #include "w32process-unix-internals.h"
8 #ifdef USE_OSX_BACKEND
10 #include <errno.h>
11 #include <unistd.h>
12 #include <sys/time.h>
13 #include <sys/proc.h>
14 #include <sys/sysctl.h>
15 #include <sys/utsname.h>
16 #include <mach-o/dyld.h>
17 #include <mach-o/getsect.h>
19 /* sys/resource.h (for rusage) is required when using osx 10.3 (but not 10.4) */
20 #ifdef __APPLE__
21 #include <TargetConditionals.h>
22 #include <sys/resource.h>
23 #ifdef HAVE_LIBPROC_H
24 /* proc_name */
25 #include <libproc.h>
26 #endif
27 #endif
29 #include "utils/mono-logger-internals.h"
30 #include "icall-decl.h"
32 gchar*
33 mono_w32process_get_name (pid_t pid)
35 gchar *ret = NULL;
37 #if defined (__mono_ppc__) || !defined (TARGET_OSX)
38 size_t size;
39 struct kinfo_proc *pi;
40 gint mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
42 if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0)
43 return(ret);
45 if ((pi = g_malloc (size)) == NULL)
46 return(ret);
48 if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) {
49 if (errno == ENOMEM) {
50 g_free (pi);
51 mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: Didn't allocate enough memory for kproc info", __func__);
53 return(ret);
56 if (strlen (pi->kp_proc.p_comm) > 0)
57 ret = g_strdup (pi->kp_proc.p_comm);
59 g_free (pi);
60 #else
61 gchar buf[256];
62 gint res;
64 /* No proc name on OSX < 10.5 nor ppc nor iOS */
65 memset (buf, '\0', sizeof(buf));
66 res = proc_name (pid, buf, sizeof(buf));
67 if (res == 0) {
68 mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: proc_name failed, error (%d) \"%s\"", __func__, errno, g_strerror (errno));
69 return NULL;
72 // Fixes proc_name triming values to 15 characters #32539
73 if (strlen (buf) >= MAXCOMLEN - 1) {
74 gchar path_buf [PROC_PIDPATHINFO_MAXSIZE];
75 gchar *name_buf;
76 gint path_len;
78 memset (path_buf, '\0', sizeof(path_buf));
79 path_len = proc_pidpath (pid, path_buf, sizeof(path_buf));
81 if (path_len > 0 && path_len < sizeof(path_buf)) {
82 name_buf = path_buf + path_len;
83 for(;name_buf > path_buf; name_buf--) {
84 if (name_buf [0] == '/') {
85 name_buf++;
86 break;
90 if (memcmp (buf, name_buf, MAXCOMLEN - 1) == 0)
91 ret = g_strdup (name_buf);
95 if (ret == NULL && strlen (buf) > 0)
96 ret = g_strdup (buf);
97 #endif
99 return ret;
102 gchar*
103 mono_w32process_get_path (pid_t pid)
105 #if defined(__mono_ppc__) || !defined(TARGET_OSX)
106 return mono_w32process_get_name (pid);
107 #else
108 gchar buf [PROC_PIDPATHINFO_MAXSIZE];
109 gint res;
111 res = proc_pidpath (pid, buf, sizeof (buf));
112 if (res <= 0)
113 return NULL;
114 if (buf [0] == '\0')
115 return NULL;
116 return g_strdup (buf);
117 #endif
120 GSList*
121 mono_w32process_get_modules (pid_t pid)
123 GSList *ret = NULL;
124 MonoW32ProcessModule *mod;
125 guint32 count;
126 int i = 0;
128 if (pid != getpid ())
129 return NULL;
131 count = _dyld_image_count ();
132 for (i = 0; i < count; i++) {
133 #if SIZEOF_VOID_P == 8
134 const struct mach_header_64 *hdr;
135 const struct section_64 *sec;
136 #else
137 const struct mach_header *hdr;
138 const struct section *sec;
139 #endif
140 const char *name;
142 name = _dyld_get_image_name (i);
143 #if SIZEOF_VOID_P == 8
144 hdr = (const struct mach_header_64*)_dyld_get_image_header (i);
145 sec = getsectbynamefromheader_64 (hdr, SEG_DATA, SECT_DATA);
146 #else
147 hdr = _dyld_get_image_header (i);
148 sec = getsectbynamefromheader (hdr, SEG_DATA, SECT_DATA);
149 #endif
151 /* Some dynlibs do not have data sections on osx (#533893) */
152 if (sec == 0)
153 continue;
155 mod = g_new0 (MonoW32ProcessModule, 1);
156 mod->address_start = GINT_TO_POINTER (sec->addr);
157 mod->address_end = GINT_TO_POINTER (sec->addr+sec->size);
158 mod->perms = g_strdup ("r--p");
159 mod->address_offset = 0;
160 mod->device = makedev (0, 0);
161 mod->inode = i;
162 mod->filename = g_strdup (name);
164 if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
165 ret = g_slist_prepend (ret, mod);
166 } else {
167 mono_w32process_module_free (mod);
171 return g_slist_reverse (ret);
174 #endif