@@ -9,6 +9,9 @@ use anyhow::{anyhow, Result};
99use log:: * ;
1010use regex:: Regex ;
1111use wait_timeout:: ChildExt ;
12+ use std:: fs:: File ;
13+ use std:: io:: BufReader ;
14+ use std:: io:: BufRead ;
1215
1316const NODEJS_INSPECT_PORT_MIN : u16 = 19230 ;
1417const NODEJS_INSPECT_PORT_MAX : u16 = 19235 ;
@@ -42,23 +45,30 @@ fn parse_port_from_address(address: &str) -> Option<u16> {
4245}
4346
4447pub fn get_process_listening_port ( pid : i32 ) -> u16 {
45- let tcp_path = format ! ( "/proc/{}/net/tcp" , pid) ;
4648
4749 // frist get ipv4 listen port
48- if let Ok ( content) = std:: fs:: read_to_string ( tcp_path) {
49-
50- for line in content. lines ( ) . skip ( 1 ) {
51- let parts: Vec < & str > = line. split_whitespace ( ) . collect ( ) ;
52- if parts. len ( ) >= 3 {
53- let local_address = parts[ 1 ] ;
54- let status = parts[ 3 ] ;
50+ let file_path = format ! ( "/proc/{}/net/tcp" , pid) ;
51+ let file = match File :: open ( & file_path) {
52+ Ok ( f) => f,
53+ Err ( _) => return 0 ,
54+ } ;
55+ let reader = BufReader :: new ( file) ;
56+
57+ for line in reader. lines ( ) . skip ( 1 ) {
58+ let line = match line {
59+ Ok ( l) => l,
60+ Err ( _) => return 0 ,
61+ } ;
62+ let parts: Vec < & str > = line. split_whitespace ( ) . collect ( ) ;
63+ if parts. len ( ) >= 4 {
64+ let local_address = parts[ 1 ] ;
5565
56- if status == "0A" {
57- if let Some ( port ) = parse_port_from_address ( local_address ) {
58- if ( NODEJS_INSPECT_PORT_MIN ..= NODEJS_INSPECT_PORT_MAX ) . contains ( & port ) {
59- info ! ( "Found IPv4 listen port {} for pid {}" , port , pid ) ;
60- return port;
61- }
66+ let status = parts [ 3 ] ;
67+ if status == "0A" {
68+ if let Some ( port ) = parse_port_from_address ( local_address ) {
69+ if ( NODEJS_INSPECT_PORT_MIN ..= NODEJS_INSPECT_PORT_MAX ) . contains ( & port) {
70+ info ! ( "Found IPv4 listen port {} for pid {}" , port, pid ) ;
71+ return port ;
6272 }
6373 }
6474 }
@@ -67,20 +77,26 @@ pub fn get_process_listening_port(pid: i32) -> u16 {
6777
6878 // get ipv6 listen port
6979 let tcp6_path = format ! ( "/proc/{}/net/tcp6" , pid) ;
70- if let Ok ( content) = std:: fs:: read_to_string ( tcp6_path) {
71-
72- for line in content. lines ( ) . skip ( 1 ) {
73- let parts: Vec < & str > = line. split_whitespace ( ) . collect ( ) ;
74- if parts. len ( ) >= 3 {
75- let local_address = parts[ 1 ] ;
76- let status = parts[ 3 ] ;
80+ let file = match File :: open ( & tcp6_path) {
81+ Ok ( f) => f,
82+ Err ( _) => return 0 ,
83+ } ;
84+ let reader = BufReader :: new ( file) ;
85+ for line in reader. lines ( ) . skip ( 1 ) {
86+ let line = match line {
87+ Ok ( l) => l,
88+ Err ( _) => return 0 ,
89+ } ;
90+ let parts: Vec < & str > = line. split_whitespace ( ) . collect ( ) ;
91+ if parts. len ( ) >= 4 {
92+ let local_address = parts[ 1 ] ;
93+ let status = parts[ 3 ] ;
7794
78- if status == "0A" {
79- if let Some ( port) = parse_port_from_address ( local_address) {
80- if ( 16680 ..= NODEJS_INSPECT_PORT_MAX ) . contains ( & port) {
81- info ! ( "Found IPv6 listen port {} for pid {}" , port, pid) ;
82- return port;
83- }
95+ if status == "0A" {
96+ if let Some ( port) = parse_port_from_address ( local_address) {
97+ if ( NODEJS_INSPECT_PORT_MIN ..= NODEJS_INSPECT_PORT_MAX ) . contains ( & port) {
98+ info ! ( "Found IPv6 listen port {} for pid {}" , port, pid) ;
99+ return port;
84100 }
85101 }
86102 }
@@ -91,31 +107,44 @@ pub fn get_process_listening_port(pid: i32) -> u16 {
91107}
92108
93109
94- pub fn get_inspect_port ( pid : i32 ) -> u16 {
110+ pub fn get_inspect_port ( process_info : & ProcessInfo ) -> u16 {
111+ let process = match procfs:: process:: Process :: new ( process_info. pid ) {
112+ Ok ( p) => p,
113+ Err ( _) => { return 0 ; }
114+ } ;
115+
95116 let re = regex:: Regex :: new ( r"inspect(?:-brk|-port)?=(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3}:)?(\d+)" )
96117 . expect ( "Invalid regex pattern" ) ;
97118
98- let cmdline = std:: fs:: read_to_string ( format ! ( "/proc/{}/cmdline" , pid) ) . unwrap_or_default ( ) ;
99-
119+
120+ let cmdline = process_info. cmdline . clone ( ) . unwrap_or ( String :: new ( ) ) ;
121+
100122 if let Some ( captures) = re. captures ( & cmdline) {
101123 if let Some ( port) = captures. get ( 1 ) {
102124 info ! ( "inspect port: {}" , port. as_str( ) ) ;
103125 return port. as_str ( ) . parse ( ) . unwrap_or ( 0 ) ;
104126 }
105127 }
106-
107- let environ = std:: fs:: read_to_string ( format ! ( "/proc/{}/environ" , pid) ) . unwrap_or_default ( ) ;
108- let options = environ. split ( '\0' ) . find ( |element| element. starts_with ( "NODE_OPTIONS=" ) ) ;
109-
110- if let Some ( options) = options {
111- if let Some ( captures) = re. captures ( options) {
112- if let Some ( port) = captures. get ( 1 ) {
113- info ! ( "inspect port: {}" , port. as_str( ) ) ;
114- return port. as_str ( ) . parse ( ) . unwrap_or ( 0 ) ;
128+ let env = match process. environ ( ) {
129+ Ok ( env) => env,
130+ Err ( _) => { return 0 ; }
131+ } ;
132+
133+ match env. get ( & std:: ffi:: OsString :: from ( "NODE_OPTIONS" ) ) {
134+ Some ( v) => match v. clone ( ) . into_string ( ) {
135+ Ok ( s) => {
136+ if let Some ( captures) = re. captures ( s. as_str ( ) ) {
137+ if let Some ( port) = captures. get ( 1 ) {
138+ info ! ( "inspect port: {}" , port. as_str( ) ) ;
139+ return port. as_str ( ) . parse ( ) . unwrap_or ( 0 ) ;
140+ }
141+ }
115142 }
116- }
117- }
118-
143+ Err ( _) => { }
144+ } ,
145+ None => { }
146+ } ;
147+
119148 0
120149}
121150
0 commit comments