5
5
* Copied from https://github.com/microsoft/vscode-node-debug/blob/master/src/node/extension/processTree.ts
6
6
*--------------------------------------------------------------------------------------------*/
7
7
/* tslint:disable */
8
- 'use strict' ;
8
+ 'use strict' ;
9
9
10
- import { spawn , ChildProcess } from 'child_process' ;
10
+ import { spawn , ChildProcessWithoutNullStreams } from 'child_process' ;
11
11
import { join } from 'path' ;
12
12
13
13
export class ProcessTreeNode {
@@ -68,7 +68,7 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
68
68
69
69
return new Promise ( ( resolve , reject ) => {
70
70
71
- let proc : ChildProcess ;
71
+ let proc : ChildProcessWithoutNullStreams ;
72
72
73
73
if ( process . platform === 'win32' ) {
74
74
@@ -77,8 +77,8 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
77
77
78
78
const wmic = join ( process . env [ 'WINDIR' ] || 'C:\\Windows' , 'System32' , 'wbem' , 'WMIC.exe' ) ;
79
79
proc = spawn ( wmic , [ 'process' , 'get' , 'CommandLine,CreationDate,ParentProcessId,ProcessId' ] ) ;
80
- proc . stdout ? .setEncoding ( 'utf8' ) ;
81
- proc . stdout ? .on ( 'data' , lines ( line => {
80
+ proc . stdout . setEncoding ( 'utf8' ) ;
81
+ proc . stdout . on ( 'data' , lines ( line => {
82
82
let matches = CMD_PAT . exec ( line . trim ( ) ) ;
83
83
if ( matches && matches . length === 5 ) {
84
84
const pid = Number ( matches [ 4 ] ) ;
@@ -110,8 +110,8 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
110
110
} else if ( process . platform === 'darwin' ) { // OS X
111
111
112
112
proc = spawn ( '/bin/ps' , [ '-x' , '-o' , `pid,ppid,comm=${ 'a' . repeat ( 256 ) } ,command` ] ) ;
113
- proc . stdout ? .setEncoding ( 'utf8' ) ;
114
- proc . stdout ? .on ( 'data' , lines ( line => {
113
+ proc . stdout . setEncoding ( 'utf8' ) ;
114
+ proc . stdout . on ( 'data' , lines ( line => {
115
115
116
116
const pid = Number ( line . substr ( 0 , 5 ) ) ;
117
117
const ppid = Number ( line . substr ( 6 , 5 ) ) ;
@@ -125,28 +125,31 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
125
125
126
126
} else { // linux
127
127
128
- proc = spawn ( '/bin/ps' , [ '-ax' , '-o' , 'pid,ppid,comm:20,command' ] ) ;
129
- proc . stdout ?. setEncoding ( 'utf8' ) ;
130
- proc . stdout ?. on ( 'data' , lines ( line => {
131
-
132
- const pid = Number ( line . substr ( 0 , 5 ) ) ;
133
- const ppid = Number ( line . substr ( 6 , 5 ) ) ;
134
- let command = line . substr ( 12 , 20 ) . trim ( ) ;
135
- let args = line . substr ( 33 ) ;
136
-
137
- let pos = args . indexOf ( command ) ;
128
+ proc = spawn ( '/bin/ps' , [ '-ax' , '-o' , 'pid:6,ppid:6,comm:20,command' ] ) ; // we specify the column width explicitly
129
+ proc . stdout . setEncoding ( 'utf8' ) ;
130
+ proc . stdout . on ( 'data' , lines ( line => {
131
+
132
+ // the following substr arguments must match the column width specified for the "ps" command above
133
+ // regular substr is deprecated
134
+ const pid = Number ( substr ( line , 0 , 6 ) ) ;
135
+ const ppid = Number ( substr ( line , 7 , 6 ) ) ;
136
+ const shortName = substr ( line , 14 , 20 ) . trim ( )
137
+ const fullCommand = substr ( line , 35 )
138
+
139
+ let command = shortName ;
140
+ let args = fullCommand ;
141
+
142
+ const pos = fullCommand . indexOf ( shortName ) ;
138
143
if ( pos >= 0 ) {
139
- pos = pos + command . length ;
140
- while ( pos < args . length ) {
141
- if ( args [ pos ] === ' ' ) {
142
- break ;
143
- }
144
- pos ++ ;
145
- }
146
- command = args . substr ( 0 , pos ) ;
147
- args = args . substr ( pos + 1 ) ;
144
+ // binaries with spaces in path may not work
145
+ // possible solution to read directly from /proc
146
+ const commandEndPositionMaybe = fullCommand . indexOf ( " " , pos + shortName . length ) ;
147
+ const commandEndPosition = commandEndPositionMaybe < 0 ? fullCommand . length : commandEndPositionMaybe ;
148
+ command = fullCommand . substring ( 0 , commandEndPosition )
149
+ args = fullCommand . substring ( commandEndPosition ) . trimStart ( )
148
150
}
149
151
152
+
150
153
if ( ! isNaN ( pid ) && ! isNaN ( ppid ) ) {
151
154
one ( pid , ppid , command , args ) ;
152
155
}
@@ -157,8 +160,8 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
157
160
reject ( err ) ;
158
161
} ) ;
159
162
160
- proc . stderr ? .setEncoding ( 'utf8' ) ;
161
- proc . stderr ? .on ( 'data' , data => {
163
+ proc . stderr . setEncoding ( 'utf8' ) ;
164
+ proc . stderr . on ( 'data' , data => {
162
165
const e = data . toString ( ) ;
163
166
if ( e . indexOf ( 'screen size is bogus' ) >= 0 ) {
164
167
// ignore this error silently; see https://github.com/microsoft/vscode/issues/75932
@@ -192,3 +195,7 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
192
195
} ) ;
193
196
} ) ;
194
197
}
198
+
199
+ function substr ( str : string , startIndex : number , length ?: number ) {
200
+ return str . slice ( startIndex , length != undefined ? startIndex + length : str . length )
201
+ }
0 commit comments