55 * Copied from https://github.com/microsoft/vscode-node-debug/blob/master/src/node/extension/processTree.ts
66 *--------------------------------------------------------------------------------------------*/
77/* tslint:disable */
8- 'use strict' ;
8+ 'use strict' ;
99
10- import { spawn , ChildProcess } from 'child_process' ;
10+ import { spawn , ChildProcessWithoutNullStreams } from 'child_process' ;
1111import { join } from 'path' ;
1212
1313export class ProcessTreeNode {
@@ -68,7 +68,7 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
6868
6969 return new Promise ( ( resolve , reject ) => {
7070
71- let proc : ChildProcess ;
71+ let proc : ChildProcessWithoutNullStreams ;
7272
7373 if ( process . platform === 'win32' ) {
7474
@@ -77,8 +77,8 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
7777
7878 const wmic = join ( process . env [ 'WINDIR' ] || 'C:\\Windows' , 'System32' , 'wbem' , 'WMIC.exe' ) ;
7979 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 => {
8282 let matches = CMD_PAT . exec ( line . trim ( ) ) ;
8383 if ( matches && matches . length === 5 ) {
8484 const pid = Number ( matches [ 4 ] ) ;
@@ -110,8 +110,8 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
110110 } else if ( process . platform === 'darwin' ) { // OS X
111111
112112 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 => {
115115
116116 const pid = Number ( line . substr ( 0 , 5 ) ) ;
117117 const ppid = Number ( line . substr ( 6 , 5 ) ) ;
@@ -125,28 +125,31 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
125125
126126 } else { // linux
127127
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 ) ;
138143 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 ( )
148150 }
149151
152+
150153 if ( ! isNaN ( pid ) && ! isNaN ( ppid ) ) {
151154 one ( pid , ppid , command , args ) ;
152155 }
@@ -157,8 +160,8 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
157160 reject ( err ) ;
158161 } ) ;
159162
160- proc . stderr ? .setEncoding ( 'utf8' ) ;
161- proc . stderr ? .on ( 'data' , data => {
163+ proc . stderr . setEncoding ( 'utf8' ) ;
164+ proc . stderr . on ( 'data' , data => {
162165 const e = data . toString ( ) ;
163166 if ( e . indexOf ( 'screen size is bogus' ) >= 0 ) {
164167 // 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
192195 } ) ;
193196 } ) ;
194197}
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