From 69dd2b81de3bcbb955669f7937f3844b86467849 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Fri, 28 Nov 2025 21:36:41 +0100 Subject: Port process spawning to g_spawn_*() --- UConfig.pas | 5 +- UCore.pas | 15 +- UCoreUtils.pas | 426 +++++++++++++--------------------------------------- UCoreWorkers.pas | 2 +- ULibc.pas | 448 ------------------------------------------------------- UMain.pas | 49 +++--- UPreferences.pas | 16 +- 7 files changed, 151 insertions(+), 810 deletions(-) diff --git a/UConfig.pas b/UConfig.pas index 6e33947..1244f21 100644 --- a/UConfig.pas +++ b/UConfig.pas @@ -89,7 +89,7 @@ var ConfPanelSep, ConfRowHeight, ConfRowHeightReal, ConfNumHistoryItems, ParamDebug, ConfShowDotFiles, ConfClearReadOnlyAttr, ConfDisableMouseRename, ConfUseSystemFont, ConfUseFileTypeIcons, ConfFocusRefresh, ConfNewStyleAltO, ConfDirsInBold, ConfDisableDirectoryBrackets, - ConfUseLibcSystem, ConfUseInternalViewer, ParamDisablePlugins: boolean; + ConfUseInternalViewer, ParamDisablePlugins: boolean; ConfNormalItemDefaultColors, ConfCursorDefaultColors, ConfInactiveItemDefaultColors, ConfSelectedItemDefaultColors, ConfLinkItemDefaultColors, ConfDotFileItemDefaultColors, ConfLynxLikeMotion, ConfSizeGroupRequestZeroDigits, ConfDisableFileTips, ConfInsMoveDown, ConfSpaceMovesDown, ConfShowFuncButtons, ConfSelectAllDirs, ConfOctalPerm: boolean; @@ -220,7 +220,6 @@ begin ConfCmdLineTerminalBehaviour := 0; // 0 = Autodetect, 1 = Terminal, 2 = no term. ConfViewerTerminalBehaviour := 0; ConfEditorTerminalBehaviour := 0; - ConfUseLibcSystem := False; ConfUseInternalViewer := False; ConfMounterUseFSTab := True; ConfShowMounterBar := 1; // 0 = No mounter bar, 1 = one mounter bar, 2 = two mounter bars above the panels @@ -490,7 +489,6 @@ begin ConfCmdLineTerminalBehaviour := IniFile.ReadInteger(ConfProfileName, 'CmdLineTerminalBehaviour', ConfCmdLineTerminalBehaviour); ConfViewerTerminalBehaviour := IniFile.ReadInteger(ConfProfileName, 'ViewerTerminalBehaviour', ConfViewerTerminalBehaviour); ConfEditorTerminalBehaviour := IniFile.ReadInteger(ConfProfileName, 'EditorTerminalBehaviour', ConfEditorTerminalBehaviour); - ConfUseLibcSystem := IniFile.ReadBool(ConfProfileName, 'CompatUseLibcSystem', ConfUseLibcSystem); ConfUseInternalViewer := IniFile.ReadBool(ConfProfileName, 'UseInternalViewer', ConfUseInternalViewer); ConfSwitchOtherPanelBehaviour := IniFile.ReadInteger(ConfProfileName, 'SwitchOtherPanelBehaviour', ConfSwitchOtherPanelBehaviour); ConfDuplicateTabWarning := IniFile.ReadBool(ConfProfileName, 'DuplicateTabWarning', ConfDuplicateTabWarning); @@ -590,7 +588,6 @@ begin IniFile.WriteInteger(ConfProfileName, 'CmdLineTerminalBehaviour', ConfCmdLineTerminalBehaviour); IniFile.WriteInteger(ConfProfileName, 'ViewerTerminalBehaviour', ConfViewerTerminalBehaviour); IniFile.WriteInteger(ConfProfileName, 'EditorTerminalBehaviour', ConfEditorTerminalBehaviour); - IniFile.WriteBool(ConfProfileName, 'CompatUseLibcSystem', ConfUseLibcSystem); IniFile.WriteBool(ConfProfileName, 'UseInternalViewer', ConfUseInternalViewer); IniFile.WriteInteger(ConfProfileName, 'SwitchOtherPanelBehaviour', ConfSwitchOtherPanelBehaviour); IniFile.WriteBool(ConfProfileName, 'DuplicateTabWarning', ConfDuplicateTabWarning); diff --git a/UCore.pas b/UCore.pas index a41a7fd..b314eb4 100644 --- a/UCore.pas +++ b/UCore.pas @@ -1044,6 +1044,7 @@ end; function TMounterItem.Mount: boolean; var s: string; + Error: string; begin if Length(MountCommand) = 0 then begin if IsInFSTab then s := Format('mount "%s"', [MountPath]) @@ -1052,11 +1053,14 @@ begin s := ReplaceStr(MountCommand, '%dev', Device); s := ReplaceStr(s, '%dir', MountPath); end; - Result := HandleSystemCommand(s, Format(LANGErrorMount, [StrToUTF8(MountPath)])); + Result := HandleSystemCommand(s, Error); + if not Result then + Application.MessageBox(Format('%s%s', [Format(LANGErrorMount, [StrToUTF8(MountPath)]), StrToUTF8(Error)]), [mbOK], mbError, mbOK, mbOK); end; function TMounterItem.Umount: boolean; var s: string; + Error: string; begin if Length(UmountCommand) = 0 then begin if IsInFSTab then s := Format('umount "%s"', [MountPath]) @@ -1065,11 +1069,14 @@ begin s := ReplaceStr(UmountCommand, '%dev', Device); s := ReplaceStr(s, '%dir', MountPath); end; - Result := HandleSystemCommand(s, Format(LANGErrorUmount, [StrToUTF8(MountPath)])); + Result := HandleSystemCommand(s, Error); + if not Result then + Application.MessageBox(Format('%s%s', [Format(LANGErrorUmount, [StrToUTF8(MountPath)]), StrToUTF8(Error)]), [mbOK], mbError, mbOK, mbOK); end; function TMounterItem.Eject: boolean; var s: string; + Error: string; begin if Length(UmountCommand) = 0 then begin if IsInFSTab then s := Format('eject "%s"', [MountPath]) @@ -1078,7 +1085,9 @@ begin s := ReplaceStr(UmountCommand, '%dev', Device); s := ReplaceStr(s, '%dir', MountPath); end; - Result := HandleSystemCommand(s, Format(LANGErrorEject, [StrToUTF8(MountPath)])); + Result := HandleSystemCommand(s, Error); + if not Result then + Application.MessageBox(Format('%s%s', [Format(LANGErrorEject, [StrToUTF8(MountPath)]), StrToUTF8(Error)]), [mbOK], mbError, mbOK, mbOK); end; diff --git a/UCoreUtils.pas b/UCoreUtils.pas index 97777dc..eafd8bc 100644 --- a/UCoreUtils.pas +++ b/UCoreUtils.pas @@ -24,16 +24,12 @@ interface uses SysUtils, Classes, lazglib2, lazgobject2, lazgdk3, lazgtk3, GTKClasses, UEngines, ULibc; type - PIntArray = ^TIntArray; - TIntArray = array[0..1023] of LongWord; - PCharArray = array[0..0] of PChar; TOpenStringArray = array of string; TOpenPCharArray = array of PChar; -const ConstERRSpawn = 26; - ConstQuotationCharacters = [' ', '"', '''', '(', ')', ':', '&']; +const ConstQuotationCharacters = [' ', '"', '''', '(', ')', ':', '&']; ConstURIIllegalCharacters = '%:@/'; function FormatSize(Value: Int64; Base: integer; OverrideSizeFormat: integer = -1): string; @@ -51,7 +47,6 @@ function OctalToAttr(Octal: Cardinal): Cardinal; function PosEnd(Substr: string; S: string): Integer; function GetHomePath: string; function GetUserName: string; -function GetHostName: string; procedure SeparateExt(const Original: string; var Name, Ext: string); procedure SeparateNameDir(Original: string; var Path, FileName: string); function PadRightStr(const Str: string; Len: byte): string; @@ -84,10 +79,9 @@ function QuoteMarkupStr(const Str: string; MarkupUnderscore: boolean = False): s function RemoveQuotation(const Str: string): string; function GetStrSize(s: string): Int64; procedure DebugMsg(Params: array of const); -function SpawnProcess(const AppPath: string; var Running: boolean; const Parameters: array of string): Cardinal; -function ExecuteProgram(const AppCMDLine, CWD: string; const AutodetectGUI, RunInTerminal: boolean; var ErrorSignal: integer): boolean; +function ExecuteProgram(const AppCMDLine, CWD: string; const AutodetectGUI, RunInTerminal: boolean; var ErrorString: string): boolean; function IsItX11App(const Application: string): boolean; -function HandleSystemCommand(const Command, ErrorText: string): boolean; +function HandleSystemCommand(const Command: string; var ErrorString: string): boolean; function CompareTextsEx(S1, S2: PChar): integer; function LVCompareItems(Data1, Data2: PDataItem; const Ascending: boolean; const SortColumnID: integer): integer; @@ -130,10 +124,7 @@ procedure InternalUnLock; function InternalLockUnlocked: boolean; procedure InternalLockInit(Locked: boolean); -var ChildExitStatus: sig_atomic_t; - - AppPath, IconPath: string; // Used in UFileTypeSettings - +var AppPath, IconPath: string; // Used in UFileTypeSettings NormalItemGDKColor, ActiveItemGDKColor, InactiveItemGDKColor, SelectedItemGDKColor, DotFileItemGDKColor, LinkItemGDKColor, NormalItemGDKBackground, ActiveItemGDKBackground, InactiveItemGDKBackground: PGdkRGBA; @@ -411,17 +402,6 @@ begin Result := String(g_get_user_name); end; -(********************************************************************************************************************************) -function GetHostName: string; -var s: PChar; -begin - s := malloc(65536); - memset(s, 0, 65536); - ULibc.gethostname(s, 65536); - Result := String(strdup(s)); - libc_free(s); -end; - (********************************************************************************************************************************) procedure SeparateExt(const Original: string; var Name, Ext: string); var j: integer; @@ -1152,292 +1132,137 @@ begin end; (********************************************************************************************************************************) -function SpawnProcess(const AppPath: string; var Running: boolean; const Parameters: array of string): Cardinal; -var child_pid: __pid_t; - args_list: PPChar; +function ExecuteProgram(const AppCMDLine, CWD: string; const AutodetectGUI, RunInTerminal: boolean; var ErrorString: string): boolean; +var s: string; + Term: boolean; i: integer; - sv: sigval_t; -begin - Result := 0; - Running := False; - ChildExitStatus := -1; - - // Make the args_list array - args_list := nil; - if Length(Parameters) > 0 then begin - args_list := malloc((Length(Parameters) + 1) * sizeof(PChar)); - memset(args_list, 0, (Length(Parameters) + 1) * sizeof(PChar)); - for I := 0 to Length(Parameters) - 1 do - begin - PCharArray(args_list^)[I] := strdup(PChar(Parameters[i])); - end; - PCharArray(args_list^)[Length(Parameters)] := nil; - end; - - // Duplicate this process - DebugMsg(['SpawnProcess: before fork']); - child_pid := fork; - if child_pid <> 0 then begin - Result := child_pid; - Sleep(100); - //* FIXME: strange behaviour when freed -{ for i := 0 to Length(Parameters) - 1 do - if PCharArray(args_list^)[i] <> nil then - libc_free(PCharArray(args_list^)[i]); } - if args_list <> nil then libc_free(args_list); - Application.ProcessMessages; - Running := ChildExitStatus < 0; - DebugMsg(['SpawnProcess: ChildExitStatus = ', ChildExitStatus]); - if not Running then Result := 0; - if not WIFEXITED(ChildExitStatus) then Result := WTERMSIG(ChildExitStatus); - DebugMsg(['SpawnProcess: Result = ', Result]); - end else begin - // Now execute AppPath, searching for it in the path - execvp(PChar(AppPath), args_list); - // The execvp function returns only if an error occurs - sigqueue(getppid, SIGUSR1, sv); - DebugMsg(['SpawnProcess: forked: error, sending SIGUSR1']); - _exit(ConstERRSpawn); - end; - ChildExitStatus := -1; -end; - -(********************************************************************************************************************************) -procedure SplitArgs(var Args: TOpenStringArray; CMDLine: string); -var InQuotes: boolean; - i, Start: integer; - QuoteChar: char; - s: string; -begin - SetLength(Args, 0); - InQuotes := False; - CMDLine := Trim(CMDLine); - if Length(CMDLine) = 0 then Exit; - Start := 1; - QuoteChar := #0; - for i := 1 to Length(CMDLine) do - case CMDLine[i] of - ' ': if (not InQuotes) and ((i = 1) or (CMDLine[i - 1] <> '\')) then begin - s := Trim(Copy(CMDLine, Start, i - Start)); - TrimQuotes(s); - Start := i; - if s = '' then Continue; - SetLength(Args, Length(Args) + 1); - Args[Length(Args) - 1] := s; - end; - '"', '''': if (i = 1) or (CMDLine[i - 1] <> '\') then - if not InQuotes then begin - InQuotes := True; - QuoteChar := CMDLine[i]; -// Start := i; - end else - if CMDLine[i] = QuoteChar then begin - InQuotes := False; - s := Trim(Copy(CMDLine, Start, i + 1 - Start)); - TrimQuotes(s); - Start := i; - if s = '' then Continue; - if (Pos('"', s) > 1) and (Pos('"', s) < Length(s)) and (NumCountChars('"', s) mod 2 = 1) then s := s + '"'; -// if (Pos('''', s) > 1) and (Pos('''', s) < Length(s)) and (NumCountChars('''', s) mod 2 = 1) then s := s + ''''; - SetLength(Args, Length(Args) + 1); - Args[Length(Args) - 1] := s; - end; - end; - if (Start <> Length(CMDLine)) or (Start = 1) then begin - SetLength(Args, Length(Args) + 1); - Args[Length(Args) - 1] := Trim(Copy(CMDLine, Start, Length(CMDLine) + 1 - Start)); - TrimQuotes(Args[Length(Args) - 1]); - end; -end; - -function ExecuteProgram(const AppCMDLine, CWD: string; const AutodetectGUI, RunInTerminal: boolean; var ErrorSignal: integer): boolean; -var Args: TOpenStringArray; - s, s2: string; - Running, Term: boolean; - x: integer; + argvp: PPgchar; + p: Pgchar; + pcwd: Pgchar; + error: PGerror; begin + error := nil; Result := False; - try - DebugMsg(['*** Running ExecuteProgram begin']); -// DebugMsg(['ExecuteProgram: ConfTerminalCommand = "', ConfTerminalCommand, '"']); - s := Trim(AppCMDLine); - ErrorSignal := 0; - Term := RunInTerminal; - SplitArgs(Args, s); - - if AutodetectGUI then - if Length(Trim(Args[0])) > 0 then Term := not IsItX11App(Trim(Args[0])); - - if Term then begin - x := 1; - while x <= Length(s) do begin - if (s[x] in [{'"',} '''']) and ((x = 1) or (s[x - 1] <> '\')) then - Insert('\', s, x); - Inc(x); - end; - s2 := ReplaceStr(ConfTerminalCommand, '%cwd', QuoteStr(CWD)); - s := Format(s2, [s]); - SplitArgs(Args, s); + DebugMsg(['*** Running ExecuteProgram begin: ', AppCMDLine]); + s := Trim(AppCMDLine); + Term := RunInTerminal; + + if AutodetectGUI then Term := not IsItX11App(s); + + if Term then begin + if not g_shell_parse_argv(PChar(ConfTerminalCommand), nil, @argvp, @error) then begin + ErrorString := String(error^.message); + DebugMsg(['ExecuteProgram: Error parsing commandline: ', ErrorString]); + g_error_free(error); + Exit; end; - if ConfUseLibcSystem then begin - s := s + ' &'; - DebugMsg([s]); - DebugMsg(['**** Running system']); - x := libc_system(PChar(s)); - Result := x <> -1; // -1 means fork failed - DebugMsg(['**** Running system = ', x, ' --- done']); - end else begin - if Length(Args) = 0 then Exit; - for x := 0 to Length(Args) - 1 do Args[x] := RemoveQuotation(Args[x]); - DebugMsg(['**** Running spawn']); - x := -1; - try - x := SpawnProcess(Args[0], Running, Args); - except - on E: Exception do DebugMsg(['ExecuteProgram(AppCMDLine = ''', AppCMDLine, '''): Exception: ', E.Message]); + for i := 0 to g_strv_length(argvp) - 1 do begin + if strstr(argvp[i], '%s') <> nil then begin + p := argvp[i]; + argvp[i] := g_strdup_printf(p, [PChar(AppCMDLine)]); + g_free(p); end; - DebugMsg(['**** Running spawn -- done']); - Result := Running; - if not Running then ErrorSignal := x; + if strstr(argvp[i], '%cwd') <> nil then begin + // TODO: g_shell_quote() the argument? + s := ReplaceStr(String(argvp[i]), '%cwd', QuoteStr(CWD)); + g_free(argvp[i]); + argvp[i] := g_strdup(PChar(s)); + end; + end; + end else begin + if not g_shell_parse_argv(PChar(s), nil, @argvp, @error) then begin + ErrorString := String(error^.message); + DebugMsg(['ExecuteProgram: Error parsing commandline: ', ErrorString]); + g_error_free(error); + Exit; end; + end; - except + if ParamDebug then + for i := 0 to g_strv_length(argvp) - 1 do + DebugMsg([' argvp[', i, '] = "', argvp[i], '"']); + + pcwd := nil; + if Length(CWD) > 0 then pcwd := PChar(CWD); + Result := g_spawn_async(pcwd, argvp, nil, + [G_SPAWN_SEARCH_PATH, G_SPAWN_STDOUT_TO_DEV_NULL, G_SPAWN_STDERR_TO_DEV_NULL, G_SPAWN_CLOEXEC_PIPES], + nil, nil, nil, @error); + if not Result then begin + ErrorString := String(error^.message); + DebugMsg(['ExecuteProgram: Error spawning command: ', ErrorString]); + g_error_free(error); end; DebugMsg(['*** Running ExecuteProgram end']); end; (********************************************************************************************************************************) function IsItX11App(const Application: string): boolean; -const BSize = 65536; - What = 'libX11.so'; -var stream: PFILE; - Buffer: Pointer; - i: integer; - str: string; +var environ: PPgchar; + argvp: PPgchar; + stdout: Pgchar; + error: PGerror; begin Result := False; DebugMsg(['***** function IsItX11App(''', Application, ''') begin --']); - try -// setenv('LD_TRACE_LOADED_OBJECTS', '1', True); - stream := popen(PChar('LD_TRACE_LOADED_OBJECTS=1 ' + Application), 'r'); -// stream := popen(PChar(Application), 'r'); - DebugMsg(['***** IsItX11App: popen OK']); - if Assigned(stream) then begin - Buffer := malloc(BSize); - if buffer = nil then Writeln('buffer nil: ', integer(errno)); - if stream = nil then Writeln('stream nil'); - memset(Buffer, 0, BSize); - DebugMsg(['***** IsItX11App: malloc() OK']); - - while feof(stream) = 0 do begin - i := fread(Buffer, 1, BSize, stream); - if i > 0 then begin - SetLength(str, i); - memcpy(@str[1], Buffer, i); - Result := Result or (Pos(What, str) > 0); - end; - end; - pclose(stream); - libc_free(Buffer); - SetLength(str, 0); - end; -// unsetenv('LD_TRACE_LOADED_OBJECTS'); - - except - on E: Exception do DebugMsg(['*** IsItX11App(''', Application, '''):Exception: ', E.Message]); + error := nil; + stdout := nil; + if not g_shell_parse_argv(PChar(Application), nil, @argvp, @error) then begin + DebugMsg(['IsItX11App: Error parsing commandline: ', String(error^.message)]); + g_error_free(error); + Exit; end; + + environ := g_get_environ(); + environ := g_environ_setenv(environ, 'LD_TRACE_LOADED_OBJECTS', '1', True); + if not g_spawn_sync(nil, argvp, environ, + [G_SPAWN_SEARCH_PATH, G_SPAWN_STDERR_TO_DEV_NULL, G_SPAWN_CLOEXEC_PIPES], + nil, nil, @stdout, nil, nil, @error) + then begin + DebugMsg(['IsItX11App: Error spawning command: ', String(error^.message)]); + g_error_free(error); + end else Result := strstr(stdout, 'libX11.so') <> nil; + + g_free(stdout); + g_strfreev(environ); + g_strfreev(argvp); + DebugMsg(['***** function IsItX11App(''', Application, ''') = ', Result]); end; -function HandleSystemCommand(const Command, ErrorText: string): boolean; -const BSize = 65536; -var stream: PFILE; - Buffer: Pointer; - i, NumRead: integer; - child_pid: __pid_t; - fds: array[0..1] of integer; - Parameters: TOpenStringArray; - args_list: System.PPChar; - Temp, s: string; +function HandleSystemCommand(const Command: string; var ErrorString: string): boolean; +var argvp: PPgchar; + stderr: Pgchar; + wait_status: gint; + error: PGerror; begin Result := False; DebugMsg(['***** function HandleSystemCommand(''', Command, ''') begin --']); - try - DebugMsg(['***** HandleSystemCommand: before fork']); - pipe(@fds); - child_pid := fork; - DebugMsg(['***** HandleSystemCommand: fork, child_pid = ', child_pid]); - - - // Main application - if child_pid <> 0 then begin - libc_close(fds[1]); - stream := fdopen(fds[0], 'r'); - Buffer := malloc(BSize); -// DebugMsg(['x0']); - memset(Buffer, 0, BSize); -// DebugMsg(['x1']); - if buffer = nil then Writeln('buffer nil: ', integer(errno)); - if stream = nil then Writeln('stream nil'); - - SetLength(s, 0); - while feof(stream) = 0 do begin - NumRead := fread(Buffer, 1, BSize, stream); - DebugMsg(['***** HandleSystemCommand: NumRead = ', NumRead]); - if NumRead > 0 then begin - SetLength(s, Length(s) + NumRead); - memcpy(@s[Length(s) - NumRead + 1], Buffer, NumRead); - end; - end; - libc_close(fds[0]); -// DebugMsg(['x2']); - TrimCRLFESC(s); -// DebugMsg(['x3']); - - libc_free(Buffer); -// DebugMsg(['x4']); - end + error := nil; + stderr := nil; + if not g_shell_parse_argv(PChar(Command), nil, @argvp, @error) then begin + ErrorString := String(error^.message); + DebugMsg(['HandleSystemCommand: Error parsing commandline: ', ErrorString]); + g_error_free(error); + Exit; + end; - // forked PID - else begin - args_list := nil; - try - SplitArgs(Parameters, Command); - // Fill the args_list array - if Length(Parameters) > 0 then begin - args_list := malloc((Length(Parameters) + 1) * SizeOf(PChar)); - memset(args_list, 0, (Length(Parameters) + 1) * SizeOf(PChar)); - for I := 0 to Length(Parameters) - 1 do - begin - Temp := Parameters[i]; -// PCharArray(args_list^)[I] := malloc(Length(Temp)+1); -// memset(PCharArray(args_list^)[I], 0, Length(Temp)+1); -// StrCopy(PCharArray(args_list^)[I], PChar(Temp)); - PCharArray(args_list^)[I] := strdup(PChar(Temp)); - end; - PCharArray(args_list^)[Length(Parameters)] := nil; - end; - except - on E: Exception do DebugMsg(['*** forked ** function HandleSystemCommand(''', Command, '''):Exception: ', E.Message]); - end; + Result := g_spawn_sync(nil, argvp, nil, [G_SPAWN_SEARCH_PATH, G_SPAWN_CLOEXEC_PIPES], + nil, nil, nil, @stderr, @wait_status, @error); + if Result then Result := g_spawn_check_exit_status(wait_status, @error); + if not Result then begin + if (stderr <> nil) and (strlen(stderr) > 0) + then ErrorString := String(stderr) + else ErrorString := String(error^.message); + DebugMsg(['HandleSystemCommand:: Error spawning command: ', ErrorString]); + g_error_free(error); + end; - libc_close(fds[0]); // Close copy of reader file descriptor - dup2(fds[1], STDERR_FILENO); - execvp(PChar(Parameters[0]), args_list); - DebugMsg(['***** HandleSystemCommand: failed execvp: something went wrong...']); - WriteLn(erroutput, 'Error executing command'); - _exit(ConstERRSpawn); - end; + g_free(stderr); + g_strfreev(argvp); - Result := Length(s) = 0; - if not Result then Application.MessageBox(Format('%s%s', [ErrorText, StrToUTF8(s)]), [mbOK], mbError, mbOK, mbOK); - SetLength(s, 0); - except - on E: Exception do DebugMsg(['***** function HandleSystemCommand(''', Command, '''):Exception: ', E.Message]); - end; DebugMsg(['***** finished function HandleSystemCommand(''', Command, ''') = ', Result]); end; @@ -1672,44 +1497,6 @@ begin end; (********************************************************************************************************************************) - -procedure signal_proc(signal_number: integer); cdecl; -var {pid,} status: integer; -begin -// !!!!!!!!!! Warning -// There should be no debug outputs in this function because it probably cause program freezes after fork -// I mean REALLY NO outputs to console - -// DebugMsg(['SIGCHLD signal received']); -// DebugMsg(['Signal received: ', signal_number]); -// DebugMsg(['*** Signal received: ', signal_number, ' = ', GetSignalString(signal_number)]); - case signal_number of -{ SIGUSR1: begin - DebugMsg(['begin wait']); - wait(@status); - DebugMsg(['end wait']); - ChildExitStatus := status; - end;} - SIGCHLD, SIGUSR1: begin -// DebugMsg(['begin wait']); -// wait(@status); - {pid :=} waitpid(-1, @status, WNOHANG); -// DebugMsg(['**** waitpid result: pid = ', pid, ', status = ', status]); -// DebugMsg(['end wait']); - if signal_number = SIGUSR1 then ChildExitStatus := status; - end; - end; -end; - -procedure SetupSignals; -var sigchld_action: _sigaction; -begin - memset(@sigchld_action, 0, SizeOf(__sigaction)); - sigchld_action.__sigaction_handler := @signal_proc; - sigaction(SIGUSR1, @sigchld_action, nil); - sigaction(SIGCHLD, @sigchld_action, nil); -end; - procedure SetupColors; begin if Assigned(NormalItemGDKColor) then gdk_rgba_free(NormalItemGDKColor); @@ -1844,7 +1631,6 @@ initialization // Kylix behaves fine, only forward slash is honored. AllowDirectorySeparators := ['/']; InternalLockInit(True); - SetupSignals; NormalItemGDKColor := nil; ActiveItemGDKColor := nil; diff --git a/UCoreWorkers.pas b/UCoreWorkers.pas index cbf5124..8e2207e 100644 --- a/UCoreWorkers.pas +++ b/UCoreWorkers.pas @@ -20,7 +20,7 @@ unit UCoreWorkers; interface -uses lazglib2, lazgobject2, lazgtk3, SyncObjs, Classes, UnixType, GTKForms, ULibc, UEngines, UCoreUtils, UVFSCore, uVFSprototypes, UCore, UDirDelete; +uses lazglib2, lazgobject2, lazgtk3, SyncObjs, Classes, UnixType, pthreads, GTKForms, ULibc, UEngines, UCoreUtils, UVFSCore, uVFSprototypes, UCore, UDirDelete; type TWorkerThreadJobType = (WORKER_JOB_DUMMY, WORKER_JOB_DELETE, WORKER_JOB_COPY, WORKER_JOB_MOVE, WORKER_JOB_EXTRACT_TO_TEMP, diff --git a/ULibc.pas b/ULibc.pas index cf3e528..d445e62 100644 --- a/ULibc.pas +++ b/ULibc.pas @@ -25,7 +25,6 @@ interface const GLIBC_LIB = 'libc.so.6'; DL_LIB = 'libdl.so.2'; - PTHREAD_LIB = 'libpthread.so.0'; type cUShort = Word; @@ -53,7 +52,6 @@ type clock_t = Cardinal; {$ENDIF} - sig_atomic_t = Longint; error_t = Integer; __mode_t = DWORD; __dev_t = QWORD; @@ -71,10 +69,6 @@ type __blkcnt64_t = Int64; - Pidtype_t = ^idtype_t; - idtype_t = (P_ALL,P_PID,P_PGID); - - Psiginfo_t = Pointer; Prusage = Pointer; PDIR = Pointer; PFILE = Pointer; @@ -278,170 +272,6 @@ type end; PPGroup = ^PGroup; - Psigval = ^sigval; - sigval = record - case longint of - 0 : ( sival_int : longint ); - 1 : ( sival_ptr : pointer ); - end; - sigval_t = sigval; - Psigval_t = ^sigval_t; - -const - _SIGSET_NWORDS = 1024 div (8 * (sizeof(dword))); - -type - __sighandler_t = procedure(SigNum: Integer); cdecl; - P__sigset_t = ^__sigset_t; - __sigset_t = record - __val : array[0..(_SIGSET_NWORDS)-1] of dword; - end; - sigset_t = __sigset_t; - Psigset_t = ^sigset_t; - P_sigaction = ^_sigaction; - _sigaction = record // Renamed, avoid conflict with sigaction function - case integer of - 1: (sa_handler : __sighandler_t; - sa_mask : __sigset_t; - sa_flags : longint; - sa_restorer : procedure ;cdecl; - ); - // Kylix compatibility - 2: (__sigaction_handler: __sighandler_t); - end; - TSigAction = _sigaction; - PSigAction = ^TSigAction; - TRestoreHandler = procedure; cdecl; - __sigaction = _sigaction; - TSigActionHandler = procedure(Signal: Integer); cdecl; - -const - EPERM = 1; - ENOENT = 2; - ESRCH = 3; - EINTR = 4; - EIO = 5; - ENXIO = 6; - E2BIG = 7; - ENOEXEC = 8; - EBADF = 9; - ECHILD = 10; - EAGAIN = 11; - ENOMEM = 12; - EACCES = 13; - EFAULT = 14; - ENOTBLK = 15; - EBUSY = 16; - EEXIST = 17; - EXDEV = 18; - ENODEV = 19; - ENOTDIR = 20; - EISDIR = 21; - EINVAL = 22; - ENFILE = 23; - EMFILE = 24; - ENOTTY = 25; - ETXTBSY = 26; - EFBIG = 27; - ENOSPC = 28; - ESPIPE = 29; - EROFS = 30; - EMLINK = 31; - EPIPE = 32; - EDOM = 33; - ERANGE = 34; - EDEADLK = 35; - ENAMETOOLONG = 36; - ENOLCK = 37; - ENOSYS = 38; - ENOTEMPTY = 39; - ELOOP = 40; - EWOULDBLOCK = EAGAIN; - ENOMSG = 42; - EIDRM = 43; - ECHRNG = 44; - EL2NSYNC = 45; - EL3HLT = 46; - EL3RST = 47; - ELNRNG = 48; - EUNATCH = 49; - ENOCSI = 50; - EL2HLT = 51; - EBADE = 52; - EBADR = 53; - EXFULL = 54; - ENOANO = 55; - EBADRQC = 56; - EBADSLT = 57; - EDEADLOCK = EDEADLK; - EBFONT = 59; - ENOSTR = 60; - ENODATA = 61; - ETIME = 62; - ENOSR = 63; - ENONET = 64; - ENOPKG = 65; - EREMOTE = 66; - ENOLINK = 67; - EADV = 68; - ESRMNT = 69; - ECOMM = 70; - EPROTO = 71; - EMULTIHOP = 72; - EDOTDOT = 73; - EBADMSG = 74; - EOVERFLOW = 75; - ENOTUNIQ = 76; - EBADFD = 77; - EREMCHG = 78; - ELIBACC = 79; - ELIBBAD = 80; - ELIBSCN = 81; - ELIBMAX = 82; - ELIBEXEC = 83; - EILSEQ = 84; - ERESTART = 85; - ESTRPIPE = 86; - EUSERS = 87; - ENOTSOCK = 88; - EDESTADDRREQ = 89; - EMSGSIZE = 90; - EPROTOTYPE = 91; - ENOPROTOOPT = 92; - EPROTONOSUPPORT = 93; - ESOCKTNOSUPPORT = 94; - EOPNOTSUPP = 95; - EPFNOSUPPORT = 96; - EAFNOSUPPORT = 97; - EADDRINUSE = 98; - EADDRNOTAVAIL = 99; - ENETDOWN = 100; - ENETUNREACH = 101; - ENETRESET = 102; - ECONNABORTED = 103; - ECONNRESET = 104; - ENOBUFS = 105; - EISCONN = 106; - ENOTCONN = 107; - ESHUTDOWN = 108; - ETOOMANYREFS = 109; - ETIMEDOUT = 110; - ECONNREFUSED = 111; - EHOSTDOWN = 112; - EHOSTUNREACH = 113; - EALREADY = 114; - EINPROGRESS = 115; - ESTALE = 116; - EUCLEAN = 117; - ENOTNAM = 118; - ENAVAIL = 119; - EISNAM = 120; - EREMOTEIO = 121; - EDQUOT = 122; - ENOMEDIUM = 123; - EMEDIUMTYPE = 124; - ENOTSUP = EOPNOTSUPP; - ECANCELED = 125; const __S_IFMT = $F000; @@ -501,23 +331,6 @@ const S_IXOTH = S_IXGRP shr 3; S_IRWXO = S_IRWXG shr 3; -const - ACCESSPERMS = (S_IRWXU or S_IRWXG) or S_IRWXO; - ALLPERMS = ((((S_ISUID or S_ISGID) or S_ISVTX) or S_IRWXU) or S_IRWXG) or S_IRWXO; - DEFFILEMODE = ((((S_IRUSR or S_IWUSR) or S_IRGRP) or S_IWGRP) or S_IROTH) or S_IWOTH; - S_BLKSIZE = 512; - -const - DT_UNKNOWN = 0; - DT_FIFO = 1; - DT_CHR = 2; - DT_DIR = 4; - DT_BLK = 6; - DT_REG = 8; - DT_LNK = 10; - DT_SOCK = 12; - DT_WHT = 14; - const RTLD_LAZY = $00001; RTLD_NOW = $00002; @@ -528,96 +341,8 @@ const RTLD_NODELETE = $01000; const - _PATH_DEFPATH = '/usr/bin:/bin'; - _PATH_STDPATH = '/usr/bin:/bin:/usr/sbin:/sbin'; - _PATH_BSHELL = '/bin/sh'; - _PATH_CONSOLE = '/dev/console'; - _PATH_CSHELL = '/bin/csh'; - _PATH_DEVDB = '/var/run/dev.db'; - _PATH_DEVNULL = '/dev/null'; - _PATH_DRUM = '/dev/drum'; - _PATH_KLOG = '/proc/kmsg'; - _PATH_KMEM = '/dev/kmem'; - _PATH_LASTLOG = '/var/log/lastlog'; - _PATH_MAILDIR = '/var/mail'; - _PATH_MAN = '/usr/share/man'; - _PATH_MEM = '/dev/mem'; _PATH_MNTTAB = '/etc/fstab'; _PATH_MOUNTED = '/etc/mtab'; - _PATH_NOLOGIN = '/etc/nologin'; - _PATH_PRESERVE = '/var/lib'; - _PATH_RWHODIR = '/var/spool/rwho'; - _PATH_SENDMAIL = '/usr/sbin/sendmail'; - _PATH_SHADOW = '/etc/shadow'; - _PATH_SHELLS = '/etc/shells'; - _PATH_TTY = '/dev/tty'; - _PATH_UNIX = '/boot/vmlinux'; - _PATH_UTMP = '/var/run/utmp'; - _PATH_VI = '/usr/bin/vi'; - _PATH_WTMP = '/var/log/wtmp'; - _PATH_DEV = '/dev/'; - _PATH_TMP = '/tmp/'; - _PATH_VARDB = '/var/db/'; - _PATH_VARRUN = '/var/run/'; - _PATH_VARTMP = '/var/tmp/'; - -const - WCOREFLAG = $80; - -const - SIG_ERR = (-1); - SIG_DFL = (0); - SIG_IGN = (1); - SIG_HOLD = (2); - -const - SIGHUP = 1; - SIGINT = 2; - SIGQUIT = 3; - SIGILL = 4; - SIGTRAP = 5; - SIGABRT = 6; - SIGIOT = 6; - SIGBUS = 7; - SIGFPE = 8; - SIGKILL = 9; - SIGUSR1 = 10; - SIGSEGV = 11; - SIGUSR2 = 12; - SIGPIPE = 13; - SIGALRM = 14; - SIGTERM = 15; - SIGSTKFLT = 16; - SIGCHLD = 17; - SIGCLD = SIGCHLD; - SIGCONT = 18; - SIGSTOP = 19; - SIGTSTP = 20; - SIGTTIN = 21; - SIGTTOU = 22; - SIGURG = 23; - SIGXCPU = 24; - SIGXFSZ = 25; - SIGVTALRM = 26; - SIGPROF = 27; - SIGWINCH = 28; - SIGIO = 29; - SIGPOLL = SIGIO; - SIGPWR = 30; - SIGSYS = 31; - SIGUNUSED = 31; - _NSIG = 64; - -const - WNOHANG = 1; - WUNTRACED = 2; - __WALL = $40000000; - __WCLONE = $80000000; - -const - STDIN_FILENO = 0; - STDOUT_FILENO = 1; - STDERR_FILENO = 2; const R_OK = 4; @@ -647,16 +372,6 @@ const O_NOFOLLOW = $20000; O_CLOEXEC = $80000; -const - _STAT_VER_LINUX_OLD = 1; - _STAT_VER_KERNEL = 1; - _STAT_VER_SVR4 = 2; - _STAT_VER_LINUX = 3; - _STAT_VER = _STAT_VER_LINUX; - - _MKNOD_VER_LINUX = 1; - _MKNOD_VER_SVR4 = 2; - _MKNOD_VER = _MKNOD_VER_LINUX; function stat64(const afile: PChar; buf: Pstat64): longint; cdecl; external GLIBC_LIB name 'stat64'; function lstat64(const path: PChar; buf: Pstat64): longint; cdecl; external GLIBC_LIB name 'lstat64'; @@ -693,25 +408,13 @@ function dlsym(handle: Pointer; const symbol: PChar): Pointer; cdecl; external D function dlerror: PChar; cdecl; external GLIBC_LIB name 'dlerror'; function real_libc_malloc(size: size_t): Pointer; cdecl; external GLIBC_LIB name 'malloc'; -{$IFNDEF CPUPOWERPC} function malloc(size: size_t): Pointer; cdecl; external GLIBC_LIB name 'malloc'; -{$ELSE} -function malloc(size: size_t): Pointer; -{$ENDIF} function calloc(nmemb: size_t; size: size_t): Pointer; cdecl; external GLIBC_LIB name 'calloc'; function realloc(ptr: Pointer; size: size_t): Pointer; cdecl; external GLIBC_LIB name 'realloc'; procedure real_libc_free(ptr: Pointer); cdecl; external GLIBC_LIB name 'free'; -{$IFNDEF CPUPOWERPC} procedure free(ptr: Pointer); cdecl; external GLIBC_LIB name 'free'; procedure libc_free(ptr: Pointer); cdecl; external GLIBC_LIB name 'free'; -{$ELSE} -procedure free(ptr: Pointer); -procedure libc_free(ptr: Pointer); -{$ENDIF} -procedure cfree(ptr: Pointer); cdecl; external GLIBC_LIB name 'cfree'; -function memalign(boundary: size_t; size: size_t): Pointer; cdecl; external GLIBC_LIB name 'memalign'; -function valloc(size: size_t): Pointer; cdecl; external GLIBC_LIB name 'valloc'; function memcpy(dest: Pointer; src: Pointer; n: size_t): Pointer; cdecl; external GLIBC_LIB name 'memcpy'; function memmove(dest: Pointer; src: Pointer; n: size_t): Pointer; cdecl; external GLIBC_LIB name 'memmove'; @@ -727,13 +430,8 @@ function strcmp(const s1: PChar; const s2: PChar): Longint; cdecl; external GLIB function strncmp(const s1: PChar; const s2: PChar; n: size_t): Longint; cdecl; external GLIBC_LIB name 'strncmp'; function strcasecmp(const s1: PChar; const s2: PChar): Longint; cdecl; external GLIBC_LIB name 'strcasecmp'; function strncasecmp(const s1: PChar; const s2: PChar; n: size_t): Longint; cdecl; external GLIBC_LIB name 'strncasecmp'; -{$IFNDEF CPUPOWERPC} function strdup(const s: PChar): PChar; cdecl; external GLIBC_LIB name 'strdup'; function strndup(const s: PChar; n: size_t): PChar; cdecl; external GLIBC_LIB name 'strndup'; -{$ELSE} -function strdup(const s: PChar): PChar; -function strndup(const s: PChar; n: size_t): PChar; -{$ENDIF} function strchr(const s: PChar; c: Longint): PChar; cdecl; external GLIBC_LIB name 'strchr'; function strrchr(const s: PChar; c: Longint): PChar; cdecl; external GLIBC_LIB name 'strrchr'; function strstr(const haystack: PChar; const needle: PChar): PChar; cdecl; external GLIBC_LIB name 'strstr'; @@ -745,7 +443,6 @@ function strlen(const s: PChar): size_t; cdecl; external GLIBC_LIB name 'strlen' function strnlen(const s: PChar; maxlen: size_t): size_t; cdecl; external GLIBC_LIB name 'strnlen'; function strerror(errnum: Longint): PChar; cdecl; external GLIBC_LIB name 'strerror'; function strerror_r(errnum: Longint; buf: PChar; buflen: size_t): PChar; cdecl; external GLIBC_LIB name 'strerror_r'; -function strsignal(sig: Longint): PChar; cdecl; external GLIBC_LIB name 'strsignal'; function __chdir(const path: PChar): Longint; cdecl; external GLIBC_LIB name 'chdir'; function chdir(const path: PChar): Longint; cdecl; external GLIBC_LIB name 'chdir'; @@ -754,8 +451,6 @@ function libc_chdir(const path: PChar): Longint; cdecl; external GLIBC_LIB name function errno : error_t; function __errno_location: PInteger; cdecl; external GLIBC_LIB name '__errno_location'; -function fork: __pid_t; cdecl; external GLIBC_LIB name 'fork'; -function vfork: __pid_t; cdecl; external GLIBC_LIB name 'vfork'; function link(const oldpath: PChar; const newpath: PChar): Longint; cdecl; external GLIBC_LIB name 'link'; function symlink(const oldpath: PChar; const newpath: PChar): Longint; cdecl; external GLIBC_LIB name 'symlink'; function readlink(const path: PChar; buf: PChar; bufsiz: size_t): Longint; cdecl; external GLIBC_LIB name 'readlink'; @@ -767,11 +462,6 @@ function remove(const pathname: PChar): Longint; cdecl; external GLIBC_LIB name function libc_remove(const pathname: PChar): Longint; cdecl; external GLIBC_LIB name 'remove'; function __rename(const oldpath: PChar; const newpath: PChar): Longint; cdecl; external GLIBC_LIB name 'rename'; function libc_rename(const oldpath: PChar; const newpath: PChar): Longint; cdecl; external GLIBC_LIB name 'rename'; -function wait(status: PLongint): __pid_t; cdecl; external GLIBC_LIB name 'wait'; -function waitpid(pid: __pid_t; status: Plongint; options: Longint): __pid_t; cdecl; external GLIBC_LIB name 'waitpid'; -function waitid(idtype: idtype_t; id: __id_t; infop: Psiginfo_t; options: Longint): Longint; cdecl; external GLIBC_LIB name 'waitid'; -function wait3(status: Plongint; options: Longint; rusage: Prusage): __pid_t; cdecl; external GLIBC_LIB name 'wait3'; -function wait4(pid: __pid_t; status: Plongint; options: Longint; rusage: Prusage): __pid_t; cdecl; external GLIBC_LIB name 'wait4'; function opendir(const name: PChar): PDIR; cdecl; external GLIBC_LIB name 'opendir'; function closedir(dir: PDIR): Longint; cdecl; external GLIBC_LIB name 'closedir'; @@ -785,16 +475,6 @@ function getcwd(buf: PChar; size: size_t): PChar; cdecl; external GLIBC_LIB name function get_current_dir_name: PChar; cdecl; external GLIBC_LIB name 'get_current_dir_name'; function getwd(buf: PChar): PChar; cdecl; external GLIBC_LIB name 'getwd'; -function dup(oldfd: Longint): Longint; cdecl; external GLIBC_LIB name 'dup'; -function dup2(oldfd: Longint; newfd: Longint): Longint; cdecl; external GLIBC_LIB name 'dup2'; - -function execve(const filename: PChar; const argv: PPchar; const envp: PPchar): Longint; cdecl; external GLIBC_LIB name 'execve'; -function execv(const path: PChar; const argv: PPchar): Longint; cdecl; external GLIBC_LIB name 'execv'; -function execle(const path: PChar; const arg: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'execle'; -function execl(const path: PChar; const arg: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'execl'; -function execvp(const afile: PChar; const argv: PPchar): Longint; cdecl; external GLIBC_LIB name 'execvp'; -function execlp(const afile: PChar; const arg: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'execlp'; - function getpid: __pid_t; cdecl; external GLIBC_LIB name 'getpid'; function getppid: __pid_t; cdecl; external GLIBC_LIB name 'getppid'; function getpgrp: __pid_t; cdecl; external GLIBC_LIB name 'getpgrp'; @@ -825,41 +505,6 @@ function localtime(timep: Ptime_t): Ptm; cdecl; external GLIBC_LIB name 'localti function ctime(timep: Ptime_t): PChar; cdecl; external GLIBC_LIB name 'ctime'; function usleep(usec: DWord): Longint; cdecl; external GLIBC_LIB name 'usleep'; -function mktemp(template: PChar): PChar; cdecl; external GLIBC_LIB name 'mktemp'; -function mkstemp(template: PChar): Longint; cdecl; external GLIBC_LIB name 'mkstemp'; -function mkstemp64(template: PChar): Longint; cdecl; external GLIBC_LIB name 'mkstemp64'; -function mkdtemp(template: PChar): PChar; cdecl; external GLIBC_LIB name 'mkdtemp'; - -function fprintf(stream: PFILE; const format: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'fprintf'; -function printf(const format: PChar): Longint; cdecl; varargs; external GLIBC_LIB name 'printf'; -function sprintf(s: PChar; const format: PChar): Longint; varargs; cdecl; external GLIBC_LIB name 'sprintf'; -function snprintf(s: PChar; size: size_t; const format: PChar): Longint; varargs; cdecl; external GLIBC_LIB name 'snprintf'; - -function WEXITSTATUS(Status: longint): longint; -function WTERMSIG(Status: longint): longint; -function WSTOPSIG(Status: longint): longint; -function WIFEXITED(Status: longint): Boolean; -function WIFSIGNALED(Status: longint): Boolean; -function WIFSTOPPED(Status: longint): Boolean; -function WCOREDUMP(Status: longint): Boolean; -function W_EXITCODE(ReturnCode, Signal: longint): longint; -function W_STOPCODE(Signal: longint): longint; - -procedure _exit(status: longint); cdecl; external GLIBC_LIB name '_exit'; - -function gethostname(name: PChar; len: size_t): Longint; cdecl; external GLIBC_LIB name 'gethostname'; - -function sigqueue(pid: __pid_t; sig: Longint; val: sigval): Longint; cdecl; external GLIBC_LIB name 'sigqueue'; -function sigaction(sig: Longint; Action: PSigAction; OldAction: PSigAction): Integer; cdecl; external GLIBC_LIB name 'sigaction'; -function __system(const command: PChar): Longint; cdecl; external GLIBC_LIB name 'system'; -function system(const command: PChar): Longint; cdecl; external GLIBC_LIB name 'system'; -function libc_system(const command: PChar): Longint; cdecl; external GLIBC_LIB name 'system'; - -procedure perror(const s: PChar); cdecl; external GLIBC_LIB name 'perror'; -function popen(const command: PChar; const _type: PChar): PFILE; cdecl; external GLIBC_LIB name 'popen'; -function pclose(stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'pclose'; -function pipe(pipedes: Plongint): Longint; cdecl; external GLIBC_LIB name 'pipe'; - function fopen(const path: PChar; const mode: PChar): PFILE; cdecl; external GLIBC_LIB name 'fopen'; function fopen64(const path: PChar; const mode: PChar): PFILE; cdecl; external GLIBC_LIB name 'fopen64'; function fdopen(fd: Longint; mode: PChar): PFILE; cdecl; external GLIBC_LIB name 'fdopen'; @@ -883,11 +528,8 @@ function fsetpos64(stream: PFILE; pos: Pfpos64_t): Longint; cdecl; external GLIB function feof(stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'feof'; function ferror(stream: PFILE): Longint; cdecl; external GLIBC_LIB name 'ferror'; -function fcntl(fd: Longint; cmd: Longint): Longint; cdecl; varargs; external GLIBC_LIB name 'fcntl'; function open(const pathname: PChar; flags: Longint; mode: Longint): Longint; cdecl; varargs; external GLIBC_LIB name 'open'; function open64(const pathname: PChar; flags: Longint; mode: Longint): Longint; cdecl; varargs; external GLIBC_LIB name 'open64'; -function creat(const pathname: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'creat'; -function creat64(const pathname: PChar; mode: __mode_t): Longint; cdecl; external GLIBC_LIB name 'creat64'; function lseek(fd: longint; offset: __off_t; whence: longint):__off_t; cdecl; external GLIBC_LIB name 'lseek'; function lseek64(fd: longint; offset: __off64_t; whence: longint):__off64_t; cdecl; external GLIBC_LIB name 'lseek64'; @@ -908,17 +550,9 @@ function euidaccess(pathname: PChar; mode: Longint): Longint; cdecl; external GL function setenv(name: PChar; value: PChar; overwrite: Longint): Longint; cdecl; external GLIBC_LIB name 'setenv'; -type pthread_t = {$ifdef cpu64}QWord{$else}DWord{$endif}; - -function pthread_self: pthread_t; cdecl; external PTHREAD_LIB name 'pthread_self'; - implementation -{$IFDEF CPUPOWERPC} -uses SysUtils; -{$ENDIF} - function errno : error_t; begin Result := __errno_location()^; @@ -964,88 +598,6 @@ begin Result := __S_ISTYPE(mode, __S_IFSOCK); end; -Function WEXITSTATUS(Status: longint): longint; -begin - Result:=(Status and $FF00) shr 8; -end; - - -Function WTERMSIG(Status: longint): longint; -begin - Result:=(Status and $7F); -end; - - -Function WSTOPSIG(Status: longint): longint; -begin - Result:=WEXITSTATUS(Status); -end; - - -Function WIFEXITED(Status: longint): Boolean; -begin - Result:=(WTERMSIG(Status)=0); -end; - - -Function WIFSIGNALED(Status: longint): Boolean; -begin - Result:=(not WIFSTOPPED(Status)) and (not WIFEXITED(Status)); -end; - - -Function WIFSTOPPED(Status: longint): Boolean; -begin - Result:=((Status and $FF)=$7F); -end; - - -Function WCOREDUMP(Status: longint): Boolean; -begin - Result:=((Status and WCOREFLAG)<>0); -end; - - -Function W_EXITCODE(ReturnCode, Signal: longint): longint; -begin - Result:=(ReturnCode shl 8) or Signal; -end; - - -Function W_STOPCODE(Signal: longint): longint; -begin - Result:=(Signal shl 8) or $7F; -end; - - -{$IFDEF CPUPOWERPC} -function malloc(size: size_t): Pointer; -begin - Result := GetMem(size); -end; - -procedure libc_free(ptr: Pointer); -begin - FreeMem(ptr); -end; - -procedure free(ptr: Pointer); -begin - libc_free(ptr); -end; - -function strdup(const s: PChar): PChar; -begin - Result := GetMem(strlen(s) + 1); - SysUtils.StrLCopy(Result, s, strlen(s) + 1); -end; - -function strndup(const s: PChar; n: size_t): PChar; -begin - Result := GetMem(n + 1); - SysUtils.StrLCopy(Result, s, n); -end; -{$ENDIF} end. diff --git a/UMain.pas b/UMain.pas index 47be5c7..5c96866 100644 --- a/UMain.pas +++ b/UMain.pas @@ -1658,7 +1658,7 @@ begin RightPathLabelEventBox.ControlState := csSelected; s := RightPathLabel.Caption; end; - CommandLineLabel.Caption := Format('%s@%s:%s>', [GetUserName, GetHostName, s]); + CommandLineLabel.Caption := Format('%s@%s:%s>', [GetUserName, String(g_get_host_name()), s]); UpdateCaption; miDisconnect.Enabled := (LeftLastFocused and (LeftPanelEngine is TVFSEngine) and (not TVFSEngine(LeftPanelEngine).ArchiveMode)) or ((not LeftLastFocused) and (RightPanelEngine is TVFSEngine) and (not TVFSEngine(RightPanelEngine).ArchiveMode)); @@ -1936,7 +1936,7 @@ begin RightPathLabel.UseMarkup := True; if LeftLastFocused then s := LeftPathLabel.Caption else s := RightPathLabel.Caption; - CommandLineLabel.Caption := Format('%s@%s:%s>', [GetUserName, GetHostName, s]); + CommandLineLabel.Caption := Format('%s@%s:%s>', [GetUserName, String(g_get_host_name()), s]); LeftPanelEngine.GetFileSystemInfo(LeftPanelEngine.Path, FSSize, FSFree, FSName); // *TODO: hide numbers if filesystem info cannot be determined if FSSize < 0 then FSSize := 0; @@ -3432,8 +3432,9 @@ end; procedure TFMain.EditViewFileInternal(Filename: string; Engine: TPanelEngine; View, NewFile: boolean); var s: string; + Error: string; Stat: PDataItem; - Error, x: integer; + x: integer; // AViewer: TViewerThread; AViewer: TFViewer; begin @@ -3469,7 +3470,7 @@ begin if View then x := ConfViewerTerminalBehaviour else x := ConfEditorTerminalBehaviour; if not ExecuteProgram(Format('%s %s', [s, QuoteStr(Filename)]), ExtractFilePath(Filename), x = 0, x = 1, Error) then - Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [s]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration + #10#10'%s', [s, StrToUTF8(Error)]), [mbOK], mbError, mbNone, mbOK); end; end; @@ -3506,6 +3507,7 @@ end; procedure TFMain.RunFile(Path: string; Engine: TPanelEngine; CustomAction: integer); var Command, FileTypeDesc: string; + Error: string; i, ac: integer; b, AutodetectGUI, RunInTerminal: boolean; Stat: PDataItem; @@ -3516,9 +3518,10 @@ begin InternalLock; Command := ''; FileTypeDesc := ''; + Error := ''; AutodetectGUI := True; RunInTerminal := False; - + Assoc := FindAssoc(ExtractFileName(Path)); if Assoc <> nil then begin FileTypeDesc := Assoc.FileTypeName; @@ -3546,7 +3549,7 @@ begin if Engine is TVFSEngine then b := HandleRunFromArchive(Path, Engine, Command, FileTypeDesc, False); // not a local engine, extract to local first if b then begin libc_chdir(PChar(ExtractFilePath(Path))); - b := ExecuteProgram(QuoteStr(Path), ExtractFilePath(Path), AutodetectGUI, RunInTerminal, i); + b := ExecuteProgram(QuoteStr(Path), ExtractFilePath(Path), AutodetectGUI, RunInTerminal, Error); libc_chdir(PChar('/')); end else b := True; // Mask cancelled extraction from VFS FreeDataItem(Stat); @@ -3570,11 +3573,11 @@ begin // DebugMsg(['execute: ', s, ' , ', Command, ' , ', QuoteStr(Path)]); if b then begin libc_chdir(PChar(ExtractFilePath(Path))); - b := ExecuteProgram(s, ExtractFilePath(Path), AutodetectGUI, RunInTerminal, i); + b := ExecuteProgram(s, ExtractFilePath(Path), AutodetectGUI, RunInTerminal, Error); libc_chdir(PChar('/')); end else b := True; // Mask cancelled extraction from VFS end; - if not b then Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [s]), [mbOK], mbError, mbNone, mbOK); + if not b then Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration + #10#10'%s', [s, StrToUTF8(Error)]), [mbOK], mbError, mbNone, mbOK); finally Application.ProcessMessages; InternalUnLock; @@ -3582,10 +3585,11 @@ begin end; procedure TFMain.CommandLineComboKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean); -var Error, OldPos, i: integer; +var OldPos, i: integer; AListView: TGTKListView; Engine: TPanelEngine; s, s2, Orig: string; + Error: string; begin try InternalLock; @@ -3626,7 +3630,7 @@ begin while not (Engine is TLocalTreeEngine) do Engine := Engine.ParentEngine; libc_chdir(PChar(Engine.Path)); if not ExecuteProgram(UTF8ToStr(Orig), Engine.Path, ConfCmdLineTerminalBehaviour = 0 , ConfCmdLineTerminalBehaviour = 1, Error) then - Application.MessageBox(LANGErrorExecutingCommand, [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(LANGErrorExecutingCommand + Format(#10#10'%s', [StrToUTF8(Error)]), [mbOK], mbError, mbNone, mbOK); libc_chdir('/'); end; end; @@ -4180,12 +4184,13 @@ var Engine: TPanelEngine; DataItem: PDataItem; AListView: TGTKListView; FileName, ShortFName, s: string; - SpawnError: integer; + SpawnError: string; Error: PGError; b: boolean; begin try InternalLock; + SpawnError := ''; if (not Assigned(Sender)) or (not (Sender is TGTKMenuItem)) then begin DebugMsg(['Error: Popup menuitem is invalid']); end; @@ -4220,7 +4225,7 @@ begin b := ExecuteProgram(QuoteStr(FileName), ExtractFilePath(FileName), True, False, SpawnError); libc_chdir(PChar('/')); end else b := True; // Mask cancelled extraction from VFS - if not b then Application.MessageBox(LANGErrorExecutingCommand, [mbOK], mbError, mbNone, mbOK); + if not b then Application.MessageBox(LANGErrorExecutingCommand + Format(#10#10'%s', [StrToUTF8(SpawnError)]), [mbOK], mbError, mbNone, mbOK); end; 2: if Application.MessageBox(Format(LANGThereIsNoApplicationAssociatedWithS, [ShortFName]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes then miFileTypesClick(Self); @@ -4237,7 +4242,7 @@ begin TAssocAction((Sender as TGTKMenuItem).Data).RunInTerminal, SpawnError); libc_chdir(PChar('/')); end else b := True; // Mask cancelled extraction from VFS - if not b then Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [FileName]), [mbOK], mbError, mbNone, mbOK); + if not b then Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration + #10#10'%s', [FileName, StrToUTF8(SpawnError)]), [mbOK], mbError, mbNone, mbOK); end; end; FreeDataItem(DataItem); @@ -6027,15 +6032,17 @@ end; procedure TFMain.OpenTerminalButtonClick(Sender: TObject); var CurrentPath: string; AEngine: TPanelEngine; - Error: integer; + Error: string; + s: string; begin - Error := 0; if LeftLastFocused then AEngine := LeftPanelEngine else AEngine := RightPanelEngine; while not (AEngine is TLocalTreeEngine) do AEngine := AEngine.ParentEngine; CurrentPath := AEngine.Path; libc_chdir(PChar(CurrentPath)); - ExecuteProgram('bash', CurrentPath, False, True, Error); + s := 'bash'; + if not ExecuteProgram(s, CurrentPath, False, True, Error) then + Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration + #10#10'%s', [s, StrToUTF8(Error)]), [mbOK], mbError, mbNone, mbOK); libc_chdir('/'); end; @@ -6187,7 +6194,7 @@ var s: string; begin s := IncludeTrailingPathDelimiter(ConfTempPath) + 'tuxcmd-XXXXXX'; tmp := strdup(PChar(s)); - tmp := mkdtemp(tmp); + tmp := g_mkdtemp(tmp); if tmp = nil then begin err := errno; DebugMsg(['(EE) ExtractFromArchive: Couldn''t create temporary directory: ', strerror(err)]); @@ -6276,7 +6283,7 @@ var LeftPanel: boolean; SourceListView, TargetListView: TGTKListView; SourceEngine, TargetEngine: TPanelEngine; SourceFile, TargetFile: string; - Error: integer; + Error: string; begin if LeftListView.Focused then LeftPanel := True else if RightListView.Focused then LeftPanel := False else @@ -6313,7 +6320,7 @@ begin if not HandleRunFromArchive(TargetFile, TargetEngine, '', '', True) then Exit; if not ExecuteProgram(Format('%s %s %s', [ConfDiffCommand, QuoteStr(SourceFile), QuoteStr(TargetFile)]), SourceEngine.Path, ConfDiffTerminalBehaviour = 0, ConfDiffTerminalBehaviour = 1, Error) then - Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [ConfDiffCommand]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration + #10#10'%s', [ConfDiffCommand, StrToUTF8(Error)]), [mbOK], mbError, mbNone, mbOK); end; procedure TFMain.miSynchronizeDirsClick(Sender: TObject); @@ -6321,7 +6328,7 @@ var LeftPanel: boolean; SourceListView, TargetListView: TGTKListView; SourceEngine, TargetEngine: TPanelEngine; SourceDir, TargetDir: string; - Error: integer; + Error: string; begin if LeftListView.Focused then LeftPanel := True else if RightListView.Focused then LeftPanel := False else @@ -6366,7 +6373,7 @@ begin if not HandleRunFromArchive(TargetDir, TargetEngine, '', '', True) then Exit; if not ExecuteProgram(Format('%s %s %s', [ConfDiffDirCommand, QuoteStr(SourceDir), QuoteStr(TargetDir)]), SourceEngine.Path, ConfDiffDirTerminalBehaviour = 0, ConfDiffDirTerminalBehaviour = 1, Error) then - Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [ConfDiffDirCommand]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration + #10#10'%s', [ConfDiffDirCommand, StrToUTF8(Error)]), [mbOK], mbError, mbNone, mbOK); end; diff --git a/UPreferences.pas b/UPreferences.pas index deee0f0..50b2e29 100644 --- a/UPreferences.pas +++ b/UPreferences.pas @@ -22,9 +22,8 @@ unit UPreferences; interface uses - SysUtils, Classes, lazgdk3, lazgtk3, lazpango1, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, - GTKUtils, GTKDialogs, GTKPixbuf, GTKClasses, GTKMenus, - ULibc; + SysUtils, Classes, unixtype, ULibc, lazgdk3, lazgtk3, lazpango1, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, + GTKUtils, GTKDialogs, GTKPixbuf, GTKClasses, GTKMenus; type TFPreferences = class(TGTKDialog) @@ -45,7 +44,7 @@ type ClearROAttr, DisableMouseRename, ShowFiletypeIcons, DefaultFontCheckBox, DefaultRowHeightCheckBox, LynxLikeMotionCheckBox, DirsInBoldCheckBox, NewStyleAltOCheckBox, DisableFileTipsCheckBox, DisableDirectoryBracketsCheckBox, InsertMovesDownCheckBox, SpaceMovesDownCheckBox, SelectAllDirectoriesCheckBox, ShowFuncButtonsCheckBox, - OctalPermissionsCheckBox, FocusRefreshCheckBox, CompatUseLibcSystemCheckBox: TGTKCheckButton; + OctalPermissionsCheckBox, FocusRefreshCheckBox: TGTKCheckButton; NormalItemFGColorDefault, ActiveItemFGColorDefault, InactiveItemFGColorDefault, LinkItemFGColorDefault, DotFileItemFGColorDefault: TGTKCheckButton; HBox1, HBox2, HBox3, HBox4: TGTKHBox; @@ -1013,13 +1012,6 @@ begin FocusRefreshCheckBox.MarginTop := 2; FocusRefreshCheckBox.MarginBottom := 2; Grid6.AddControl(0, 0, 1, 1, FocusRefreshCheckBox); - CompatUseLibcSystemCheckBox := TGTKCheckButton.CreateWithLabel(Self, LANGPreferencesCompatUseLibcSystemCheckBox_Caption); - CompatUseLibcSystemCheckBox.Tooltip := LANGPreferencesCompatUseLibcSystemCheckBox_Tooltip; - CompatUseLibcSystemCheckBox.MarginStart := 30; - CompatUseLibcSystemCheckBox.MarginEnd := 30; - CompatUseLibcSystemCheckBox.MarginTop := 2; - CompatUseLibcSystemCheckBox.MarginBottom := 2; - Grid6.AddControl(0, 2, 1, 1, CompatUseLibcSystemCheckBox); // ****************** @@ -1174,7 +1166,6 @@ begin ViewerX11AppComboBox.ItemIndex := ConfViewerTerminalBehaviour; EditorX11AppComboBox.ItemIndex := ConfEditorTerminalBehaviour; FocusRefreshCheckBox.Checked := ConfFocusRefresh; - CompatUseLibcSystemCheckBox.Checked := ConfUseLibcSystem; CustomTimeFormatEntry.Text := ConfCustomTimeFormat; CustomDateFormatEntry.Text := ConfCustomDateFormat; @@ -1245,7 +1236,6 @@ begin ConfViewerTerminalBehaviour := ViewerX11AppComboBox.ItemIndex; ConfEditorTerminalBehaviour := EditorX11AppComboBox.ItemIndex; ConfFocusRefresh := FocusRefreshCheckBox.Checked; - ConfUseLibcSystem := CompatUseLibcSystemCheckBox.Checked; ConfDisableFileTips := DisableFileTipsCheckBox.Checked; ConfShowFuncButtons := ShowFuncButtonsCheckBox.Checked; -- cgit v1.2.3