summaryrefslogtreecommitdiff
path: root/UEngines.pas
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2009-12-13 14:32:58 +0100
committerTomas Bzatek <tbzatek@users.sourceforge.net>2009-12-13 14:32:58 +0100
commit0f7616a007edaa1d19c4672a4fd390c072b1eba6 (patch)
treea1524927d8986bb54345c47ded84bb3c2a9559c2 /UEngines.pas
parentae0047b8a5fa76ea76c66d8c5c580eba39178755 (diff)
downloadtuxcmd-0.6.74.tar.xz
Error system transformation to GErrorv0.6.74
Note that most coreworkers are broken at the moment.
Diffstat (limited to 'UEngines.pas')
-rw-r--r--UEngines.pas539
1 files changed, 270 insertions, 269 deletions
diff --git a/UEngines.pas b/UEngines.pas
index a8f1923..66dd9ea 100644
--- a/UEngines.pas
+++ b/UEngines.pas
@@ -24,14 +24,7 @@ interface
uses glib2, gdk2, Classes, ULibc;
-const ERRException = -1;
- ERRNoAccess = -2;
- ERRCreateLink = -3;
- ERRCopyMove = -4;
- ERRRemove = -5;
- ERRMkDIr = -6;
-
- omRead = 0;
+const omRead = 0;
omWrite = 1;
omAppend = 2;
@@ -66,8 +59,12 @@ type
ForceMove, IsOnRO: boolean;
end;
- TEngineProgressFunc = function (Sender: Pointer; BytesDone: Int64): boolean; cdecl; // Return False to break the copy process
- TEngineErrorFunc = function (Sender: Pointer; ErrorType, ErrorNum: integer; FileName: string): boolean; cdecl; // Return
+ // Progress callback, return False to break the copy process
+ // If an Error is set, returning True means to ignore error (don't delete broken file if possible)
+ // If an Error is set, BytesDone may contain random value
+ // Do not free Error, it belongs to the copy operation
+ TEngineProgressFunc = function (Sender: Pointer; BytesDone: Int64; Error: PGError): boolean; cdecl;
+ // * TODO: file handle
TEngineFileDes = pointer;
TPanelEngine = class
@@ -79,10 +76,10 @@ type
constructor Create;
destructor Destroy; override;
- function GetListing(List: TList; const APath: string; AddDotFiles, FollowSymlinks, AddFullPath: boolean): integer; virtual; abstract; // Returns errorcode
- function GetFileInfo(const APath: string; FollowSymlinks, AddFullPath: boolean): PDataItem; virtual; abstract;
+ function GetListing(List: TList; const APath: string; AddDotFiles, FollowSymlinks, AddFullPath: boolean; Error: PPGError): boolean; virtual; abstract;
+ function GetFileInfo(const APath: string; FollowSymlinks, AddFullPath: boolean; Error: PPGError): PDataItem; virtual; abstract;
- function ChangeDir(const NewPath: string): integer; virtual; abstract; // Returns errorcode
+ function ChangeDir(const NewPath: string; Error: PPGError): boolean; virtual; abstract;
function GetPath: string; virtual; abstract;
procedure SetPath(Value: string); virtual; abstract;
@@ -95,28 +92,28 @@ type
function FileCanRun(const FileName: string): boolean; virtual; abstract;
// Operations
- function MakeDir(const NewDir: string): integer; virtual; abstract; // Returns errorcode
- function Remove(const APath: string): integer; virtual; abstract; // Returns errorcode
- function MakeSymLink(const NewFileName, PointTo: string): integer; virtual; abstract; // Returns errorcode
- function Chmod(const FileName: string; Mode: cuLong): integer; virtual; abstract; // Returns errorcode
- function Chown(const FileName: string; UID, GID: cuLong): integer; virtual; abstract; // Returns errorcode
- function RenameFile(const SourceFile, DestFile: string): integer; virtual; abstract; // Returns errorcode
- function ChangeTimes(const APath: string; mtime, atime: time_t): integer; virtual; abstract; // Returns errorcode
+ function MakeDir(const NewDir: string; Error: PPGError): boolean; virtual; abstract;
+ function Remove(const APath: string; Error: PPGError): boolean; virtual; abstract;
+ function MakeSymLink(const NewFileName, PointTo: string; Error: PPGError): boolean; virtual; abstract;
+ function Chmod(const FileName: string; Mode: cuLong; Error: PPGError): boolean; virtual; abstract;
+ function Chown(const FileName: string; UID, GID: cuLong; Error: PPGError): boolean; virtual; abstract;
+ function RenameFile(const SourceFile, DestFile: string; Error: PPGError): boolean; virtual; abstract;
+ function ChangeTimes(const APath: string; mtime, atime: time_t; Error: PPGError): boolean; virtual; abstract;
// Copy-related routines
function GetBlockSize: guint32; virtual; abstract;
procedure SetBlockSize(Value: guint32); virtual; abstract;
- function CopyFileIn(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; virtual; abstract; // returns True if file is successfully copied
- function CopyFileOut(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; virtual; abstract; // returns True if file is successfully copied
+ 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 IsOnSameFS(const Path1, Path2: string; FollowSymlinks: boolean): boolean; virtual; abstract;
function TwoSameFiles(const Path1, Path2: string; FollowSymlinks: boolean): boolean; virtual; abstract;
// Separate file read/write routines, not supported on most backends
- function OpenFile(const APath: string; Mode: integer; var Error: integer): TEngineFileDes; virtual; abstract; // Returns filedescriptor
- function ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; var Error: integer): integer; virtual; abstract; // Returns number of bytes read
- function WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; var Error: integer): integer; virtual; abstract; // Returns number of bytes written
- function CloseFile(const FileDescriptor: TEngineFileDes): integer; virtual; abstract; // Returns errorcode
- function FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; var Error: integer): Int64; virtual; abstract; // Returns errorcode
+ function OpenFile(const APath: string; Mode: integer; Error: PPGError): TEngineFileDes; virtual; abstract; // Returns filedescriptor
+ function ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; Error: PPGError): integer; virtual; abstract; // Returns number of bytes read
+ function WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; Error: PPGError): integer; virtual; abstract; // Returns number of bytes written
+ function CloseFile(const FileDescriptor: TEngineFileDes; Error: PPGError): boolean; virtual; abstract;
+ function FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; Error: PPGError): Int64; virtual; abstract;
published
property Path: string read GetPath write SetPath;
property BlockSize: guint32 read GetBlockSize write SetBlockSize;
@@ -130,10 +127,10 @@ type
constructor Create;
destructor Destroy; override;
- function GetListing(List: TList; const APath: string; AddDotFiles, FollowSymlinks, AddFullPath: boolean): integer; override;
- function GetFileInfo(const APath: string; FollowSymlinks, AddFullPath: boolean): PDataItem; override;
+ function GetListing(List: TList; const APath: string; AddDotFiles, FollowSymlinks, AddFullPath: boolean; Error: PPGError): boolean; override;
+ function GetFileInfo(const APath: string; FollowSymlinks, AddFullPath: boolean; Error: PPGError): PDataItem; override;
- function ChangeDir(const NewPath: string): integer; override;
+ function ChangeDir(const NewPath: string; Error: PPGError): boolean; override;
function GetPath: string; override;
procedure SetPath(Value: string); override;
@@ -145,29 +142,26 @@ type
function IsOnROMedium(const FileName: string): boolean; override;
function FileCanRun(const FileName: string): boolean; override;
- function MakeDir(const NewDir: string): integer; override;
- function Remove(const APath: string): integer; override;
- function MakeSymLink(const NewFileName, PointTo: string): integer; override;
- function Chmod(const FileName: string; Mode: cuLong): integer; override;
- function Chown(const FileName: string; UID, GID: cuLong): integer; override;
- function RenameFile(const SourceFile, DestFile: string): integer; override;
- function ChangeTimes(const APath: string; mtime, atime: time_t): integer; override;
+ function MakeDir(const NewDir: string; Error: PPGError): boolean; override;
+ function Remove(const APath: string; Error: PPGError): boolean; override;
+ function MakeSymLink(const NewFileName, PointTo: string; Error: PPGError): boolean; override;
+ function Chmod(const FileName: string; Mode: cuLong; Error: PPGError): boolean; override;
+ function Chown(const FileName: string; UID, GID: cuLong; Error: PPGError): boolean; override;
+ function RenameFile(const SourceFile, DestFile: string; Error: PPGError): boolean; override;
+ function ChangeTimes(const APath: string; mtime, atime: time_t; Error: PPGError): boolean; override;
function GetBlockSize: guint32; override;
procedure SetBlockSize(Value: guint32); override;
- function CopyFileIn(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; override;
- function CopyFileOut(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean; 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 IsOnSameFS(const Path1, Path2: string; FollowSymlinks: boolean): boolean; override;
function TwoSameFiles(const Path1, Path2: string; FollowSymlinks: boolean): boolean; override;
- function OpenFile(const APath: string; Mode: integer; var Error: integer): TEngineFileDes; override;
- function ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; var Error: integer): integer; override;
- function WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; var Error: integer): integer; override;
- function CloseFile(const FileDescriptor: TEngineFileDes): integer; override;
- function FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; var Error: integer): Int64; override;
-
- // Local extra functions
- function CopyFile(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+ function OpenFile(const APath: string; Mode: integer; Error: PPGError): TEngineFileDes; override;
+ function ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; Error: PPGError): integer; override;
+ function WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; Error: PPGError): integer; override;
+ function CloseFile(const FileDescriptor: TEngineFileDes; Error: PPGError): boolean; override;
+ function FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; Error: PPGError): Int64; override;
published
property Path;
property BlockSize;
@@ -182,7 +176,7 @@ function DuplicateDataItem(DataItem: PDataItemSL): PDataItemSL; overload;
implementation
-uses SysUtils, UCoreUtils, UGnome;
+uses SysUtils, UCoreUtils, UGnome, UError;
(********************************************************************************************************************************)
constructor TPanelEngine.Create;
@@ -235,26 +229,31 @@ begin
end;
end;
-function TLocalTreeEngine.GetListing(List: TList; const APath: string; AddDotFiles, FollowSymlinks, AddFullPath: boolean): integer;
+function TLocalTreeEngine.GetListing(List: TList; const APath: string; AddDotFiles, FollowSymlinks, AddFullPath: boolean; Error: PPGError): boolean;
var Item: PDataItem;
Handle: PDIR;
DirEnt: PDirent64;
Buf: PChar;
+ saved_errno: integer;
+ FError: PGError;
begin
- Result := 0;
+ Result := False;
try
if libc_chdir(PChar(APath)) <> 0 then begin
- Result := errno;
- DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): chdir error: ', strerror(Result)]);
+ 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)]);
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));
DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, '): opendir() handle == NULL: ', strerror(errno)]);
- Result := ERRNoAccess;
Exit;
end;
+ FError := nil;
repeat
DirEnt := readdir64(Handle);
if (DirEnt <> nil) and (DirEnt^.d_name[0] <> #0) then begin
@@ -262,32 +261,37 @@ begin
if (Buf <> '.') and (Buf <> '..') and (strlen(Buf) > 0) and
(AddDotFiles or (Buf[0] <> '.')) then
begin
- Item := GetFileInfo(IncludeTrailingPathDelimiter(APath) + string(Buf), FollowSymlinks, AddFullPath);
+ Item := GetFileInfo(IncludeTrailingPathDelimiter(APath) + string(Buf), FollowSymlinks, AddFullPath, @FError);
List.Add(Item);
end;
end;
- until DirEnt = nil;
- // TODO: check errno?
+ until (DirEnt = nil) or (FError <> nil);
closedir(Handle);
+
+ if FError <> nil then g_propagate_error(Error, FError)
+ else Result := True;
except
on E: Exception do begin
- Result := ERRException;
+ Result := False;
DebugMsg(['*** TLocalTreeEngine.GetListing(APath=', APath, ') -Exception: ', E.Message]);
Exit;
end;
end;
end;
-function TLocalTreeEngine.GetFileInfo(const APath: string; FollowSymlinks, AddFullPath: boolean): PDataItem;
+function TLocalTreeEngine.GetFileInfo(const APath: string; FollowSymlinks, AddFullPath: boolean; Error: PPGError): PDataItem;
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
- DebugMsg(['*** TLocalTreeEngine.GetFileInfo(APath=', APath, '): Error reading file via lstat64: ', strerror(errno)]);
+ 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)]);
libc_free(StatBuf);
Result := nil;
Exit;
@@ -342,19 +346,23 @@ begin
Result := Item;
end;
-function TLocalTreeEngine.ChangeDir(const NewPath: string): integer;
+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
- Result := errno;
+ 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));
Exit;
end;
Handle := opendir(PChar(APath));
- if not Assigned(Handle) then begin
- Result := ERRNoAccess;
+ 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));
Exit;
end;
{ if not Assigned(readdir(Handle)) then begin
@@ -362,13 +370,14 @@ begin
Exit;
end; }
if closedir(Handle) <> 0 then begin
- Result := ERRNoAccess;
+ 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));
Exit;
end;
- Result := 0;
+ Result := True;
except
on E: Exception do begin
- Result := ERRException;
+ Result := False;
DebugMsg(['*** TLocalTreeEngine.ChangeDir(APath=', APath, ') -Exception: ', E.Message]);
Exit;
end;
@@ -376,26 +385,6 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.MakeDir(const NewDir: string): integer;
-begin
-// DebugMsg(['(II) TLocalTreeEngine.MakeDir: begin']);
- Result := __mkdir(PChar(NewDir), OctalToAttr(ConfDefaultDirCreationMask));
-// DebugMsg(['(II) TLocalTreeEngine.MakeDir: Result = ', Result]);
-// if Result <> 0 then Result := errno;
-
- if Result <> 0 then try
- if Self.DirectoryExists(NewDir, False) or (g_mkdir_with_parents(PChar(NewDir), OctalToAttr(ConfDefaultDirCreationMask)) <> 0) {ForceDirectories(NewDir))}
- then Result := errno
- else Result := 0;
- except
- Result := -1;
- DebugMsg(['(II) TLocalTreeEngine.MakeDir: Exception']);
- end;
-
-// DebugMsg(['(II) TLocalTreeEngine.MakeDir: end']);
-end;
-
-(********************************************************************************************************************************)
function TLocalTreeEngine.GetDirSize(const APath: string): Int64;
function InternalGetDirSize(APath: string): Int64;
@@ -447,157 +436,202 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.Remove(const APath: string): integer;
+function TLocalTreeEngine.MakeDir(const NewDir: string; Error: PPGError): boolean;
+var saved_errno: integer;
begin
- Result := libc_remove(PChar(ExcludeTrailingPathDelimiter(APath)));
- if Result <> 0 then Result := errno;
+ 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;
+ 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));
+ end else Result := True;
+end;
-function TLocalTreeEngine.CopyFileIn(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+(********************************************************************************************************************************)
+function TLocalTreeEngine.MakeSymLink(const NewFileName, PointTo: string; Error: PPGError): boolean;
+var saved_errno: integer;
begin
- Result := CopyFile(Sender, SourceFile, DestFile, ProgressFunc, ErrorFunc, Append);
+ 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));
+ end else Result := True;
end;
-function TLocalTreeEngine.CopyFileOut(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
+(********************************************************************************************************************************)
+function TLocalTreeEngine.Chmod(const FileName: string; Mode: cuLong; Error: PPGError): boolean;
+var saved_errno: integer;
begin
- Result := CopyFile(Sender, SourceFile, DestFile, ProgressFunc, ErrorFunc, Append);
+ 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));
+ end else Result := True;
end;
-function TLocalTreeEngine.CopyFile(Sender: Pointer; const SourceFile, DestFile: string; ProgressFunc: TEngineProgressFunc; ErrorFunc: TEngineErrorFunc; Append: boolean): boolean;
-var fsrc, fdest: PFILE;
- BytesDone, BytesRead: Int64;
-// offset: __off_t;
+(********************************************************************************************************************************)
+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));
+ 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));
+ end else Result := True;
+end;
- // Used due to sendfile bug while copying from NTFS and some 2.6.x kernels
- function OldCopyRoutine: boolean;
- var Buffer: Pointer;
- BytesWritten: Int64;
- Res: boolean;
- begin
- Result := False;
- Res := True;
- try
-// DebugMsg(['*** Using old copy function due to bug in sendfile']);
-// WriteLn('x1');
- Buffer := malloc(FBlockSize);
-// WriteLn('x2');
- if Buffer = nil then begin
- ErrorFunc(Sender, 1, errno, SourceFile); // Memory allocation failed
-// libc_free(Buffer);
+(********************************************************************************************************************************)
+function TLocalTreeEngine.ChangeTimes(const APath: string; mtime, atime: time_t; Error: PPGError): boolean;
+var timebuf: Putimbuf;
+ saved_errno: integer;
+begin
+ Result := False;
+ try
+ timebuf := malloc(sizeof(Tutimbuf));
+ memset(timebuf, 0, sizeof(Tutimbuf));
+ 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));
+ end else Result := True;
+ libc_free(timebuf);
+ except
+ on E: Exception do DebugMsg(['*** Exception raised in TLocalTreeEngine.ChangeTimes(APath=', APath, '): (', E.ClassName, '): ', E.Message]);
+ end;
+end;
+
+(********************************************************************************************************************************)
+
+function TLocalTreeEngine.CopyFileIn(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer): boolean;
+begin
+ Result := CopyFileOut(SourceFile, DestFile, Append, ProgressFunc, Sender);
+end;
+
+function TLocalTreeEngine.CopyFileOut(const SourceFile, DestFile: string; Append: boolean; ProgressFunc: TEngineProgressFunc; Sender: Pointer): boolean;
+var fsrc, fdest: PFILE;
+ Buffer: Pointer;
+ BytesDone, BytesRead, BytesWritten: Int64;
+ Ignore: boolean;
+ saved_errno: integer;
+ Error: PGError;
+begin
+ Result := False;
+ Error := nil;
+ 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;
Exit;
end;
- memset(Buffer, 0, FBlockSize);
+ // 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;
+ fclose(fsrc);
+ Exit;
+ end;
+
+ BytesDone := 0;
+ Buffer := malloc(FBlockSize);
-// WriteLn('x3');
while feof(fsrc) = 0 do begin
-// WriteLn('x4');
+ Error := nil;
+
+ // Read block
BytesRead := fread(Buffer, 1, FBlockSize, fsrc);
if (BytesRead < FBlockSize) and (feof(fsrc) = 0) then begin
- Res := ErrorFunc(Sender, 6, errno, SourceFile); // Cannot read from source file
- Break;
+ 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;
end;
-// WriteLn('x5');
+
+ // Write block
BytesWritten := fwrite(Buffer, 1, BytesRead, fdest);
if BytesWritten < BytesRead then begin
- Res := ErrorFunc(Sender, 7, ferror(fdest), DestFile); // Cannot write to source file
- Break;
+ 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;
+ Break; // We cannot ignore write errors
end;
+
Inc(BytesDone, BytesRead);
-// WriteLn('x6');
- try
- if Assigned(ProgressFunc) and (not ProgressFunc(Sender, BytesDone)) then begin
- Res := False;
+ if (@ProgressFunc <> nil) and (not ProgressFunc(Sender, BytesDone, nil)) then
Break;
- end;
- except
- on E: Exception do DebugMsg(['*** ProgressFunc ! Exception raised in TLocalTreeEngine.CopyFile.OldCopyRoutine(Sender=', DWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
- end;
-// WriteLn('x7');
end;
-// WriteLn('x8');
+ Result := feof(fsrc) <> 0;
libc_free(Buffer);
-// WriteLn('x9');
- Result := Res;
- except
- on E: Exception do DebugMsg(['*** Exception raised in TLocalTreeEngine.CopyFile.OldCopyRoutine(Sender=', DWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
- end;
- end;
-(*
- function NewCopyRoutine: boolean;
- var Res: boolean;
- StatBuf: Pstat64;
- begin
- try
- Res := True;
- repeat
- DebugMsg(['Copy(sendfile): offset = ', offset, ', BytesDone = ', BytesDone, ', ftell(fsrc) = ', ftell(fsrc)]);
- BytesRead := sendfile(fileno(fdest), fileno(fsrc), offset, FBlockSize);
- if BytesRead = -1 then begin
- if errno = EINVAL then begin
- Result := OldCopyRoutine;
- Exit;
- end else Res := ErrorFunc(Sender, 6, errno, SourceFile); // Cannot read from source file
- Break;
+
+ if fclose(fdest) <> 0 then begin
+ fclose(fsrc);
+ 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;
- Inc(BytesDone, BytesRead);
- if Assigned(ProgressFunc) and (not ProgressFunc(Sender, BytesDone)) then begin
- Res := False;
- Break;
+ Exit;
+ end;
+ if fclose(fsrc) <> 0 then begin
+ 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;
- until BytesRead < FBlockSize;
-
- StatBuf := malloc(sizeof(Tstat64));
- memset(StatBuf, 0, sizeof(Tstat64));
- if lstat64(PChar(SourceFile), StatBuf) <> 0 then begin
- DebugMsg(['*** TLocalTreeEngine.CopyFile.NewCopyRoutine(Sender=', DWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): Error reading file via lstat64: ', strerror(errno)]);
- Res := ErrorFunc(Sender, 6, errno, SourceFile);
- end else
- if (BytesDone < StatBuf^.st_size) and Res then
- Res := ErrorFunc(Sender, 6, errno, SourceFile);
- libc_free(StatBuf);
- Result := Res;
- except
- on E: Exception do DebugMsg(['*** Exception raised in TLocalTreeEngine.CopyFile.NewCopyRoutine(Sender=', DWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
+ Exit;
end;
- end;
-*)
-begin
- Result := False;
- try
- fsrc := fopen64(PChar(SourceFile), 'r');
- if fsrc = nil then begin
- ErrorFunc(Sender, 2, errno, SourceFile); // Cannot open source file
- Exit;
- end;
- if Append then fdest := fopen64(PChar(DestFile), 'a')
- else fdest := fopen64(PChar(DestFile), 'w');
- if fdest = nil then begin
- fclose(fsrc);
- ErrorFunc(Sender, 3, errno, DestFile); // Cannot open target file
- Exit;
- end;
-
- BytesDone := 0;
-// offset := 0;
-
- Result := OldCopyRoutine;
-
- if fclose(fdest) <> 0 then begin
- fclose(fsrc);
- ErrorFunc(Sender, 4, errno, DestFile); // Cannot close target file
- Exit;
- end;
- if fclose(fsrc) <> 0 then begin
- ErrorFunc(Sender, 5, errno, SourceFile); // Cannot close source file
- Exit;
- end;
except
- on E: Exception do DebugMsg(['*** Exception raised in TLocalTreeEngine.CopyFile(Sender=', DWord(Sender), ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
+ on E: Exception do DebugMsg(['*** Exception raised in TLocalTreeEngine.CopyFile(Sender=', Sender, ', SourceFile=', SourceFile, ', DestFile=', DestFile, '): (', E.ClassName, '): ', E.Message]);
end;
-// DebugMsg(['(II) TLocalTreeEngine.CopyFile: finished']);
end;
(********************************************************************************************************************************)
@@ -624,28 +658,6 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.MakeSymLink(const NewFileName, PointTo: string): integer;
-begin
-// DebugMsg(['TLocalTreeEngine.MakeSymLink(NewFileName = "', NewFileName, '", PointTo = "', PointTo, '"']);
- Result := symlink(PChar(PointTo), PChar(NewFileName));
- if Result <> 0 then Result := errno;
-end;
-
-(********************************************************************************************************************************)
-function TLocalTreeEngine.Chmod(const FileName: string; Mode: cuLong): integer;
-begin
- Result := libc_chmod(PChar(FileName), Mode);
- if Result <> 0 then Result := errno;
-end;
-
-(********************************************************************************************************************************)
-function TLocalTreeEngine.Chown(const FileName: string; UID, GID: cuLong): integer;
-begin
- Result := libc_chown(PChar(FileName), UID, GID);
- if Result <> 0 then Result := errno;
-end;
-
-(********************************************************************************************************************************)
procedure TLocalTreeEngine.BreakProcessing(ProcessingKind: integer);
begin
BreakProcessingType := ProcessingKind;
@@ -698,31 +710,6 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.RenameFile(const SourceFile, DestFile: string): integer;
-begin
- Result := libc_rename(PChar(SourceFile), PChar(DestFile));
- if Result <> 0 then Result := errno;
-end;
-
-(********************************************************************************************************************************)
-function TLocalTreeEngine.ChangeTimes(const APath: string; mtime, atime: time_t): integer;
-var timebuf: Putimbuf;
-begin
- Result := errno;
- try
- timebuf := malloc(sizeof(Tutimbuf));
- memset(timebuf, 0, sizeof(Tutimbuf));
- timebuf^.actime := atime;
- timebuf^.modtime := mtime;
- Result := utime(PChar(APath), timebuf);
- if Result <> 0 then Result := errno;
- libc_free(timebuf);
- except
- on E: Exception do DebugMsg(['*** Exception raised in TLocalTreeEngine.ChangeTimes(APath=', APath, '): (', E.ClassName, '): ', E.Message]);
- end;
-end;
-
-(********************************************************************************************************************************)
procedure TLocalTreeEngine.GetFileSystemInfo(const APath: string; var FSSize, FSFree: Int64; var FSName: string);
var Stat: Pstatfs64;
fd: PFILE;
@@ -774,10 +761,10 @@ begin
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.OpenFile(const APath: string; Mode: integer; var Error: integer): TEngineFileDes;
+function TLocalTreeEngine.OpenFile(const APath: string; Mode: integer; Error: PPGError): TEngineFileDes;
var m: PChar;
+ saved_errno: integer;
begin
- Error := 0;
case Mode of
omRead: m := 'r';
omWrite: m := 'w';
@@ -785,40 +772,54 @@ begin
else m := 'r';
end;
Result := fopen64(PChar(APath), m);
- if Result = nil then Error := errno;
+ 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;
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; var Error: integer): integer;
+function TLocalTreeEngine.ReadFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; ABlockSize: integer; Error: PPGError): integer;
+var saved_errno: integer;
begin
- Error := 0;
Result := fread(Buffer, 1, ABlockSize, FileDescriptor);
- if (Result = 0) and (feof(FileDescriptor) = 0) then Error := errno;
+ 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;
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; var Error: integer): integer;
+function TLocalTreeEngine.WriteFile(const FileDescriptor: TEngineFileDes; Buffer: Pointer; BytesCount: integer; Error: PPGError): integer;
+var saved_errno: integer;
begin
- Error := 0;
-{ Result := __write(fileno(FileDescriptor), Buffer^, BytesCount);
- if Result < BytesCount then Error := errno; }
Result := fwrite(Buffer, 1, BytesCount, FileDescriptor);
- if Result < BytesCount then Error := ferror(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;
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.CloseFile(const FileDescriptor: TEngineFileDes): integer;
+function TLocalTreeEngine.CloseFile(const FileDescriptor: TEngineFileDes; Error: PPGError): boolean;
+var saved_errno: integer;
begin
- Result := fclose(FileDescriptor);
- if Result <> 0 then Result := errno;
+ 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;
end;
(********************************************************************************************************************************)
-function TLocalTreeEngine.FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; var Error: integer): Int64;
+function TLocalTreeEngine.FileSeek(const FileDescriptor: TEngineFileDes; const AbsoluteOffset: Int64; Error: PPGError): Int64;
+var saved_errno: integer;
begin
- Error := 0;
Result := fseeko64(FileDescriptor, AbsoluteOffset, SEEK_SET);
- if Result = -1 then Error := errno;
+ 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;
end;
(********************************************************************************************************************************)