Skip to content

Commit

Permalink
add file.Truncate
Browse files Browse the repository at this point in the history
  • Loading branch information
leongross committed Mar 27, 2024
1 parent a5ceb79 commit a116c85
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 5 deletions.
20 changes: 15 additions & 5 deletions src/os/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,14 +283,24 @@ func (f *File) Sync() (err error) {
return
}

// Truncate is a stub, not yet implemented
// 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 {
err = ErrClosed
} else {
err = ErrNotImplemented
return ErrClosed
}
return &PathError{Op: "truncate", Path: f.name, Err: err}

e := ignoringEINTR(func() error {

Check failure on line 296 in src/os/file.go

View workflow job for this annotation

GitHub Actions / build-macos (macos-14)

undefined: ignoringEINTR
return syscall.Truncate(f.name, size)

Check failure on line 297 in src/os/file.go

View workflow job for this annotation

GitHub Actions / build-macos (macos-14)

undefined: syscall.Truncate
})

if e != nil {
return &PathError{Op: "truncate", Path: f.name, Err: e}
}
return
}

// LinkError records an error during a link or symlink or rename system call and
Expand Down
58 changes: 58 additions & 0 deletions src/os/truncate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//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"
. "os"
"path/filepath"
"testing"
)

func TestTruncate(t *testing.T) {
tmpDir, _ := os.MkdirTemp("", "TestTruncate")
if err := RemoveAll(""); err != nil {
t.Errorf("Truncate(\"\"): %v; want nil", err)
}

file := filepath.Join(tmpDir, "truncate_0x100")

fd, err := Create(file)
if err != nil {
t.Fatalf("create %q: %s", file, err)
}

// truncate up to 0x100
if err := fd.Truncate(0x100); err != nil {
t.Fatalf("truncate %q: %s", file, err)
}

// check if size is 0x100
fi, err := Stat(file)
if err != nil {
t.Fatalf("stat %q: %s", 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: %s", file, err)
}

// check if size is 0x80
fi, err = Stat(file)
if err != nil {
t.Fatalf("stat %q: %s", file, err)
}

if fi.Size() != 0x80 {
t.Fatalf("size of %q is %d; want 0x80", file, fi.Size())
}
}
14 changes: 14 additions & 0 deletions src/syscall/syscall_libc.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,15 @@ func Unlink(path string) (err error) {
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 Kill(pid int, sig Signal) (err error) {
Expand Down Expand Up @@ -431,5 +440,10 @@ func libc_readlink(path *byte, buf *byte, count uint) int
//export unlink
func libc_unlink(pathname *byte) int32

// int truncate(const char *path, off_t length);
//
//export truncate
func libc_truncate(path *byte, length int64) int32

//go:extern environ
var libc_environ *unsafe.Pointer

0 comments on commit a116c85

Please sign in to comment.