Browse Source

Improve detect_linuxvcs to allow parsing of /proc/PID/stat even with spaces in exe name

git-svn-id: trunk@39579 -
pierre 7 years ago
parent
commit
bc75e8547e
1 changed files with 39 additions and 12 deletions
  1. 39 12
      rtl/linux/linuxvcs.pp

+ 39 - 12
rtl/linux/linuxvcs.pp

@@ -82,9 +82,10 @@ end;
 procedure detect_linuxvcs;
 procedure detect_linuxvcs;
 
 
 var f:text;
 var f:text;
-    c:char;
-    pid,ppid,dummy:integer;
-    device:longint;
+    f_open : boolean;
+    c,pc:char;
+    pid,cpid,dummy:longint;
+    device:dword;
     s:string[15];
     s:string[15];
 
 
 begin
 begin
@@ -92,36 +93,62 @@ begin
    Commander. Idea from the C++ Turbo Vision project, credits go
    Commander. Idea from the C++ Turbo Vision project, credits go
    to Martynas Kunigelis <[email protected]>.}
    to Martynas Kunigelis <[email protected]>.}
   pid:=fpgetpid;
   pid:=fpgetpid;
+  f_open:=false;
+  {$push}
+  {$I-}
+  {$R-}
   repeat
   repeat
+    cpid:=pid;
     str(pid,s);
     str(pid,s);
     assign(f,'/proc/'+s+'/stat');
     assign(f,'/proc/'+s+'/stat');
-    {$I-}
     reset(f);
     reset(f);
-    {$I+}
     if ioresult<>0 then
     if ioresult<>0 then
-      break;
+      exit;
+    f_open:=true;
+    { from here we can discard I/O errors, as long as we avoid
+      infinite loops }
+    { first number is pid }
+    dummy:=0;
     read(f,dummy);
     read(f,dummy);
-    read(f,c);
+    if dummy<>pid then
+      exit;
+    { after comes the name of the binary within (), look for closing brace followed by space }
+    c:=#0;
     repeat
     repeat
+      pc:=c;
       read(f,c);
       read(f,c);
-    until c=' ';
+      if ioresult<>0 then
+        break;
+    until (pc=')') and (c=' ');
+    { now comes the state letter }
     repeat
     repeat
       read(f,c);
       read(f,c);
+      if ioresult<>0 then
+        break;
     until c=' ';
     until c=' ';
-    ppid:=pid;
+    { parent pid }
+    pid:=-1;
     read(f,pid);
     read(f,pid);
+    { process group }
     read(f,dummy);
     read(f,dummy);
+    { session }
     read(f,dummy);
     read(f,dummy);
+    { device number }
+    device:=0;
     read(f,device);
     read(f,device);
     close(f);
     close(f);
-    if device and $ffffffc0=$00000400 then {/dev/tty*}
+    f_open:=false;
+    if (device and $ffffffc0)=$00000400 then {/dev/tty*}
       begin
       begin
         vcs_device:=device and $3f;
         vcs_device:=device and $3f;
         break;
         break;
       end;
       end;
-   until (device=0) {Not attached to a terminal, i.e. an xterm.}
+  until (device=0) {Not attached to a terminal, i.e. an xterm.}
       or (pid=-1)
       or (pid=-1)
-      or (ppid=pid);
+      or (cpid=pid);
+  if f_open then
+    close(f);
+  {$pop}
 end;
 end;
 
 
 begin
 begin