| /* eslint-disable @typescript-eslint/no-unused-vars */ |
| /*--------------------------------------------------------- |
| * Copyright 2021 The Go Authors. All rights reserved. |
| * Licensed under the MIT License. See LICENSE in the project root for license information. |
| *--------------------------------------------------------*/ |
| |
| 'use strict'; |
| |
| import { AttachItem, ProcessListCommand } from '../pickProcess'; |
| |
| // lsofDarwinCommand uses the lsof command to find the executable path. |
| // Argument explanation: |
| // - '-Pnl' disables the conversion of network numbers (n), user id numbers (l), |
| // and port number (P) to potentially make the command run faster. |
| // - '-F ptnc' specifies the output to be printed for use in another program |
| // and to include the pid (p), file descriptor and type (t), and name (n). |
| // - '-d txt' limits the files to be included to be those with file descriptor='txt'. |
| export const lsofDarwinCommand: ProcessListCommand = { |
| command: 'lsof', |
| args: ['-Pnl', '-F', 'pn', '-d', 'txt'] |
| }; |
| |
| export function parseLsofProcesses(processes: string): AttachItem[] { |
| const lines: string[] = processes.split('\n'); |
| return parseProcessesFromLsofArray(lines); |
| } |
| |
| function parseProcessesFromLsofArray(processArray: string[], includesEnv?: boolean): AttachItem[] { |
| const processEntries: AttachItem[] = []; |
| let i = 0; |
| while (i < processArray.length) { |
| const line = processArray[i]; |
| i++; |
| if (!line) { |
| continue; |
| } |
| // The output for each process begins with a line containing the pid. |
| const out = line[0]; |
| const val = line.substr(1); |
| if (out !== 'p') { |
| continue; |
| } |
| const processEntry: AttachItem = { id: val, label: '' }; |
| |
| // Loop through every file which will have 3 lines containing: f=filedescriptor, t=type, n=name. |
| while (i < processArray.length && processArray[i].length > 0 && processArray[i][0] !== 'p') { |
| // Assume the first file with type 'txt' is the executable |
| if (!processEntry.executable) { |
| const file: { |
| fd?: string; |
| name?: string; |
| } = parseFile(i, processArray); |
| processEntry.executable = file.name; |
| } |
| i += 2; |
| } |
| |
| if (processEntry) { |
| processEntries.push(processEntry); |
| } |
| } |
| return processEntries; |
| } |
| |
| function parseFile(start: number, lines: string[]): { fd?: string; name?: string } { |
| const file: { |
| fd?: string; |
| name?: string; |
| } = {}; |
| |
| for (let j = start; j < start + 2; j++) { |
| const line = lines[j]; |
| if (!line) { |
| continue; |
| } |
| const out = line[0]; |
| const val = line.substr(1); |
| switch (out) { |
| case 'f': |
| file.fd = val; |
| break; |
| case 'n': |
| file.name = val; |
| break; |
| } |
| } |
| return file; |
| } |