Skip to content

Commit 8cb66da

Browse files
authored
Merge branch 'doublecmd:master' into master
2 parents c0e2079 + 85f15ab commit 8cb66da

File tree

119 files changed

+6668
-1157
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+6668
-1157
lines changed

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
lazarus-version: "stable"
2020

2121
- name: Get Lazarus source
22-
uses: actions/checkout@v4
22+
uses: actions/checkout@v5
2323
with:
2424
repository: 'fpc/Lazarus'
2525
ref: 'fixes_4'
@@ -34,7 +34,7 @@ jobs:
3434
sudo sed -i -e "s|_PPCARCH_|fpc|g; s|/Developer/lazarus|/usr/local/share/lazarus|g" /etc/lazarus/environmentoptions.xml
3535
3636
- name: Checkout source
37-
uses: actions/checkout@v4
37+
uses: actions/checkout@v5
3838
with:
3939
fetch-depth: 0
4040

.github/workflows/snapshots.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
lazarus-version: "stable"
2626

2727
- name: Get Lazarus source
28-
uses: actions/checkout@v4
28+
uses: actions/checkout@v5
2929
with:
3030
repository: 'fpc/Lazarus'
3131

@@ -39,7 +39,7 @@ jobs:
3939
sudo sed -i -e "s|_PPCARCH_|fpc|g; s|/Developer/lazarus|/usr/local/share/lazarus|g" /etc/lazarus/environmentoptions.xml
4040
4141
- name: Checkout source
42-
uses: actions/checkout@v4
42+
uses: actions/checkout@v5
4343
with:
4444
fetch-depth: 0
4545

@@ -67,7 +67,7 @@ jobs:
6767
lazarus-version: "stable"
6868

6969
- name: Checkout source
70-
uses: actions/checkout@v4
70+
uses: actions/checkout@v5
7171
with:
7272
fetch-depth: 0
7373

components/doublecmd/dcclasses.pas

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
unit DCClasses;
2+
3+
{$mode objfpc}{$H+}
4+
5+
interface
6+
7+
uses
8+
Classes, SysUtils, NullStream;
9+
10+
type
11+
12+
{ TNullStreamEx }
13+
14+
TNullStreamEx = class(TNullStream)
15+
public
16+
function Write(const Buffer; Count: LongInt): LongInt; override;
17+
end;
18+
19+
implementation
20+
21+
{ TNullStreamEx }
22+
23+
function TNullStreamEx.Write(const Buffer; Count: LongInt): LongInt;
24+
begin
25+
Result:= Count;
26+
inherited Write(Buffer, Count);
27+
end;
28+
29+
end.
30+

components/doublecmd/dcdarwin.pas

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,19 @@ interface
1414
CLOSE_RANGE_CLOEXEC = (1 << 2);
1515

1616
function CloseRange(first: cuint; last: cuint; flags: cint): cint; cdecl;
17+
function mbFileCopyXattr(const Source, Target: String): Boolean;
1718

1819
// MacOS File Utils
1920
function MacosFileSetCreationTime( const path:String; const birthtime:TFileTimeEx ): Boolean;
2021

22+
type
23+
24+
{ TDarwinFileUtil }
25+
26+
TDarwinFileUtil = class
27+
class function cloneFile( const fromPath: String; const toPath: String; const size: Int64 ): Boolean;
28+
end;
29+
2130
implementation
2231

2332
uses
@@ -34,6 +43,32 @@ proc_fdinfo = record
3443
PROC_PIDLISTFDS = 1;
3544
PROC_PIDLISTFD_SIZE = SizeOf(proc_fdinfo);
3645

46+
const
47+
NSAppKitVersionNumber10_13 = 1561;
48+
49+
const
50+
COPYFILE_ACL = 1 shl 0;
51+
COPYFILE_STAT = 1 shl 1;
52+
COPYFILE_XATTR = 1 shl 2;
53+
COPYFILE_DATA = 1 shl 3;
54+
55+
COPYFILE_SECURITY = COPYFILE_STAT or COPYFILE_ACL;
56+
COPYFILE_METADATA = COPYFILE_SECURITY or COPYFILE_XATTR;
57+
COPYFILE_ALL = COPYFILE_METADATA or COPYFILE_DATA;
58+
59+
COPYFILE_UNLINK = 1 shl 21;
60+
COPYFILE_CLONE = 1 shl 24;
61+
COPYFILE_CLONE_FORCE = 1 shl 25;
62+
63+
type
64+
copyfile_state_t_o = record
65+
end;
66+
copyfile_state_t = ^copyfile_state_t_o;
67+
copyfile_flags_t = UInt32;
68+
69+
function copyfile( const fromPath: pchar; const toPath: pchar; state: copyfile_state_t; flags: copyfile_flags_t ): Integer;
70+
cdecl; external name 'copyfile';
71+
3772
function proc_pidinfo(pid: cint; flavor: cint; arg: cuint64; buffer: pointer; buffersize: cint): cint; cdecl; external 'proc';
3873

3974
function CloseRange(first: cuint; last: cuint; flags: cint): cint; cdecl;
@@ -68,6 +103,16 @@ function CloseRange(first: cuint; last: cuint; flags: cint): cint; cdecl;
68103
end;
69104
end;
70105

106+
function mbFileCopyXattr(const Source, Target: String): Boolean;
107+
var
108+
ret: Integer;
109+
begin
110+
Writeln( '>>3> mbFileCopyXattr' );
111+
ret:= copyfile( pchar(Source), pchar(Target), nil, COPYFILE_XATTR );
112+
fpseterrno( ret );
113+
Result:= (ret=0);
114+
end;
115+
71116
function StringToNSString(const S: String): NSString;
72117
begin
73118
Result:= NSString(NSString.stringWithUTF8String(PAnsiChar(S)));
@@ -88,5 +133,39 @@ function MacosFileSetCreationTime( const path:String; const birthtime:TFileTimeE
88133
Result:= NSFileManager.defaultManager.setAttributes_ofItemAtPath_error( attrs, nsPath, nil );
89134
end;
90135

136+
{ TDarwinFileUtil }
137+
138+
// the copyfile() api has two advantages:
139+
// 1. dramatically improve file copy speed on APFS
140+
// 2. supports copying macOS specific attributes
141+
// therefore, we should try copyfile() as much as possible on macOS
142+
class function TDarwinFileUtil.cloneFile( const fromPath: String; const toPath: String; const size: Int64 ): Boolean;
143+
const
144+
NO_CALLBACK_MAXSIZE = 20*1024*1024; // 20MB
145+
var
146+
flags: copyfile_flags_t;
147+
ret: Integer;
148+
begin
149+
Result:= False;
150+
flags:= COPYFILE_ALL;
151+
152+
// call copyfile() when:
153+
// 1. macOS < 10.13 and filesize <= MAX_SIZE (copy only)
154+
// 2. macOS >= 10.13 and filesize > MAX_SIZE (clone only, fail fast)
155+
// 3. macOS >= 10.13 and filesize <= MAX_SIZE (try clone, then copy)
156+
if NSAppKitVersionNumber < NSAppKitVersionNumber10_13 then begin
157+
if size > NO_CALLBACK_MAXSIZE then
158+
Exit;
159+
end else begin
160+
if size > NO_CALLBACK_MAXSIZE then
161+
flags:= flags or COPYFILE_CLONE_FORCE or COPYFILE_UNLINK
162+
else
163+
flags:= flags or COPYFILE_CLONE;
164+
end;
165+
166+
ret:= copyfile( pchar(fromPath), pchar(toPath), nil, flags );
167+
Result:= (ret=0);
168+
end;
169+
91170
end.
92171

components/doublecmd/dcosutils.pas

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ interface
3434
{$IFDEF LINUX}
3535
, DCLinux
3636
{$ENDIF}
37+
{$IFDEF DARWIN}
38+
, DCDarwin
39+
{$ENDIF}
3740
{$IFDEF HAIKU}
3841
, DCHaiku
3942
{$ENDIF}
@@ -654,7 +657,7 @@ function mbFileCopyAttr(const sSrc, sDst: String;
654657
end;
655658
end;
656659

657-
{$IF DEFINED(LINUX) or DEFINED(HAIKU)}
660+
{$IF DEFINED(LINUX) or DEFINED(DARWIN) or DEFINED(HAIKU)}
658661
if caoCopyXattributes in Options then
659662
begin
660663
if not mbFileCopyXattr(sSrc, sDst) then

components/doublecmd/dcunix.pas

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ interface
4141
FD_CLOEXEC = 1;
4242
O_CLOEXEC = &02000000;
4343
O_PATH = &010000000;
44+
_SC_NPROCESSORS_CONF = 83;
4445
_SC_NPROCESSORS_ONLN = 84;
4546
{$ELSEIF DEFINED(FREEBSD)}
4647
O_CLOEXEC = &04000000;
48+
_SC_NPROCESSORS_CONF = 57;
4749
_SC_NPROCESSORS_ONLN = 58;
4850
CLOSE_RANGE_CLOEXEC = (1 << 2);
4951
{$ELSEIF DEFINED(NETBSD)}
@@ -54,6 +56,7 @@ interface
5456
{$ELSEIF DEFINED(DARWIN)}
5557
F_NOCACHE = 48;
5658
O_CLOEXEC = $1000000;
59+
_SC_NPROCESSORS_CONF = 57;
5760
_SC_NPROCESSORS_ONLN = 58;
5861
{$ELSE}
5962
O_CLOEXEC = 0;

components/doublecmd/dcxmlconfig.pas

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,11 +553,12 @@ procedure TXmlConfig.ReadFromStream(AStream: TStream);
553553

554554
procedure TXmlConfig.WriteToFile(const AFilename: String);
555555
var
556-
FileStream: TStream;
556+
FileStream: TFileStreamEx;
557557
begin
558558
FileStream := TFileStreamEx.Create(AFilename, fmCreate or fmShareDenyWrite);
559559
try
560560
WriteToStream(FileStream);
561+
FileStream.Flush;
561562
finally
562563
FileStream.Free;
563564
end;

components/doublecmd/doublecmd_common.lpk

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ end"/>
3636
</CompilerOptions>
3737
<Description Value="Common units for Double Commander"/>
3838
<License Value="GNU GPL 2"/>
39-
<Version Minor="4" Release="2"/>
40-
<Files Count="12">
39+
<Version Minor="4" Release="3"/>
40+
<Files Count="13">
4141
<Item1>
4242
<Filename Value="dcclassesutf8.pas"/>
4343
<UnitName Value="DCClassesUtf8"/>
@@ -86,6 +86,10 @@ end"/>
8686
<Filename Value="dcjsonconfig.pas"/>
8787
<UnitName Value="DCJsonConfig"/>
8888
</Item12>
89+
<Item13>
90+
<Filename Value="dcclasses.pas"/>
91+
<UnitName Value="DCClasses"/>
92+
</Item13>
8993
</Files>
9094
<CompatibilityMode Value="True"/>
9195
<RequiredPkgs Count="2">

components/doublecmd/doublecmd_common.pas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface
1010
uses
1111
DCClassesUtf8, DCOSUtils, DCStrUtils, DCBasicTypes, DCFileAttributes,
1212
DCConvertEncoding, DCDateTimeUtils, DCXmlConfig, DCProcessUtf8,
13-
DCUnicodeUtils, DCStringHashListUtf8, DCJsonConfig;
13+
DCUnicodeUtils, DCStringHashListUtf8, DCJsonConfig, DCClasses;
1414

1515
implementation
1616

0 commit comments

Comments
 (0)