@@ -64,29 +64,26 @@ void Process_fillStarttimeBuffer(Process* this) {
64
64
*/
65
65
#define TASK_COMM_LEN 16
66
66
67
- static bool findCommInCmdline (const char * comm , const char * cmdline , int cmdlineBasenameStart , int * pCommStart , int * pCommEnd ) {
67
+ static bool findCommInCmdline (const char * comm , const char * cmdline , size_t cmdlineBasenameStart , size_t * pCommStart , size_t * pCommLen ) {
68
68
/* Try to find procComm in tokenized cmdline - this might in rare cases
69
69
* mis-identify a string or fail, if comm or cmdline had been unsuitably
70
70
* modified by the process */
71
71
const char * tokenBase ;
72
72
size_t tokenLen ;
73
73
const size_t commLen = strlen (comm );
74
74
75
- if (cmdlineBasenameStart < 0 )
76
- return false;
77
-
78
75
for (const char * token = cmdline + cmdlineBasenameStart ; * token ;) {
79
76
for (tokenBase = token ; * token && * token != '\n' ; ++ token ) {
80
77
if (* token == '/' ) {
81
78
tokenBase = token + 1 ;
82
79
}
83
80
}
84
- tokenLen = token - tokenBase ;
81
+ tokenLen = ( size_t )( token - tokenBase ) ;
85
82
86
83
if ((tokenLen == commLen || (tokenLen > commLen && commLen == (TASK_COMM_LEN - 1 ))) &&
87
84
strncmp (tokenBase , comm , commLen ) == 0 ) {
88
- * pCommStart = tokenBase - cmdline ;
89
- * pCommEnd = token - cmdline ;
85
+ * pCommStart = ( size_t )( tokenBase - cmdline ) ;
86
+ * pCommLen = tokenLen ;
90
87
return true;
91
88
}
92
89
@@ -99,15 +96,12 @@ static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdline
99
96
return false;
100
97
}
101
98
102
- static int matchCmdlinePrefixWithExeSuffix (const char * cmdline , int cmdlineBaseOffset , const char * exe , int exeBaseOffset , int exeBaseLen ) {
103
- int matchLen ; /* matching length to be returned */
104
- char delim ; /* delimiter following basename */
105
-
99
+ static size_t matchCmdlinePrefixWithExeSuffix (const char * cmdline , size_t * cmdlineBasenameStart , const char * exe , size_t exeBaseOffset , size_t exeBaseLen ) {
106
100
/* cmdline prefix is an absolute path: it must match whole exe. */
107
101
if (cmdline [0 ] == '/' ) {
108
- matchLen = exeBaseLen + exeBaseOffset ;
102
+ size_t matchLen = exeBaseLen + exeBaseOffset ;
109
103
if (strncmp (cmdline , exe , matchLen ) == 0 ) {
110
- delim = cmdline [matchLen ];
104
+ char delim = cmdline [matchLen ];
111
105
if (delim == 0 || delim == '\n' || delim == ' ' ) {
112
106
return matchLen ;
113
107
}
@@ -121,35 +115,43 @@ static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int cmdlineBaseO
121
115
* that make htop's identification of the basename in cmdline unreliable.
122
116
* For e.g. /usr/libexec/gdm-session-worker modifies its cmdline to
123
117
* "gdm-session-worker [pam/gdm-autologin]" and htop ends up with
124
- * proccmdlineBasenameEnd at "gdm-autologin]". This issue could arise with
118
+ * cmdlineBasenameStart at "gdm-autologin]". This issue could arise with
125
119
* chrome as well as it stores in cmdline its concatenated argument vector,
126
120
* without NUL delimiter between the arguments (which may contain a '/')
127
121
*
128
122
* So if needed, we adjust cmdlineBaseOffset to the previous (if any)
129
123
* component of the cmdline relative path, and retry the procedure. */
130
- bool delimFound ; /* if valid basename delimiter found */
124
+ size_t cmdlineBaseOffset = * cmdlineBasenameStart ;
125
+ bool delimFound = true; /* if valid basename delimiter found */
131
126
do {
132
127
/* match basename */
133
- matchLen = exeBaseLen + cmdlineBaseOffset ;
128
+ size_t matchLen = exeBaseLen + cmdlineBaseOffset ;
134
129
if (cmdlineBaseOffset < exeBaseOffset &&
135
130
strncmp (cmdline + cmdlineBaseOffset , exe + exeBaseOffset , exeBaseLen ) == 0 ) {
136
- delim = cmdline [matchLen ];
131
+ char delim = cmdline [matchLen ];
137
132
if (delim == 0 || delim == '\n' || delim == ' ' ) {
138
- int i , j ;
139
133
/* reverse match the cmdline prefix and exe suffix */
140
- for (i = cmdlineBaseOffset - 1 , j = exeBaseOffset - 1 ;
141
- i >= 0 && j >= 0 && cmdline [i ] == exe [j ]; -- i , -- j )
142
- ;
134
+ size_t i = cmdlineBaseOffset ;
135
+ size_t j = exeBaseOffset ;
136
+ while (i >= 1 && j >= 1 && cmdline [i - 1 ] == exe [j - 1 ]) {
137
+ -- i , -- j ;
138
+ }
143
139
144
140
/* full match, with exe suffix being a valid relative path */
145
- if (i < 0 && j >= 0 && exe [j ] == '/' )
141
+ if (i < 1 && j >= 1 && exe [j - 1 ] == '/' ) {
142
+ * cmdlineBasenameStart = cmdlineBaseOffset ;
146
143
return matchLen ;
144
+ }
147
145
}
148
146
}
149
147
150
148
/* Try to find the previous potential cmdlineBaseOffset - it would be
151
149
* preceded by '/' or nothing, and delimited by ' ' or '\n' */
152
- for (delimFound = false, cmdlineBaseOffset -= 2 ; cmdlineBaseOffset > 0 ; -- cmdlineBaseOffset ) {
150
+ delimFound = false;
151
+ if (cmdlineBaseOffset <= 2 ) {
152
+ return 0 ;
153
+ }
154
+ for (cmdlineBaseOffset -= 2 ; cmdlineBaseOffset > 0 ; -- cmdlineBaseOffset ) {
153
155
if (delimFound ) {
154
156
if (cmdline [cmdlineBaseOffset - 1 ] == '/' ) {
155
157
break ;
@@ -309,17 +311,37 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
309
311
char * strStart = mc -> str ;
310
312
char * str = strStart ;
311
313
312
- int cmdlineBasenameStart = this -> cmdlineBasenameStart ;
313
- int cmdlineBasenameEnd = this -> cmdlineBasenameEnd ;
314
+ size_t cmdlineBasenameStart = this -> cmdlineBasenameStart ;
315
+ size_t cmdlineBasenameLen = 0 ;
316
+ if (this -> cmdlineBasenameEnd > this -> cmdlineBasenameStart )
317
+ cmdlineBasenameLen = this -> cmdlineBasenameEnd - this -> cmdlineBasenameStart ;
314
318
315
319
if (!cmdline ) {
316
320
cmdlineBasenameStart = 0 ;
317
- cmdlineBasenameEnd = 0 ;
321
+ cmdlineBasenameLen = 0 ;
318
322
cmdline = "(zombie)" ;
319
323
}
320
324
321
- assert (cmdlineBasenameStart >= 0 );
322
- assert (cmdlineBasenameStart <= (int )strlen (cmdline ));
325
+ assert (cmdlineBasenameStart <= strlen (cmdline ));
326
+
327
+ size_t exeLen = 0 ;
328
+ size_t exeBasenameOffset = 0 ;
329
+ size_t exeBasenameLen = 0 ;
330
+ size_t matchLen = 0 ;
331
+ if (procExe ) {
332
+ exeLen = strlen (procExe );
333
+ exeBasenameOffset = this -> procExeBasenameOffset ;
334
+ exeBasenameLen = exeLen - exeBasenameOffset ;
335
+
336
+ assert (exeBasenameOffset <= strlen (procExe ));
337
+
338
+ if (this -> cmdline ) {
339
+ matchLen = matchCmdlinePrefixWithExeSuffix (this -> cmdline , & cmdlineBasenameStart , procExe , exeBasenameOffset , exeBasenameLen );
340
+ }
341
+ if (matchLen ) {
342
+ cmdlineBasenameLen = exeBasenameLen ;
343
+ }
344
+ }
323
345
324
346
if (!showMergedCommand || !procExe || !procComm ) { /* fall back to cmdline */
325
347
if ((showMergedCommand || (Process_isUserlandThread (this ) && showThreadNames )) && procComm && strlen (procComm )) { /* set column to or prefix it with comm */
@@ -337,37 +359,62 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
337
359
if (shadowDistPathPrefix && showProgramPath )
338
360
CHECK_AND_MARK_DIST_PATH_PREFIXES (cmdline );
339
361
340
- if (cmdlineBasenameEnd > cmdlineBasenameStart )
341
- WRITE_HIGHLIGHT (showProgramPath ? cmdlineBasenameStart : 0 , cmdlineBasenameEnd - cmdlineBasenameStart , baseAttr , CMDLINE_HIGHLIGHT_FLAG_BASENAME );
362
+ if (cmdlineBasenameLen > 0 ) {
363
+ WRITE_HIGHLIGHT (showProgramPath ? cmdlineBasenameStart : 0 , cmdlineBasenameLen , baseAttr , CMDLINE_HIGHLIGHT_FLAG_BASENAME );
342
364
343
- if (this -> procExeDeleted )
344
- WRITE_HIGHLIGHT (showProgramPath ? cmdlineBasenameStart : 0 , cmdlineBasenameEnd - cmdlineBasenameStart , delExeAttr , CMDLINE_HIGHLIGHT_FLAG_DELETED );
345
- else if (this -> usesDeletedLib )
346
- WRITE_HIGHLIGHT (showProgramPath ? cmdlineBasenameStart : 0 , cmdlineBasenameEnd - cmdlineBasenameStart , delLibAttr , CMDLINE_HIGHLIGHT_FLAG_DELETED );
365
+ if (this -> procExeDeleted )
366
+ WRITE_HIGHLIGHT (showProgramPath ? cmdlineBasenameStart : 0 , cmdlineBasenameLen , delExeAttr , CMDLINE_HIGHLIGHT_FLAG_DELETED );
367
+ else if (this -> usesDeletedLib )
368
+ WRITE_HIGHLIGHT (showProgramPath ? cmdlineBasenameStart : 0 , cmdlineBasenameLen , delLibAttr , CMDLINE_HIGHLIGHT_FLAG_DELETED );
369
+ }
347
370
348
371
(void )stpcpyWithNewlineConversion (str , cmdline + (showProgramPath ? 0 : cmdlineBasenameStart ));
349
372
350
373
return ;
351
374
}
352
375
353
- int exeLen = strlen (this -> procExe );
354
- int exeBasenameOffset = this -> procExeBasenameOffset ;
355
- int exeBasenameLen = exeLen - exeBasenameOffset ;
356
-
357
- assert (exeBasenameOffset >= 0 );
358
- assert (exeBasenameOffset <= (int )strlen (procExe ));
376
+ size_t commLen = 0 ;
359
377
360
378
bool haveCommInExe = false;
361
379
if (procExe && procComm && (!Process_isUserlandThread (this ) || showThreadNames )) {
362
380
haveCommInExe = strncmp (procExe + exeBasenameOffset , procComm , TASK_COMM_LEN - 1 ) == 0 ;
363
381
}
382
+ if (haveCommInExe ) {
383
+ commLen = exeBasenameLen ;
384
+ }
385
+
386
+ bool haveCommInCmdline = false;
387
+ size_t commStart = 0 ;
388
+
389
+ if (!haveCommInExe && this -> cmdline && procComm && searchCommInCmdline && (!Process_isUserlandThread (this ) || showThreadNames )) {
390
+ haveCommInCmdline = findCommInCmdline (procComm , cmdline , cmdlineBasenameStart , & commStart , & commLen );
391
+ }
392
+
393
+ if (!stripExeFromCmdline ) {
394
+ matchLen = 0 ;
395
+ }
396
+ if (matchLen ) {
397
+ /* strip the matched exe prefix */
398
+ cmdline += matchLen ;
399
+
400
+ if (haveCommInCmdline ) {
401
+ if (commStart == cmdlineBasenameStart ) {
402
+ haveCommInExe = true;
403
+ haveCommInCmdline = false;
404
+ commStart = 0 ;
405
+ } else {
406
+ assert (commStart >= matchLen );
407
+ commStart -= matchLen ;
408
+ }
409
+ }
410
+ }
364
411
365
412
/* Start with copying exe */
366
413
if (showProgramPath ) {
367
414
if (shadowDistPathPrefix )
368
415
CHECK_AND_MARK_DIST_PATH_PREFIXES (procExe );
369
416
if (haveCommInExe )
370
- WRITE_HIGHLIGHT (exeBasenameOffset , exeBasenameLen , commAttr , CMDLINE_HIGHLIGHT_FLAG_COMM );
417
+ WRITE_HIGHLIGHT (exeBasenameOffset , commLen , commAttr , CMDLINE_HIGHLIGHT_FLAG_COMM );
371
418
WRITE_HIGHLIGHT (exeBasenameOffset , exeBasenameLen , baseAttr , CMDLINE_HIGHLIGHT_FLAG_BASENAME );
372
419
if (this -> procExeDeleted )
373
420
WRITE_HIGHLIGHT (exeBasenameOffset , exeBasenameLen , delExeAttr , CMDLINE_HIGHLIGHT_FLAG_DELETED );
@@ -376,7 +423,7 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
376
423
str = stpcpy (str , procExe );
377
424
} else {
378
425
if (haveCommInExe )
379
- WRITE_HIGHLIGHT (0 , exeBasenameLen , commAttr , CMDLINE_HIGHLIGHT_FLAG_COMM );
426
+ WRITE_HIGHLIGHT (0 , commLen , commAttr , CMDLINE_HIGHLIGHT_FLAG_COMM );
380
427
WRITE_HIGHLIGHT (0 , exeBasenameLen , baseAttr , CMDLINE_HIGHLIGHT_FLAG_BASENAME );
381
428
if (this -> procExeDeleted )
382
429
WRITE_HIGHLIGHT (0 , exeBasenameLen , delExeAttr , CMDLINE_HIGHLIGHT_FLAG_DELETED );
@@ -385,18 +432,6 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
385
432
str = stpcpy (str , procExe + exeBasenameOffset );
386
433
}
387
434
388
- bool haveCommInCmdline = false;
389
- int commStart = 0 ;
390
- int commEnd = 0 ;
391
-
392
- /* Try to match procComm with procExe's basename: This is reliable (predictable) */
393
- if (searchCommInCmdline ) {
394
- /* commStart/commEnd will be adjusted later along with cmdline */
395
- haveCommInCmdline = (!Process_isUserlandThread (this ) || showThreadNames ) && findCommInCmdline (procComm , cmdline , cmdlineBasenameStart , & commStart , & commEnd );
396
- }
397
-
398
- int matchLen = matchCmdlinePrefixWithExeSuffix (cmdline , cmdlineBasenameStart , procExe , exeBasenameOffset , exeBasenameLen );
399
-
400
435
bool haveCommField = false;
401
436
402
437
if (!haveCommInExe && !haveCommInCmdline && procComm && (!Process_isUserlandThread (this ) || showThreadNames )) {
@@ -406,18 +441,6 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
406
441
haveCommField = true;
407
442
}
408
443
409
- if (matchLen ) {
410
- if (stripExeFromCmdline ) {
411
- /* strip the matched exe prefix */
412
- cmdline += matchLen ;
413
-
414
- commStart -= matchLen ;
415
- commEnd -= matchLen ;
416
- } else {
417
- matchLen = 0 ;
418
- }
419
- }
420
-
421
444
if (!matchLen || (haveCommField && * cmdline )) {
422
445
/* cmdline will be a separate field */
423
446
WRITE_SEPARATOR ;
@@ -427,7 +450,7 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
427
450
CHECK_AND_MARK_DIST_PATH_PREFIXES (cmdline );
428
451
429
452
if (!haveCommInExe && haveCommInCmdline && !haveCommField && (!Process_isUserlandThread (this ) || showThreadNames ))
430
- WRITE_HIGHLIGHT (commStart , commEnd - commStart , commAttr , CMDLINE_HIGHLIGHT_FLAG_COMM );
453
+ WRITE_HIGHLIGHT (commStart , commLen , commAttr , CMDLINE_HIGHLIGHT_FLAG_COMM );
431
454
432
455
/* Display cmdline if it hasn't been consumed by procExe */
433
456
if (* cmdline )
@@ -445,20 +468,20 @@ void Process_writeCommand(const Process* this, int attr, int baseAttr, RichStrin
445
468
const ProcessMergedCommand * mc = & this -> mergedCommand ;
446
469
const char * mergedCommand = mc -> str ;
447
470
448
- int strStart = RichString_size (str );
471
+ size_t strStart = RichString_size (str );
449
472
450
473
const Settings * settings = this -> super .host -> settings ;
451
474
const bool highlightBaseName = settings -> highlightBaseName ;
452
475
const bool highlightSeparator = true;
453
476
const bool highlightDeleted = settings -> highlightDeletedExe ;
454
477
455
478
if (!mergedCommand ) {
456
- int len = 0 ;
479
+ size_t len = 0 ;
457
480
const char * cmdline = this -> cmdline ;
458
481
459
482
if (highlightBaseName || !settings -> showProgramPath ) {
460
- int basename = 0 ;
461
- for (int i = 0 ; i < this -> cmdlineBasenameEnd ; i ++ ) {
483
+ size_t basename = 0 ;
484
+ for (size_t i = 0 ; i < this -> cmdlineBasenameEnd ; i ++ ) {
462
485
if (cmdline [i ] == '/' ) {
463
486
basename = i + 1 ;
464
487
} else if (cmdline [i ] == ':' ) {
@@ -849,7 +872,7 @@ bool Process_rowMatchesFilter(const Row* super, const Table* table) {
849
872
void Process_init (Process * this , const Machine * host ) {
850
873
Row_init (& this -> super , host );
851
874
852
- this -> cmdlineBasenameEnd = -1 ;
875
+ this -> cmdlineBasenameEnd = 0 ;
853
876
this -> st_uid = (uid_t )- 1 ;
854
877
}
855
878
@@ -1001,12 +1024,12 @@ void Process_updateComm(Process* this, const char* comm) {
1001
1024
this -> mergedCommand .lastUpdate = 0 ;
1002
1025
}
1003
1026
1004
- static int skipPotentialPath (const char * cmdline , int end ) {
1027
+ static size_t skipPotentialPath (const char * cmdline , size_t end ) {
1005
1028
if (cmdline [0 ] != '/' )
1006
1029
return 0 ;
1007
1030
1008
- int slash = 0 ;
1009
- for (int i = 1 ; i < end ; i ++ ) {
1031
+ size_t slash = 0 ;
1032
+ for (size_t i = 1 ; i < end ; i ++ ) {
1010
1033
if (cmdline [i ] == '/' && cmdline [i + 1 ] != '\0' ) {
1011
1034
slash = i + 1 ;
1012
1035
continue ;
@@ -1022,11 +1045,10 @@ static int skipPotentialPath(const char* cmdline, int end) {
1022
1045
return slash ;
1023
1046
}
1024
1047
1025
- void Process_updateCmdline (Process * this , const char * cmdline , int basenameStart , int basenameEnd ) {
1026
- assert (basenameStart >= 0 );
1027
- assert ((cmdline && basenameStart < (int )strlen (cmdline )) || (!cmdline && basenameStart == 0 ));
1048
+ void Process_updateCmdline (Process * this , const char * cmdline , size_t basenameStart , size_t basenameEnd ) {
1049
+ assert ((cmdline && basenameStart < strlen (cmdline )) || (!cmdline && basenameStart == 0 ));
1028
1050
assert ((basenameEnd > basenameStart ) || (basenameEnd == 0 && basenameStart == 0 ));
1029
- assert ((cmdline && basenameEnd <= ( int ) strlen (cmdline )) || (!cmdline && basenameEnd == 0 ));
1051
+ assert ((cmdline && basenameEnd <= strlen (cmdline )) || (!cmdline && basenameEnd == 0 ));
1030
1052
1031
1053
if (!this -> cmdline && !cmdline )
1032
1054
return ;
@@ -1059,7 +1081,7 @@ void Process_updateExe(Process* this, const char* exe) {
1059
1081
if (exe ) {
1060
1082
this -> procExe = xStrdup (exe );
1061
1083
const char * lastSlash = strrchr (exe , '/' );
1062
- this -> procExeBasenameOffset = (lastSlash && * (lastSlash + 1 ) != '\0' && lastSlash != exe ) ? (lastSlash - exe + 1 ) : 0 ;
1084
+ this -> procExeBasenameOffset = (lastSlash && * (lastSlash + 1 ) != '\0' && lastSlash != exe ) ? (size_t )( lastSlash - exe + 1 ) : 0 ;
1063
1085
} else {
1064
1086
this -> procExe = NULL ;
1065
1087
this -> procExeBasenameOffset = 0 ;
0 commit comments