From 7d757b8452daed2575e3a9cc300459d7e8674345 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Fri, 11 Oct 2024 23:38:44 +0200 Subject: Full port to GError Started 15 years ago, picking up on that work. Introduced the new TUXCMD_ERROR domain to distinguish between operations or their steps. Plugins may continue reporting the G_IO_ERROR domain. --- UEngines.pas | 235 +++++++++++++++++++++++++---------------------------------- 1 file changed, 100 insertions(+), 135 deletions(-) (limited to 'UEngines.pas') diff --git a/UEngines.pas b/UEngines.pas index 4891314..8a0e9e6 100644 --- a/UEngines.pas +++ b/UEngines.pas @@ -29,8 +29,8 @@ const omRead = 0; omAppend = 2; ConfDefaultDirCreationMask = 755; - - + + type PDataItem = ^TDataItem; TDataItem = record @@ -103,8 +103,8 @@ type // Copy-related routines function GetBlockSize: guint32; virtual; abstract; procedure SetBlockSize(Value: guint32); virtual; abstract; - function CopyFileIn(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer): boolean; virtual; abstract; // returns True if file is successfully copied - function CopyFileOut(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer): boolean; virtual; abstract; // returns True if file is successfully copied + function CopyFileIn(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer; Error: PPGError): boolean; virtual; abstract; // returns True if file is successfully copied + function CopyFileOut(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer; Error: PPGError): boolean; virtual; abstract; // returns True if file is successfully copied function IsOnSameFS(const Path1, Path2: string; FollowSymlinks: boolean): boolean; virtual; abstract; function TwoSameFiles(const Path1, Path2: string; FollowSymlinks: boolean): boolean; virtual; abstract; @@ -153,8 +153,8 @@ type function GetBlockSize: guint32; override; procedure SetBlockSize(Value: guint32); override; - function CopyFileIn(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer): boolean; override; - function CopyFileOut(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer): boolean; override; + function CopyFileIn(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer; Error: PPGError): boolean; override; + function CopyFileOut(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer; Error: PPGError): boolean; override; function IsOnSameFS(const Path1, Path2: string; FollowSymlinks: boolean): boolean; override; function TwoSameFiles(const Path1, Path2: string; FollowSymlinks: boolean): boolean; override; @@ -235,26 +235,21 @@ var Item: PDataItem; Handle: PDIR; DirEnt: PDirent64; Buf: PChar; - saved_errno: integer; - FError: PGError; begin Result := False; try if libc_chdir(PChar(APath)) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error changing directory to ''''%s'''': %s', StrToUTF8(PChar(APath)), g_strerror(saved_errno)); - DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): chdir error: ', strerror(saved_errno)]); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_CHDIR), '%m'); + DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): chdir error: ', strerror(errno)]); Exit; end; Handle := opendir(PChar(APath)); if Handle = nil then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error opening directory ''''%s'''': %s', StrToUTF8(PChar(APath)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_OPENDIR), '%m'); DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): opendir() handle == NULL: ', strerror(errno)]); Exit; end; - FError := nil; repeat DirEnt := readdir64(Handle); if (DirEnt <> nil) and (DirEnt^.d_name[0] <> #0) then begin @@ -269,14 +264,13 @@ begin List.Add(Item); end; end; - until (DirEnt = nil) or (FError <> nil); + until (DirEnt = nil); closedir(Handle); - - if FError <> nil then g_propagate_error(Error, FError) - else Result := True; + Result := True; except on E: Exception do begin Result := False; + tuxcmd_set_error_from_exception(Error, E); DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, ') -Exception: ', E.Message]); Exit; end; @@ -288,14 +282,12 @@ var Item: PDataItem; StatBuf: Pstat64; LnkBuf: array[0..65535] of char; i: integer; - saved_errno: integer; begin StatBuf := malloc(sizeof(Tstat64)); memset(StatBuf, 0, sizeof(Tstat64)); if lstat64(PChar(APath), StatBuf) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error getting file info for ''''%s'''': %s', StrToUTF8(PChar(APath)), g_strerror(saved_errno)); - DebugMsg(['*** TLocalTreeEngine.GetFileInfo(APath=', APath, '): Error reading file via lstat64: ', strerror(saved_errno)]); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_STAT), '%m'); + DebugMsg(['*** TLocalTreeEngine.GetFileInfo(APath=', APath, '): Error reading file via lstat64: ', strerror(errno)]); libc_free(StatBuf); Result := nil; Exit; @@ -388,20 +380,17 @@ end; function TLocalTreeEngine.ChangeDir(const NewPath: string; Error: PPGError): boolean; var APath: string; Handle : PDIR; - saved_errno: integer; begin Result := False; try APath := IncludeTrailingPathDelimiter(NewPath); if libc_chdir(PChar(APath)) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error changing directory to ''''%s'''': %s', StrToUTF8(PChar(NewPath)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_CHDIR), '%m'); Exit; end; Handle := opendir(PChar(APath)); if Handle = nil then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error changing directory to ''''%s'''': %s', StrToUTF8(PChar(NewPath)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_OPENDIR), '%m'); Exit; end; { if not Assigned(readdir(Handle)) then begin @@ -409,14 +398,13 @@ begin Exit; end; } if closedir(Handle) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error changing directory to ''''%s'''': %s', StrToUTF8(PChar(NewPath)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_OPENDIR), '%m'); Exit; end; Result := True; except on E: Exception do begin - Result := False; + tuxcmd_set_error_from_exception(Error, E); DebugMsg(['*** TLocalTreeEngine.ChangeDir(APath=', APath, ') -Exception: ', E.Message]); Exit; end; @@ -476,76 +464,63 @@ end; (********************************************************************************************************************************) function TLocalTreeEngine.MakeDir(const NewDir: string; Error: PPGError): boolean; -var saved_errno: integer; begin Result := False; if __mkdir(PChar(NewDir), OctalToAttr(ConfDefaultDirCreationMask)) <> 0 then begin - if Self.DirectoryExists(NewDir, False) or (@g_mkdir_with_parents = nil) or (g_mkdir_with_parents(PChar(NewDir), OctalToAttr(ConfDefaultDirCreationMask)) <> 0) then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error creating directory ''''%s'''': %s', StrToUTF8(PChar(NewDir)), g_strerror(saved_errno)); - end else Result := True; + if Self.DirectoryExists(NewDir, False) or (@g_mkdir_with_parents = nil) or (g_mkdir_with_parents(PChar(NewDir), OctalToAttr(ConfDefaultDirCreationMask)) <> 0) + then g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_MKDIR), '%m') + else Result := True; end else Result := True; end; (********************************************************************************************************************************) function TLocalTreeEngine.Remove(const APath: string; Error: PPGError): boolean; -var saved_errno: integer; begin Result := False; if libc_remove(PChar(ExcludeTrailingPathDelimiter(APath))) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error deleting ''''%s'''': %s', StrToUTF8(PChar(APath)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_REMOVE), '%m'); end else Result := True; end; (********************************************************************************************************************************) function TLocalTreeEngine.MakeSymLink(const NewFileName, PointTo: string; Error: PPGError): boolean; -var saved_errno: integer; begin Result := False; if symlink(PChar(PointTo), PChar(NewFileName)) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error creating symlink ''''%s'''': %s', StrToUTF8(PChar(NewFileName)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_SYMLINK), '%m'); end else Result := True; end; (********************************************************************************************************************************) function TLocalTreeEngine.Chmod(const FileName: string; Mode: cuLong; Error: PPGError): boolean; -var saved_errno: integer; begin Result := False; if libc_chmod(PChar(FileName), Mode) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error during chmod of ''''%s'''': %s', StrToUTF8(PChar(FileName)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_CHMOD), '%m'); end else Result := True; end; (********************************************************************************************************************************) function TLocalTreeEngine.Chown(const FileName: string; UID, GID: cuLong; Error: PPGError): boolean; -var saved_errno: integer; begin Result := False; if libc_chown(PChar(FileName), UID, GID) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error during chown of ''''%s'''': %s', StrToUTF8(PChar(FileName)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_CHOWN), '%m'); end else Result := True; end; (********************************************************************************************************************************) function TLocalTreeEngine.RenameFile(const SourceFile, DestFile: string; Error: PPGError): boolean; -var saved_errno: integer; begin Result := False; if libc_rename(PChar(SourceFile), PChar(DestFile)) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error renaming file ''''%s'''': %s', StrToUTF8(PChar(SourceFile)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_RENAME), '%m'); end else Result := True; end; (********************************************************************************************************************************) function TLocalTreeEngine.ChangeTimes(const APath: string; mtime, atime: time_t; Error: PPGError): boolean; var timebuf: Putimbuf; - saved_errno: integer; begin Result := False; try @@ -554,87 +529,85 @@ begin timebuf^.actime := atime; timebuf^.modtime := mtime; if utime(PChar(APath), timebuf) <> 0 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error while changing timestamps of ''''%s'''': %s', StrToUTF8(PChar(APath)), g_strerror(saved_errno)); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_TIMESTAMPS), '%m'); end else Result := True; libc_free(timebuf); except - on E: Exception do DebugMsg(['*** Exception raised in TLocalTreeEngine.ChangeTimes(APath=', APath, '): (', E.ClassName, '): ', E.Message]); + on E: Exception do begin + tuxcmd_set_error_from_exception(Error, E); + DebugMsg(['*** Exception raised in TLocalTreeEngine.ChangeTimes(APath=', APath, '): (', E.ClassName, '): ', E.Message]); + Result := False; + end; end; end; (********************************************************************************************************************************) -function TLocalTreeEngine.CopyFileIn(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer): boolean; +function TLocalTreeEngine.CopyFileIn(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer; Error: PPGError): boolean; begin - Result := CopyFileOut(SourceFile, DestFile, Append, ProgressFunc, Sender); + Result := CopyFileOut(SourceFile, DestFile, Append, ProgressFunc, Sender, Error); end; -function TLocalTreeEngine.CopyFileOut(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer): boolean; +function TLocalTreeEngine.CopyFileOut(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer; Error: PPGError): boolean; var fsrc, fdest: PFILE; Buffer: Pointer; BytesDone, BytesRead, BytesWritten: Int64; - Ignore: boolean; - saved_errno: integer; - Error: PGError; begin Result := False; - Error := nil; + BytesDone := 0; try // Open source file for reading fsrc := fopen64(PChar(SourceFile), 'r'); if fsrc = nil then begin - if @ProgressFunc <> nil then begin - saved_errno := errno; - g_set_error(@Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error opening source file ''''%s'''': %s', StrToUTF8(PChar(SourceFile)), g_strerror(saved_errno)); - ProgressFunc(Sender, 0, Error); - g_error_free(Error); - end; + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_SOURCE_OPEN), '%m'); + if @ProgressFunc <> nil then + ProgressFunc(Sender, 0, Error^); Exit; end; // Open target file for writing/appending if Append then fdest := fopen64(PChar(DestFile), 'a') else fdest := fopen64(PChar(DestFile), 'w'); - if fsrc = nil then begin - if @ProgressFunc <> nil then begin - saved_errno := errno; - g_set_error(@Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error opening target file ''''%s'''': %s', StrToUTF8(PChar(DestFile)), g_strerror(saved_errno)); - ProgressFunc(Sender, 0, Error); - g_error_free(Error); - end; + if fdest = nil then begin + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_TARGET_OPEN), '%m'); fclose(fsrc); + if @ProgressFunc <> nil then + ProgressFunc(Sender, 0, Error^); Exit; end; - BytesDone := 0; Buffer := malloc(FBlockSize); + if Buffer = nil then begin + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_ALLOC_FAILED), '%m'); + fclose(fdest); + fclose(fsrc); + if @ProgressFunc <> nil then + ProgressFunc(Sender, 0, Error^); + Exit; + end; while feof(fsrc) = 0 do begin - Error := nil; - // Read block BytesRead := fread(Buffer, 1, FBlockSize, fsrc); if (BytesRead < FBlockSize) and (feof(fsrc) = 0) then begin - Ignore := False; - if @ProgressFunc <> nil then begin - saved_errno := errno; - g_set_error(@Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error reading from source file ''''%s'''': %s', StrToUTF8(PChar(SourceFile)), g_strerror(saved_errno)); - Ignore := ProgressFunc(Sender, BytesDone + BytesRead, Error); - g_error_free(Error); - end; - if Ignore then Continue - else Break; + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_SOURCE_READ), '%m'); + Result := False; + if @ProgressFunc <> nil then + Result := ProgressFunc(Sender, BytesDone + BytesRead, Error^); + if Result then begin + // user has chosen to ignore the error + g_error_free(Error^); + Error^ := nil; + Continue; + end else Break; end; // Write block BytesWritten := fwrite(Buffer, 1, BytesRead, fdest); if BytesWritten < BytesRead then begin - if @ProgressFunc <> nil then begin - saved_errno := ferror(fdest); - g_set_error(@Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error writing to target file ''''%s'''': %s', StrToUTF8(PChar(DestFile)), g_strerror(saved_errno)); - ProgressFunc(Sender, BytesDone + BytesWritten, Error); - g_error_free(Error); - end; + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_TARGET_WRITE), '%m'); + Result := False; + if @ProgressFunc <> nil then + ProgressFunc(Sender, BytesDone + BytesRead, Error^); Break; // We cannot ignore write errors end; @@ -642,34 +615,41 @@ begin if (@ProgressFunc <> nil) and (not ProgressFunc(Sender, BytesDone, nil)) then Break; end; - Result := feof(fsrc) <> 0; + Result := (feof(fsrc) <> 0) and (Error^ = nil); libc_free(Buffer); if fclose(fdest) <> 0 then begin - fclose(fsrc); + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_TARGET_CLOSE), '%m'); Result := False; - if @ProgressFunc <> nil then begin - Error := nil; - saved_errno := errno; - g_set_error(@Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error closing target file ''''%s'''': %s', StrToUTF8(PChar(DestFile)), g_strerror(saved_errno)); - Result := ProgressFunc(Sender, BytesDone, Error); - g_error_free(Error); - end; + if @ProgressFunc <> nil then + ProgressFunc(Sender, BytesDone, Error^); + fclose(fsrc); Exit; end; if fclose(fsrc) <> 0 then begin + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_SOURCE_CLOSE), '%m'); Result := False; - if @ProgressFunc <> nil then begin - Error := nil; - saved_errno := errno; - g_set_error(@Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error closing source file ''''%s'''': %s', StrToUTF8(PChar(SourceFile)), g_strerror(saved_errno)); - Result := ProgressFunc(Sender, BytesDone, Error); - g_error_free(Error); - end; - Exit; + if @ProgressFunc <> nil then + Result := ProgressFunc(Sender, BytesDone, Error^); + if Result then begin + // user has chosen to ignore the error + g_error_free(Error^); + Error^ := nil; + end else Exit; end; except - on E: Exception do DebugMsg(['*** Exception raised in TLocalTreeEngine.CopyFile(Sender=', Sender, ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]); + on E: Exception do begin + Result := False; + tuxcmd_set_error_from_exception(@Error, E); + DebugMsg(['*** Exception raised in TLocalTreeEngine.CopyFile(Sender=', Sender, ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]); + if @ProgressFunc <> nil then + Result := ProgressFunc(Sender, BytesDone, Error^); + if Result then begin + // user has chosen to ignore the error + g_error_free(Error^); + Error^ := nil; + end; + end; end; end; @@ -802,7 +782,6 @@ end; (********************************************************************************************************************************) function TLocalTreeEngine.OpenFile(const APath: string; Mode: integer; Error: PPGError): TEngineFileDes; var m: PChar; - saved_errno: integer; begin case Mode of omRead: m := 'r'; @@ -811,54 +790,40 @@ begin else m := 'r'; end; Result := fopen64(PChar(APath), m); - if Result = nil then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error opening file ''''%s'''': %s', StrToUTF8(PChar(APath)), g_strerror(saved_errno)); - end; + if Result = nil then + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_OPEN_FILE), '%m'); end; (********************************************************************************************************************************) function TLocalTreeEngine.ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; Error: PPGError): integer; -var saved_errno: integer; begin Result := fread(Buffer, 1, ABlockSize, FileDescriptor); - if (Result = 0) and (feof(FileDescriptor) = 0) then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error reading from file: %s', g_strerror(saved_errno)); - end; + if (Result = 0) and (feof(FileDescriptor) = 0) then + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_READ_FILE), '%m'); end; (********************************************************************************************************************************) function TLocalTreeEngine.WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; Error: PPGError): integer; -var saved_errno: integer; begin Result := fwrite(Buffer, 1, BytesCount, FileDescriptor); - if Result < BytesCount then begin - saved_errno := ferror(FileDescriptor); - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error writing to file: %s', g_strerror(saved_errno)); - end; + if Result < BytesCount then + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_WRITE_FILE), '%m'); end; (********************************************************************************************************************************) function TLocalTreeEngine.CloseFile(const FileDescriptor: TEngineFileDes; Error: PPGError): boolean; -var saved_errno: integer; begin Result := fclose(FileDescriptor) = 0; - if not Result then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error closing file: %s', g_strerror(saved_errno)); - end; + if not Result then + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_CLOSE_FILE), '%m'); end; (********************************************************************************************************************************) function TLocalTreeEngine.FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; Error: PPGError): Int64; -var saved_errno: integer; begin Result := fseeko64(FileDescriptor, AbsoluteOffset, SEEK_SET); - if Result = -1 then begin - saved_errno := errno; - g_set_error(Error, G_IO_ERROR, gint(g_io_error_from_errno(saved_errno)), 'Error seeking in file: %s', g_strerror(saved_errno)); - end; + if Result = -1 then + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_SEEK), '%m'); end; (********************************************************************************************************************************) -- cgit v1.2.3