mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-16 02:33:28 +00:00
os: add file.Truncate
This commit is contained in:
@@ -290,16 +290,6 @@ func (f *File) Sync() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Truncate is a stub, not yet implemented
|
|
||||||
func (f *File) Truncate(size int64) (err error) {
|
|
||||||
if f.handle == nil {
|
|
||||||
err = ErrClosed
|
|
||||||
} else {
|
|
||||||
err = ErrNotImplemented
|
|
||||||
}
|
|
||||||
return &PathError{Op: "truncate", Path: f.name, Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinkError records an error during a link or symlink or rename system call and
|
// LinkError records an error during a link or symlink or rename system call and
|
||||||
// the paths that caused it.
|
// the paths that caused it.
|
||||||
type LinkError struct {
|
type LinkError struct {
|
||||||
|
|||||||
@@ -125,6 +125,25 @@ func Readlink(name string) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Truncate changes the size of the file.
|
||||||
|
// It does not change the I/O offset.
|
||||||
|
// If there is an error, it will be of type *PathError.
|
||||||
|
// Alternatively just use 'raw' syscall by file name
|
||||||
|
func (f *File) Truncate(size int64) (err error) {
|
||||||
|
if f.handle == nil {
|
||||||
|
return ErrClosed
|
||||||
|
}
|
||||||
|
|
||||||
|
e := ignoringEINTR(func() error {
|
||||||
|
return syscall.Truncate(f.name, size)
|
||||||
|
})
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
return &PathError{Op: "truncate", Path: f.name, Err: e}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ReadAt reads up to len(b) bytes from the File starting at the given absolute offset.
|
// ReadAt reads up to len(b) bytes from the File starting at the given absolute offset.
|
||||||
// It returns the number of bytes read and any error encountered, possibly io.EOF.
|
// It returns the number of bytes read and any error encountered, possibly io.EOF.
|
||||||
// At end of file, Pread returns 0, io.EOF.
|
// At end of file, Pread returns 0, io.EOF.
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ func Pipe() (r *File, w *File, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *unixFileHandle) Truncate(size int64) error {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func tempDir() string {
|
func tempDir() string {
|
||||||
n := uint32(syscall.MAX_PATH)
|
n := uint32(syscall.MAX_PATH)
|
||||||
for {
|
for {
|
||||||
@@ -106,6 +110,16 @@ func (f unixFileHandle) Sync() error {
|
|||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *File) Truncate(size int64) error {
|
||||||
|
var err error
|
||||||
|
if f.handle == nil {
|
||||||
|
err = ErrClosed
|
||||||
|
} else {
|
||||||
|
err = ErrNotImplemented
|
||||||
|
}
|
||||||
|
return &PathError{Op: "truncate", Path: f.name, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
// isWindowsNulName reports whether name is os.DevNull ('NUL') on Windows.
|
// isWindowsNulName reports whether name is os.DevNull ('NUL') on Windows.
|
||||||
// True is returned if name is 'NUL' whatever the case.
|
// True is returned if name is 'NUL' whatever the case.
|
||||||
func isWindowsNulName(name string) bool {
|
func isWindowsNulName(name string) bool {
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
//go:build darwin || (linux && !baremetal && !js && !wasi)
|
||||||
|
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package os_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTruncate(t *testing.T) {
|
||||||
|
// Truncate is not supported on Windows or wasi at the moment
|
||||||
|
if runtime.GOOS == "windows" || runtime.GOOS == "wasip1" || runtime.GOOS == "wasip2" {
|
||||||
|
t.Logf("skipping test on %s", runtime.GOOS)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
file := filepath.Join(tmpDir, "truncate_test")
|
||||||
|
|
||||||
|
fd, err := Create(file)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("create %q: got %v, want nil", file, err)
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
|
||||||
|
// truncate up to 0x100
|
||||||
|
if err := fd.Truncate(0x100); err != nil {
|
||||||
|
t.Fatalf("truncate %q: got %v, want nil", file, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if size is 0x100
|
||||||
|
fi, err := Stat(file)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("stat %q: got %v, want nil", file, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fi.Size() != 0x100 {
|
||||||
|
t.Fatalf("size of %q is %d; want 0x100", file, fi.Size())
|
||||||
|
}
|
||||||
|
|
||||||
|
// truncate down to 0x80
|
||||||
|
if err := fd.Truncate(0x80); err != nil {
|
||||||
|
t.Fatalf("truncate %q: got %v, want nil", file, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if size is 0x80
|
||||||
|
fi, err = Stat(file)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("stat %q: got %v, want nil", file, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fi.Size() != 0x80 {
|
||||||
|
t.Fatalf("size of %q is %d; want 0x80", file, fi.Size())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -432,7 +432,6 @@ func chmod(pathname *byte, mode uint32) int32 {
|
|||||||
//
|
//
|
||||||
//export mkdir
|
//export mkdir
|
||||||
func mkdir(pathname *byte, mode uint32) int32 {
|
func mkdir(pathname *byte, mode uint32) int32 {
|
||||||
|
|
||||||
path := goString(pathname)
|
path := goString(pathname)
|
||||||
dir, relPath := findPreopenForPath(path)
|
dir, relPath := findPreopenForPath(path)
|
||||||
if dir.d == cm.ResourceNone {
|
if dir.d == cm.ResourceNone {
|
||||||
@@ -773,7 +772,6 @@ var libcCWD wasiDir
|
|||||||
var wasiPreopens map[string]types.Descriptor
|
var wasiPreopens map[string]types.Descriptor
|
||||||
|
|
||||||
func populatePreopens() {
|
func populatePreopens() {
|
||||||
|
|
||||||
var cwd string
|
var cwd string
|
||||||
|
|
||||||
// find CWD
|
// find CWD
|
||||||
@@ -1354,3 +1352,11 @@ func getcwd(buf *byte, size uint) *byte {
|
|||||||
copy(s, cwd)
|
copy(s, cwd)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int truncate(const char *path, off_t length);
|
||||||
|
//
|
||||||
|
//export truncate
|
||||||
|
func truncate(path *byte, length int64) int32 {
|
||||||
|
libcErrno = ENOSYS
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|||||||
@@ -203,6 +203,15 @@ func Execve(pathname string, argv []string, envv []string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Truncate(path string, length int64) (err error) {
|
||||||
|
data := cstring(path)
|
||||||
|
fail := int(libc_truncate(&data[0], length))
|
||||||
|
if fail < 0 {
|
||||||
|
err = getErrno()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
|
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
|
||||||
|
|
||||||
func Kill(pid int, sig Signal) (err error) {
|
func Kill(pid int, sig Signal) (err error) {
|
||||||
@@ -451,3 +460,8 @@ func libc_fork() int32
|
|||||||
//
|
//
|
||||||
//export execve
|
//export execve
|
||||||
func libc_execve(filename *byte, argv **byte, envp **byte) int
|
func libc_execve(filename *byte, argv **byte, envp **byte) int
|
||||||
|
|
||||||
|
// int truncate(const char *path, off_t length);
|
||||||
|
//
|
||||||
|
//export truncate
|
||||||
|
func libc_truncate(path *byte, length int64) int32
|
||||||
|
|||||||
Reference in New Issue
Block a user