Fix OpenFlags.Append mode for io2.openFile() (#226)

* Initial commit.

* Fix Windows version.

* Remove debugging echoes.

* Fix Posix version.

* Add one more test.
This commit is contained in:
Eugene Kabanov 2024-08-02 08:32:31 +03:00 committed by GitHub
parent 8e0e344f0f
commit af07b0a70d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 156 additions and 46 deletions

View File

@ -32,6 +32,7 @@ when defined(windows):
FILE_FLAG_OVERLAPPED = 0x40000000'u32
FILE_SHARE_READ = 0x00000001'u32
FILE_SHARE_WRITE = 0x00000002'u32
FILE_APPEND_DATA = 0x00000004'u32
FILE_FLAG_NO_BUFFERING = 0x20000000'u32
FILE_ATTRIBUTE_READONLY = 0x00000001'u32
@ -1012,7 +1013,14 @@ proc openFile*(pathName: string, flags: set[OpenFlags],
if OpenFlags.Truncate in flags:
cflags = cflags or posix.O_TRUNC
if OpenFlags.Append in flags:
cflags = cflags or posix.O_APPEND
if ((cflags and posix.O_WRONLY) != 0) or ((cflags and posix.O_RDWR) != 0):
cflags = cflags or posix.O_APPEND
else:
if ((cflags and posix.O_RDONLY) != 0):
cflags = cflags and not(posix.O_RDONLY)
cflags = cflags or posix.O_APPEND or O_RDWR
else:
cflags = cflags or posix.O_APPEND or O_WRONLY
when defined(linux) or defined(freebsd) or defined(netbsd) or
defined(dragonflybsd):
if OpenFlags.Direct in flags:
@ -1053,7 +1061,7 @@ proc openFile*(pathName: string, flags: set[OpenFlags],
var
dwAccess: uint32
dwShareMode: uint32
dwCreation: uint32
dwCreation: uint32 = OPEN_EXISTING
dwFlags: uint32
var sa = SECURITY_ATTRIBUTES(
@ -1062,36 +1070,37 @@ proc openFile*(pathName: string, flags: set[OpenFlags],
bInheritHandle: 0
)
if (OpenFlags.Write in flags) and (OpenFlags.Read in flags):
dwAccess = dwAccess or (GENERIC_READ or GENERIC_WRITE)
else:
if OpenFlags.Write in flags:
dwAccess = dwAccess or GENERIC_WRITE
else:
dwAccess = dwAccess or GENERIC_READ
if OpenFlags.Write in flags:
dwAccess = dwAccess or GENERIC_WRITE
if OpenFlags.Read in flags:
dwAccess = dwAccess or GENERIC_READ
if OpenFlags.Append in flags:
dwAccess = dwAccess or FILE_APPEND_DATA
if {OpenFlags.Create, OpenFlags.Exclusive} <= flags:
dwCreation = dwCreation or CREATE_NEW
elif OpenFlags.Truncate in flags:
if OpenFlags.Truncate in flags:
if OpenFlags.Create in flags:
dwCreation = dwCreation or CREATE_ALWAYS
elif OpenFlags.Read notin flags:
else:
dwCreation = dwCreation or TRUNCATE_EXISTING
elif OpenFlags.Append in flags:
dwCreation = dwCreation or OPEN_EXISTING
elif OpenFlags.Create in flags:
dwCreation = dwCreation or OPEN_ALWAYS
if {OpenFlags.Create} == flags or
{OpenFlags.Create, OpenFlags.Exclusive} == flags:
dwCreation = dwCreation or CREATE_NEW
else:
dwCreation = dwCreation or OPEN_EXISTING
if OpenFlags.Create in flags:
dwCreation = dwCreation and not(OPEN_EXISTING)
dwCreation = dwCreation or OPEN_ALWAYS
if dwCreation == OPEN_EXISTING and
((dwAccess and (GENERIC_READ or GENERIC_WRITE)) == GENERIC_READ):
dwShareMode = dwShareMode or FILE_SHARE_READ
((dwAccess and GENERIC_READ) == GENERIC_READ):
if OpenFlags.Exclusive notin flags:
dwShareMode = dwShareMode or FILE_SHARE_READ
if OpenFlags.ShareRead in flags:
dwShareMode = dwShareMode or FILE_SHARE_READ
if OpenFlags.ShareWrite in flags:
dwShareMode = dwShareMode or FILE_SHARE_WRITE
if OpenFlags.Exclusive notin flags:
if OpenFlags.ShareRead in flags:
dwShareMode = dwShareMode or FILE_SHARE_READ
if OpenFlags.ShareWrite in flags:
dwShareMode = dwShareMode or FILE_SHARE_WRITE
if OpenFlags.NonBlock in flags:
dwFlags = dwFlags or FILE_FLAG_OVERLAPPED

View File

@ -406,35 +406,136 @@ suite "OS Input/Output procedures test suite":
removeFile("testblob6").isOk()
test "openFile()/readFile()/writeFile() test":
var buffer = newString(10)
let flags = {OpenFlags.Write, OpenFlags.Truncate, OpenFlags.Create}
var buffer = newString(100)
var fdres = openFile("testfile.txt", flags)
check:
fdres.isOk()
readFile(fdres.get(), buffer).isErr()
writeFile(fdres.get(), "TEST").isOk()
readFile(fdres.get(), buffer).isErr()
closeFile(fdres.get()).isOk()
block:
let
flags = {OpenFlags.Write, OpenFlags.Truncate, OpenFlags.Create}
fdres = openFile("testfile.txt", flags)
check:
fdres.isOk()
readFile(fdres.get(), buffer).isErr()
writeFile(fdres.get(), "TEST1").isOk()
readFile(fdres.get(), buffer).isErr()
closeFile(fdres.get()).isOk()
fdres = openFile("testfile.txt", {OpenFlags.Read})
check:
fdres.isOk()
readFile(fdres.get(), buffer).isOk()
writeFile(fdres.get(), "TEST2").isErr()
readFile(fdres.get(), buffer).isOk()
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Read})
check fdres.isOk()
let res1 = readFile(fdres.get(), buffer)
check:
res1.isOk()
res1.get() == uint(5)
writeFile(fdres.get(), "TEST2").isErr()
let res2 = readFile(fdres.get(), buffer)
check:
res2.isOk()
res2.get() == uint(0)
closeFile(fdres.get()).isOk()
fdres = openFile("testfile.txt", {OpenFlags.Read, OpenFlags.Write})
check:
fdres.isOk()
readFile(fdres.get(), buffer).isOk()
writeFile(fdres.get(), "TEST2").isOk()
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Read, OpenFlags.Write})
check fdres.isOk()
let res1 = readFile(fdres.get(), buffer)
check:
res1.isOk()
res1.get() == uint(5)
writeFile(fdres.get(), "TEST3").isOk()
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Read})
check fdres.isOk()
let res1 = readFile(fdres.get(), buffer)
check:
res1.isOk()
res1.get() == uint(10)
buffer[0 .. 9] == "TEST1TEST3"
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Write})
check:
fdres.isOk()
writeFile(fdres.get(), "TEST2").isOk()
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Read})
check fdres.isOk()
let res1 = readFile(fdres.get(), buffer)
check:
res1.isOk()
res1.get() == uint(10)
buffer[0 .. 9] == "TEST2TEST3"
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Append})
check:
fdres.isOk()
writeFile(fdres.get(), "TEST4").isOk()
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Append})
check:
fdres.isOk()
writeFile(fdres.get(), "TEST5").isOk()
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Read})
check fdres.isOk()
let res = readFile(fdres.get(), buffer)
check:
res.isOk()
res.get() == 20
buffer[0 .. 19] == "TEST2TEST3TEST4TEST5"
closeFile(fdres.get()).isOk()
check:
removeFile("testfile.txt").isOk()
# Create file if not exists and append data to file.
block:
let fdres = openFile("testfile.txt", {OpenFlags.Append, OpenFlags.Create})
check:
fdres.isOk()
writeFile(fdres.get(), "TEST1").isOk()
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Append, OpenFlags.Create})
check:
fdres.isOk()
writeFile(fdres.get(), "TEST2").isOk()
closeFile(fdres.get()).isOk()
block:
let fdres = openFile("testfile.txt", {OpenFlags.Read})
check fdres.isOk()
let res = readFile(fdres.get(), buffer)
check:
res.isOk()
res.get() == 10
buffer[0 .. 9] == "TEST1TEST2"
closeFile(fdres.get()).isOk()
check:
removeFile("testfile.txt").isOk()
# Open nonexisting file with different flags.
check:
openFile("testfile.txt", {OpenFlags.Append}).isErr()
openFile("testfile.txt", {OpenFlags.Read}).isErr()
openFile("testfile.txt", {OpenFlags.Write}).isErr()
openFile("testfile.txt", {OpenFlags.Read, OpenFlags.Write}).isErr()
openFile("testfile.txt", {OpenFlags.Read, OpenFlags.Write,
OpenFlags.Append}).isErr()
test "toString(set[Permission]) test":
let emptyMask: set[Permission] = {}
check: