@@ -235,7 +235,7 @@ func NewCallbackCDecl(fn any) uintptr {
235
235
//sys GetVersion() (ver uint32, err error)
236
236
//sys formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
237
237
//sys ExitProcess(exitcode uint32)
238
- //sys CreateFile (name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval== InvalidHandle] = CreateFileW
238
+ //sys createFile (name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval == InvalidHandle || e1 == ERROR_ALREADY_EXISTS ] = CreateFileW
239
239
//sys readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = ReadFile
240
240
//sys writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = WriteFile
241
241
//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
@@ -404,18 +404,20 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) {
404
404
const _FILE_FLAG_WRITE_THROUGH = 0x80000000
405
405
attrs |= _FILE_FLAG_WRITE_THROUGH
406
406
}
407
- h , err := CreateFile (namep , access , sharemode , sa , createmode , attrs , 0 )
408
- if err != nil {
407
+ h , err := createFile (namep , access , sharemode , sa , createmode , attrs , 0 )
408
+ if h == InvalidHandle {
409
409
if err == ERROR_ACCESS_DENIED && (flag & O_WRONLY != 0 || flag & O_RDWR != 0 ) {
410
410
// We should return EISDIR when we are trying to open a directory with write access.
411
411
fa , e1 := GetFileAttributes (namep )
412
412
if e1 == nil && fa & FILE_ATTRIBUTE_DIRECTORY != 0 {
413
413
err = EISDIR
414
414
}
415
415
}
416
- return InvalidHandle , err
416
+ return h , err
417
417
}
418
- if flag & O_TRUNC == O_TRUNC {
418
+ // Ignore O_TRUNC if the file has just been created.
419
+ if flag & O_TRUNC == O_TRUNC &&
420
+ (createmode == OPEN_EXISTING || (createmode == OPEN_ALWAYS && err == ERROR_ALREADY_EXISTS )) {
419
421
err = Ftruncate (h , 0 )
420
422
if err != nil {
421
423
CloseHandle (h )
@@ -1454,3 +1456,13 @@ func GetStartupInfo(startupInfo *StartupInfo) error {
1454
1456
getStartupInfo (startupInfo )
1455
1457
return nil
1456
1458
}
1459
+
1460
+ func CreateFile (name * uint16 , access uint32 , mode uint32 , sa * SecurityAttributes , createmode uint32 , attrs uint32 , templatefile int32 ) (handle Handle , err error ) {
1461
+ handle , err = createFile (name , access , mode , sa , createmode , attrs , templatefile )
1462
+ if handle != InvalidHandle {
1463
+ // CreateFileW can return ERROR_ALREADY_EXISTS with a valid handle.
1464
+ // We only want to return an error if the handle is invalid.
1465
+ err = nil
1466
+ }
1467
+ return handle , err
1468
+ }
0 commit comments