Skip to content

Commit 5e1909a

Browse files
committed
Issue #230.
1 parent 77d74ba commit 5e1909a

File tree

5 files changed

+72
-4
lines changed

5 files changed

+72
-4
lines changed

Diff for: vfs/const.go

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const (
3131
_READONLY _ErrorCode = util.READONLY
3232
_IOERR _ErrorCode = util.IOERR
3333
_NOTFOUND _ErrorCode = util.NOTFOUND
34+
_FULL _ErrorCode = util.FULL
3435
_CANTOPEN _ErrorCode = util.CANTOPEN
3536
_IOERR_READ _ErrorCode = util.IOERR_READ
3637
_IOERR_SHORT_READ _ErrorCode = util.IOERR_SHORT_READ
@@ -57,10 +58,12 @@ const (
5758
_IOERR_COMMIT_ATOMIC _ErrorCode = util.IOERR_COMMIT_ATOMIC
5859
_IOERR_ROLLBACK_ATOMIC _ErrorCode = util.IOERR_ROLLBACK_ATOMIC
5960
_IOERR_DATA _ErrorCode = util.IOERR_DATA
61+
_IOERR_CORRUPTFS _ErrorCode = util.IOERR_CORRUPTFS
6062
_BUSY_SNAPSHOT _ErrorCode = util.BUSY_SNAPSHOT
6163
_CANTOPEN_FULLPATH _ErrorCode = util.CANTOPEN_FULLPATH
6264
_CANTOPEN_ISDIR _ErrorCode = util.CANTOPEN_ISDIR
6365
_READONLY_CANTINIT _ErrorCode = util.READONLY_CANTINIT
66+
_READONLY_DIRECTORY _ErrorCode = util.READONLY_DIRECTORY
6467
_OK_SYMLINK _ErrorCode = util.OK_SYMLINK
6568
)
6669

Diff for: vfs/file.go

+17-4
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
8888
oflags |= os.O_RDWR
8989
}
9090

91+
isCreate := flags&(OPEN_CREATE) != 0
92+
isJournl := flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0
93+
9194
var err error
9295
var f *os.File
9396
if name == nil {
@@ -102,6 +105,10 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
102105
if errors.Is(err, syscall.EISDIR) {
103106
return nil, flags, _CANTOPEN_ISDIR
104107
}
108+
if isCreate && isJournl && errors.Is(err, fs.ErrPermission) &&
109+
osAccess(name.String(), ACCESS_EXISTS) != nil {
110+
return nil, flags, _READONLY_DIRECTORY
111+
}
105112
return nil, flags, err
106113
}
107114

@@ -119,10 +126,8 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
119126
File: f,
120127
psow: true,
121128
readOnly: flags&OPEN_READONLY != 0,
122-
syncDir: canSyncDirs &&
123-
flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0 &&
124-
flags&(OPEN_CREATE) != 0,
125-
shm: NewSharedMemory(name.String()+"-shm", flags),
129+
syncDir: canSyncDirs && isCreate && isJournl,
130+
shm: NewSharedMemory(name.String()+"-shm", flags),
126131
}
127132
return &file, flags, nil
128133
}
@@ -154,6 +159,14 @@ func (f *vfsFile) Close() error {
154159
return f.File.Close()
155160
}
156161

162+
func (f *vfsFile) ReadAt(p []byte, off int64) (n int, err error) {
163+
return osReadAt(f.File, p, off)
164+
}
165+
166+
func (f *vfsFile) WriteAt(p []byte, off int64) (n int, err error) {
167+
return osWriteAt(f.File, p, off)
168+
}
169+
157170
func (f *vfsFile) Sync(flags SyncFlag) error {
158171
dataonly := (flags & SYNC_DATAONLY) != 0
159172
fullsync := (flags & 0x0f) == SYNC_FULL

Diff for: vfs/os_std_rw.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//go:build !unix && (!windows || sqlite3_dotlk)
2+
3+
package vfs
4+
5+
import "os"
6+
7+
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
8+
return file.ReadAt(p, off)
9+
}
10+
11+
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
12+
return file.WriteAt(p, off)
13+
}

Diff for: vfs/os_unix.go

+22
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,28 @@ func osAccess(path string, flags AccessFlag) error {
2525
return unix.Access(path, access)
2626
}
2727

28+
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
29+
n, err := file.ReadAt(p, off)
30+
if errno, ok := err.(unix.Errno); ok {
31+
switch errno {
32+
case
33+
unix.ERANGE,
34+
unix.EIO,
35+
unix.ENXIO:
36+
return n, _IOERR_CORRUPTFS
37+
}
38+
}
39+
return n, err
40+
}
41+
42+
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
43+
n, err := file.WriteAt(p, off)
44+
if errno, ok := err.(unix.Errno); ok && errno == unix.ENOSPC {
45+
return n, _FULL
46+
}
47+
return n, err
48+
}
49+
2850
func osSetMode(file *os.File, modeof string) error {
2951
fi, err := os.Stat(modeof)
3052
if err != nil {

Diff for: vfs/os_windows.go

+17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@ import (
99
"golang.org/x/sys/windows"
1010
)
1111

12+
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
13+
return file.ReadAt(p, off)
14+
}
15+
16+
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
17+
n, err := file.WriteAt(p, off)
18+
if errno, ok := err.(windows.Errno); ok {
19+
switch errno {
20+
case
21+
windows.ERROR_HANDLE_DISK_FULL,
22+
windows.ERROR_DISK_FULL:
23+
return n, _FULL
24+
}
25+
}
26+
return n, err
27+
}
28+
1229
func osGetSharedLock(file *os.File) _ErrorCode {
1330
// Acquire the PENDING lock temporarily before acquiring a new SHARED lock.
1431
rc := osReadLock(file, _PENDING_BYTE, 1, 0)

0 commit comments

Comments
 (0)