Recent

Author Topic: [Solved] Running one program from another multiple times  (Read 648 times)

iso4free

  • Newbie
  • Posts: 5
[Solved] Running one program from another multiple times
« on: November 21, 2024, 09:11:12 pm »
I have a problem with launching one program from another. Actually, there are no problems to run one program from another using TProcess, but my situation is a little unusual. I will try to explain what I need and what I have.
Raspberry Pi operating system (I test on a regular computer with Linux), laboratory equipment. There are two programs written in Lazarus with a graphical interface. "runner" is launched at system startup without command line parameters with normal user rights, without showing its window it starts another "sdu" program with root rights. When there is a need to exit this program, it runs "runner" again with the command line option "-?" and with normal user rights. Everything seems to work fine, but only once. If I use the button from the "runner" GUI, I try to start "sdu" again, but now it stops working. I used ChatGPT in writing the process launch code, tried various options, both launch via TProcess and process replacement via FpExecv() and similar functions.
Here is code for launch app from runner:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.runApp(anApp: string; asRoot: boolean);
  2. var
  3.   AProcess: TProcess;
  4.   I: integer;
  5.   DisplayVar: string;
  6. begin
  7.   AProcess := TProcess.Create(nil);
  8.   try
  9.     AProcess.InheritHandles := False;
  10.     AProcess.Options := [poNoConsole, poWaitOnExit];
  11.     AProcess.ShowWindow := swoShow;
  12.  
  13.     DisplayVar := GetEnvironmentVariable('DISPLAY');
  14.     if DisplayVar = '' then
  15.       DisplayVar := ':0';
  16.     AProcess.Environment.Add('DISPLAY=' + DisplayVar);
  17.  
  18.     for I := 1 to GetEnvironmentVariableCount do
  19.       AProcess.Environment.Add(GetEnvironmentString(I));
  20.  
  21.     if asRoot then
  22.     begin
  23.       AProcess.Executable := '/bin/bash';
  24.       AProcess.Parameters.Add('-c');
  25.       AProcess.Parameters.Add('sudo setsid ' + anApp + ' &');
  26.     end
  27.     else
  28.     begin
  29.       AProcess.Executable := '/bin/bash';
  30.       AProcess.Parameters.Add('-c');
  31.       AProcess.Parameters.Add('setsid ' + anApp + ' &');
  32.     end;
  33.  
  34.     AProcess.Execute;
  35.   finally
  36.     AProcess.Free;
  37.   end;
  38. end;
  39.  

Another core for replace process from runner:
Code: Pascal  [Select][+][-]
  1. procedure ReplaceWithProgram(const ProgramPath: string; const Params: array of string);
  2. var
  3.   Args: array of PChar;
  4.   I: integer;
  5. begin
  6.   // Arguments for  execv
  7.   SetLength(Args, Length(Params) + 2); // +2: for ProgramPath and nil in the end
  8.   Args[0] := PChar(ProgramPath);
  9.   for I := 0 to High(Params) do
  10.     Args[I + 1] := PChar(Params[I]);
  11.   Args[Length(Params) + 1] := nil;
  12.  
  13.   // Replace current process
  14.   FpExecv(PChar(ProgramPath), @Args[0],envp);
  15.  
  16.   // If we here FpExecV() won`t work
  17.   WriteLn(Format('Failed to replace process with "%s". Error: %d',
  18.     [ProgramPath, fpGetErrno]));
  19.   Halt(1);
  20. end;

Code for run "runner" from "sdu" as regular user
Code: Pascal  [Select][+][-]
  1. procedure LaunchRunnerAsUser;
  2. var
  3.   Process: TProcess;
  4. begin
  5.   Process := TProcess.Create(nil);
  6.   try
  7.     Process.Executable := '/bin/bash';
  8.  
  9.     Process.Parameters.Add('-c');
  10.     {$IFDEF DEBUG}
  11.     Process.Parameters.Add('runuser -l vadim -c "DISPLAY=:0 '+BaseAppPath+'runner -?" &');
  12.     {$ELSE}
  13.     Process.Parameters.Add('runuser -l pi -c "DISPLAY=:0 '+BaseAppPath+'runner -?" &');
  14.     {$ENDIF}
  15.  
  16.     Process.Options := [poNoConsole];
  17.  
  18.     Process.Execute;
  19.   finally
  20.     Process.Free;
  21.   end;
  22. end;
  23.  

After loading the system, the runner starts the sdu and finishes its work. After terminating the work, the sdu starts the runner again, but it is no longer possible to return to the sdu from it. I used both the first and the second method.
sdu must be executed with root rights, as it requires access to system resources.
What should I change to be able to run one program from another an unlimited number of times?
« Last Edit: November 25, 2024, 08:57:20 am by iso4free »

iso4free

  • Newbie
  • Posts: 5
Re: Running one program from another multiple times
« Reply #1 on: November 24, 2024, 06:11:37 pm »
Well, the problem was solved, and now everything works for me through tprocess. As it turned out, one more environment variable needed to be exported, Xauthority. After that, both programs can correctly launch each other with the necessary permissions. So this topic can be marked as 'Solved'.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11990
  • FPC developer.
Re: Running one program from another multiple times
« Reply #2 on: November 24, 2024, 07:03:08 pm »
Thanks for the update.  You can edit your first post and added the solved to the subject yourself.

 

TinyPortal © 2005-2018