@@ -48,7 +48,6 @@ static const char rcsid[] =
48
48
49
49
#include <sys/ucred.h>
50
50
#include <sys/user.h>
51
- #include <sys/sysctl.h>
52
51
#include <sys/cdefs.h>
53
52
54
53
#ifdef __APPLE__
@@ -71,6 +70,8 @@ static const char rcsid[] =
71
70
#include <vis.h>
72
71
#include <pwd.h>
73
72
73
+ #include <libgetargv.h>
74
+
74
75
#include "ps.h"
75
76
76
77
extern int mflg , print_all_thread , print_thread_num ;
@@ -115,9 +116,6 @@ static void
115
116
getproclline (KINFO * k , char * * command_name , int * argvlen , int * argv0len ,
116
117
int show_args )
117
118
{
118
- int mib [3 ], argmax , nargs , c = 0 ;
119
- size_t size ;
120
- char * procargs , * sp , * np , * cp ;
121
119
extern int eflg ;
122
120
123
121
/*
@@ -129,126 +127,16 @@ getproclline(KINFO *k, char **command_name, int *argvlen, int *argv0len,
129
127
return ;
130
128
}
131
129
132
- /* Get the maximum process arguments size. */
133
- mib [0 ] = CTL_KERN ;
134
- mib [1 ] = KERN_ARGMAX ;
135
-
136
- size = sizeof (argmax );
137
- if (sysctl (mib , 2 , & argmax , & size , NULL , 0 ) == -1 ) {
138
- goto ERROR_A ;
139
- }
140
-
141
- /* Allocate space for the arguments. */
142
- procargs = (char * )malloc (argmax );
143
- if (procargs == NULL ) {
130
+ struct ArgvEnvpResult result ;
131
+ if (!get_argv_and_envp_of_pid (KI_PROC (k )-> p_pid , & result )) {
144
132
goto ERROR_A ;
145
133
}
146
134
147
- /*
148
- * Make a sysctl() call to get the raw argument space of the process.
149
- * The layout is documented in start.s, which is part of the Csu
150
- * project. In summary, it looks like:
151
- *
152
- * /---------------\ 0x00000000
153
- * : :
154
- * : :
155
- * |---------------|
156
- * | argc |
157
- * |---------------|
158
- * | arg[0] |
159
- * |---------------|
160
- * : :
161
- * : :
162
- * |---------------|
163
- * | arg[argc - 1] |
164
- * |---------------|
165
- * | 0 |
166
- * |---------------|
167
- * | env[0] |
168
- * |---------------|
169
- * : :
170
- * : :
171
- * |---------------|
172
- * | env[n] |
173
- * |---------------|
174
- * | 0 |
175
- * |---------------| <-- Beginning of data returned by sysctl() is here.
176
- * | argc |
177
- * |---------------|
178
- * | exec_path |
179
- * |:::::::::::::::|
180
- * | |
181
- * | String area. |
182
- * | |
183
- * |---------------| <-- Top of stack.
184
- * : :
185
- * : :
186
- * \---------------/ 0xffffffff
187
- */
188
- mib [0 ] = CTL_KERN ;
189
- mib [1 ] = KERN_PROCARGS2 ;
190
- mib [2 ] = KI_PROC (k )-> p_pid ;
191
-
192
- size = (size_t )argmax ;
193
- if (sysctl (mib , 3 , procargs , & size , NULL , 0 ) == -1 ) {
194
- goto ERROR_B ;
195
- }
196
-
197
- memcpy (& nargs , procargs , sizeof (nargs ));
198
- cp = procargs + sizeof (nargs );
199
-
200
- /* Skip the saved exec_path. */
201
- for (; cp < & procargs [size ]; cp ++ ) {
202
- if (* cp == '\0' ) {
203
- /* End of exec_path reached. */
204
- break ;
205
- }
206
- }
207
- if (cp == & procargs [size ]) {
208
- goto ERROR_B ;
209
- }
210
-
211
- /* Skip trailing '\0' characters. */
212
- for (; cp < & procargs [size ]; cp ++ ) {
213
- if (* cp != '\0' ) {
214
- /* Beginning of first argument reached. */
215
- break ;
216
- }
217
- }
218
- if (cp == & procargs [size ]) {
219
- goto ERROR_B ;
220
- }
221
- /* Save where the argv[0] string starts. */
222
- sp = cp ;
223
-
224
- /*
225
- * Iterate through the '\0'-terminated strings and convert '\0' to ' '
226
- * until a string is found that has a '=' character in it (or there are
227
- * no more strings in procargs). There is no way to deterministically
228
- * know where the command arguments end and the environment strings
229
- * start, which is why the '=' character is searched for as a heuristic.
230
- */
231
- for (np = NULL ; c < nargs && cp < & procargs [size ]; cp ++ ) {
232
- if (* cp == '\0' ) {
233
- c ++ ;
234
- if (np != NULL ) {
235
- /* Convert previous '\0'. */
236
- * np = ' ' ;
237
- } else {
238
- * argv0len = cp - sp ;
239
- }
240
- /* Note location of current '\0'. */
241
- np = cp ;
242
-
243
- if (!show_args ) {
244
- /*
245
- * Don't convert '\0' characters to ' '.
246
- * However, we needed to know that the
247
- * command name was terminated, which we
248
- * now know.
249
- */
250
- break ;
251
- }
135
+ * argv0len = (result .argv [1 ] - result .argv [0 ]) - 1 ;
136
+ if (show_args ) {
137
+ //for every arg except the last one, convert the terminating NUL into a space
138
+ for (int c = 0 ; c < result .argc - 1 ; c ++ ) {
139
+ * (result .argv [c + 1 ] - 1 ) = ' ' ;
252
140
}
253
141
}
254
142
@@ -258,46 +146,18 @@ getproclline(KINFO *k, char **command_name, int *argvlen, int *argv0len,
258
146
* follow.
259
147
*/
260
148
if ( show_args && (eflg != 0 ) && ( (getuid () == 0 ) || (KI_EPROC (k )-> e_pcred .p_ruid == getuid ()) ) ) {
261
- for (; cp < & procargs [size ]; cp ++ ) {
262
- if (* cp == '\0' ) {
263
- if (np != NULL ) {
264
- if (& np [1 ] == cp ) {
265
- /*
266
- * Two '\0' characters in a row.
267
- * This should normally only
268
- * happen after all the strings
269
- * have been seen, but in any
270
- * case, stop parsing.
271
- */
272
- break ;
273
- }
274
- /* Convert previous '\0'. */
275
- * np = ' ' ;
276
- }
277
- /* Note location of current '\0'. */
278
- np = cp ;
279
- }
149
+ for (int c = 0 ; c < result .envc - 1 ; c ++ ) {
150
+ * (result .envp [c + 1 ] - 1 ) = ' ' ;
280
151
}
281
152
}
282
153
283
- /*
284
- * sp points to the beginning of the arguments/environment string, and
285
- * np should point to the '\0' terminator for the string.
286
- */
287
- if (np == NULL || np == sp ) {
288
- /* Empty or unterminated string. */
289
- goto ERROR_B ;
290
- }
291
-
292
154
/* Make a copy of the string. */
293
- * argvlen = asprintf (command_name , "%s" , sp );
155
+ * argvlen = asprintf (command_name , "%s" , result . argv [ 0 ] );
294
156
295
157
/* Clean up. */
296
- free ( procargs );
158
+ free_ArgvEnvpResult ( & result );
297
159
return ;
298
160
299
- ERROR_B :
300
- free (procargs );
301
161
ERROR_A :
302
162
* argv0len = * argvlen
303
163
= asprintf (command_name , "(%s)" , KI_PROC (k )-> p_comm );
0 commit comments