Forum > Linux
[Solved] Running one program from another multiple times
(1/1)
iso4free:
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 [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.runApp(anApp: string; asRoot: boolean);var AProcess: TProcess; I: integer; DisplayVar: string;begin AProcess := TProcess.Create(nil); try AProcess.InheritHandles := False; AProcess.Options := [poNoConsole, poWaitOnExit]; AProcess.ShowWindow := swoShow; DisplayVar := GetEnvironmentVariable('DISPLAY'); if DisplayVar = '' then DisplayVar := ':0'; AProcess.Environment.Add('DISPLAY=' + DisplayVar); for I := 1 to GetEnvironmentVariableCount do AProcess.Environment.Add(GetEnvironmentString(I)); if asRoot then begin AProcess.Executable := '/bin/bash'; AProcess.Parameters.Add('-c'); AProcess.Parameters.Add('sudo setsid ' + anApp + ' &'); end else begin AProcess.Executable := '/bin/bash'; AProcess.Parameters.Add('-c'); AProcess.Parameters.Add('setsid ' + anApp + ' &'); end; AProcess.Execute; finally AProcess.Free; end;end;
Another core for replace process from runner:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure ReplaceWithProgram(const ProgramPath: string; const Params: array of string);var Args: array of PChar; I: integer;begin // Arguments for execv SetLength(Args, Length(Params) + 2); // +2: for ProgramPath and nil in the end Args[0] := PChar(ProgramPath); for I := 0 to High(Params) do Args[I + 1] := PChar(Params[I]); Args[Length(Params) + 1] := nil; // Replace current process FpExecv(PChar(ProgramPath), @Args[0],envp); // If we here FpExecV() won`t work WriteLn(Format('Failed to replace process with "%s". Error: %d', [ProgramPath, fpGetErrno])); Halt(1);end;
Code for run "runner" from "sdu" as regular user
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure LaunchRunnerAsUser;var Process: TProcess;begin Process := TProcess.Create(nil); try Process.Executable := '/bin/bash'; Process.Parameters.Add('-c'); {$IFDEF DEBUG} Process.Parameters.Add('runuser -l vadim -c "DISPLAY=:0 '+BaseAppPath+'runner -?" &'); {$ELSE} Process.Parameters.Add('runuser -l pi -c "DISPLAY=:0 '+BaseAppPath+'runner -?" &'); {$ENDIF} Process.Options := [poNoConsole]; Process.Execute; finally Process.Free; end;end;
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?
iso4free:
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:
Thanks for the update. You can edit your first post and added the solved to the subject yourself.
Navigation
[0] Message Index