Skip to content

Commit df80626

Browse files
committed
Call SyscallConn() instead of Fd() to use file's fd
[os.File.SyscallConn] is the safer alternative to [os.File.Fd], without the pitfalls mentioned in Fd's doc comment. The SyscallConn method is implemented on all platforms except Plan 9, where it returns [syscall.EPLAN9], which matches [errors.ErrUnsupported] and goes to the fallback path.
1 parent 31c2c6c commit df80626

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

reader.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func Open(file string, options ...ReaderOption) (*Reader, error) {
234234
return nil, errors.New("file too large")
235235
}
236236

237-
data, err := mmap(int(mapFile.Fd()), size)
237+
data, err := openMmap(mapFile, size)
238238
if err != nil {
239239
if errors.Is(err, errors.ErrUnsupported) {
240240
data, err = openFallback(mapFile, size)
@@ -257,6 +257,21 @@ func Open(file string, options ...ReaderOption) (*Reader, error) {
257257
return reader, nil
258258
}
259259

260+
func openMmap(f *os.File, size int) (data []byte, err error) {
261+
rawConn, err := f.SyscallConn()
262+
if err != nil {
263+
return nil, err
264+
}
265+
266+
if cerr := rawConn.Control(func(fd uintptr) {
267+
data, err = mmap(int(fd), size)
268+
}); cerr != nil {
269+
return nil, cerr
270+
}
271+
272+
return data, err
273+
}
274+
260275
func openFallback(f *os.File, size int) (data []byte, err error) {
261276
data = make([]byte, size)
262277
_, err = io.ReadFull(f, data)

0 commit comments

Comments
 (0)