1 /* ProcFS - pid.c - generators for PID-specific files */ 2 3 #include "inc.h" 4 5 #include <sys/mman.h> 6 #include <minix/vm.h> 7 8 static void pid_psinfo(int slot); 9 static void pid_cmdline(int slot); 10 static void pid_environ(int slot); 11 static void pid_map(int slot); 12 13 /* 14 * The files that are dynamically created in each PID directory. The data 15 * field contains each file's read function. Subdirectories are not yet 16 * supported. 17 */ 18 struct file pid_files[] = { 19 { "psinfo", REG_ALL_MODE, (data_t) pid_psinfo }, 20 { "cmdline", REG_ALL_MODE, (data_t) pid_cmdline }, 21 { "environ", REG_ALL_MODE, (data_t) pid_environ }, 22 { "map", REG_ALL_MODE, (data_t) pid_map }, 23 { NULL, 0, (data_t) NULL } 24 }; 25 26 /* 27 * Is the given slot a zombie process? 28 */ 29 static int 30 is_zombie(int slot) 31 { 32 33 return (slot >= NR_TASKS && 34 (proc_list[slot - NR_TASKS].mpl_flags & MPLF_ZOMBIE)); 35 } 36 37 /* 38 * Get MINIX3-specific process data for the process identified by the given 39 * kernel slot. Return OK or a negative error code. 40 */ 41 int 42 get_proc_data(pid_t pid, struct minix_proc_data * mpd) 43 { 44 int mib[4] = { CTL_MINIX, MINIX_PROC, PROC_DATA, pid }; 45 size_t oldlen; 46 47 oldlen = sizeof(*mpd); 48 if (__sysctl(mib, __arraycount(mib), mpd, &oldlen, NULL, 0) != 0) 49 return -errno; 50 51 return OK; 52 } 53 54 /* 55 * Print process information. This feature is now used only by mtop(1), and as 56 * a result, we only provide information that mtop(1) actually uses. In the 57 * future, this file may be extended with additional fields again. 58 */ 59 static void 60 pid_psinfo(int slot) 61 { 62 struct minix_proc_data mpd; 63 struct vm_usage_info vui; 64 pid_t pid; 65 uid_t uid; 66 char *p; 67 int task, type, state; 68 69 if ((pid = pid_from_slot(slot)) == 0) 70 return; 71 72 if (get_proc_data(pid, &mpd) != OK) 73 return; 74 75 task = (slot < NR_TASKS); 76 77 /* Get the type of the process. */ 78 if (task) 79 type = TYPE_TASK; 80 else if (mpd.mpd_flags & MPDF_SYSTEM) 81 type = TYPE_SYSTEM; 82 else 83 type = TYPE_USER; 84 85 /* 86 * Get the (rudimentary) state of the process. The zombie flag is also 87 * in the proc_list entry but it just may be set since we obtained that 88 * entry, in which case we'd end up with the wrong state here. 89 */ 90 if (mpd.mpd_flags & MPDF_ZOMBIE) 91 state = STATE_ZOMBIE; 92 else if (mpd.mpd_flags & MPDF_RUNNABLE) 93 state = STATE_RUN; 94 else if (mpd.mpd_flags & MPDF_STOPPED) 95 state = STATE_STOP; 96 else 97 state = STATE_SLEEP; 98 99 /* Get the process's effective user ID. */ 100 if (!task) 101 uid = proc_list[slot - NR_TASKS].mpl_uid; 102 else 103 uid = 0; 104 105 /* Get memory usage. We do not care if this fails. */ 106 memset(&vui, 0, sizeof(vui)); 107 if (!(mpd.mpd_flags & MPDF_ZOMBIE)) 108 (void)vm_info_usage(mpd.mpd_endpoint, &vui); 109 110 /* Spaces in the process name would mess up the output format. */ 111 if ((p = strchr(mpd.mpd_name, ' ')) != NULL) 112 *p = '\0'; 113 114 /* Print all the information. */ 115 buf_printf("%d %c %d %s %c %d %d %u %u " 116 "%"PRIu64" %"PRIu64" %"PRIu64" %lu %d %u\n", 117 PSINFO_VERSION, /* information version */ 118 type, /* process type */ 119 mpd.mpd_endpoint, /* process endpoint */ 120 mpd.mpd_name, /* process name */ 121 state, /* process state letter */ 122 mpd.mpd_blocked_on, /* endpt blocked on, or NONE */ 123 mpd.mpd_priority, /* process priority */ 124 mpd.mpd_user_time, /* user time */ 125 mpd.mpd_sys_time, /* system time */ 126 mpd.mpd_cycles, /* execution cycles */ 127 mpd.mpd_kipc_cycles, /* kernel IPC cycles */ 128 mpd.mpd_kcall_cycles, /* kernel call cycles */ 129 vui.vui_total, /* total memory */ 130 mpd.mpd_nice, /* nice value */ 131 uid /* effective user ID */ 132 ); 133 } 134 135 /* 136 * Dump the process's command line as it is contained in the process itself. 137 * Each argument is terminated with a null character. 138 */ 139 static void 140 pid_cmdline(int slot) 141 { 142 char buf[BUF_SIZE]; 143 int mib[] = { CTL_KERN, KERN_PROC_ARGS, 0, KERN_PROC_ARGV }; 144 size_t oldlen; 145 pid_t pid; 146 147 /* Kernel tasks and zombies have no memory. */ 148 if ((pid = pid_from_slot(slot)) <= 0 || is_zombie(slot)) 149 return; 150 151 mib[2] = proc_list[slot - NR_TASKS].mpl_pid; 152 153 /* TODO: zero-copy into the main output buffer */ 154 oldlen = sizeof(buf); 155 156 if (__sysctl(mib, __arraycount(mib), buf, &oldlen, NULL, 0) != 0) 157 return; 158 159 buf_append(buf, oldlen); 160 } 161 162 /* 163 * Dump the process's initial environment as it is contained in the process 164 * itself. Each entry is terminated with a null character. 165 */ 166 static void 167 pid_environ(int slot) 168 { 169 char buf[BUF_SIZE]; 170 int mib[] = { CTL_KERN, KERN_PROC_ARGS, 0, KERN_PROC_ENV }; 171 size_t oldlen; 172 pid_t pid; 173 174 /* Kernel tasks and zombies have no memory. */ 175 if ((pid = pid_from_slot(slot)) <= 0 || is_zombie(slot)) 176 return; 177 178 mib[2] = proc_list[slot - NR_TASKS].mpl_pid; 179 180 /* TODO: zero-copy into the main output buffer */ 181 oldlen = sizeof(buf); 182 183 if (__sysctl(mib, __arraycount(mib), buf, &oldlen, NULL, 0) != 0) 184 return; 185 186 buf_append(buf, oldlen); 187 } 188 189 /* 190 * Print the virtual memory regions of a process. 191 */ 192 static void 193 pid_map(int slot) 194 { 195 struct minix_proc_data mpd; 196 struct vm_region_info vri[MAX_VRI_COUNT]; 197 vir_bytes next; 198 pid_t pid; 199 int i, r, count; 200 201 /* Kernel tasks and zombies have no memory. */ 202 if ((pid = pid_from_slot(slot)) <= 0 || is_zombie(slot)) 203 return; 204 205 /* Get the process endpoint. */ 206 if (get_proc_data(pid, &mpd) != OK) 207 return; 208 209 count = 0; 210 next = 0; 211 212 do { 213 r = vm_info_region(mpd.mpd_endpoint, vri, MAX_VRI_COUNT, 214 &next); 215 216 if (r <= 0) 217 break; 218 219 for (i = 0; i < r; i++) { 220 buf_printf("%08lx-%08lx %c%c%c\n", 221 vri[i].vri_addr, 222 vri[i].vri_addr + vri[i].vri_length, 223 (vri[i].vri_prot & PROT_READ) ? 'r' : '-', 224 (vri[i].vri_prot & PROT_WRITE) ? 'w' : '-', 225 (vri[i].vri_prot & PROT_EXEC) ? 'x' : '-'); 226 227 count++; 228 } 229 } while (r == MAX_VRI_COUNT); 230 } 231