mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 06:06:27 +08:00
Add lib/diskusage to measure used/free on disks
This commit is contained in:
parent
8c25a15a40
commit
0fb36562dd
15
lib/diskusage/diskusage.go
Normal file
15
lib/diskusage/diskusage.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Package diskusage provides a cross platform version of the statfs
|
||||
// system call to read disk space usage.
|
||||
package diskusage
|
||||
|
||||
import "errors"
|
||||
|
||||
// Info is returned from New showing details about the disk.
|
||||
type Info struct {
|
||||
Free uint64 // total free bytes
|
||||
Available uint64 // free bytes available to the current user
|
||||
Total uint64 // total bytes on disk
|
||||
}
|
||||
|
||||
// ErrUnsupported is returned if this platform doesn't support disk usage.
|
||||
var ErrUnsupported = errors.New("disk usage unsupported on this platform")
|
27
lib/diskusage/diskusage_netbsd.go
Normal file
27
lib/diskusage/diskusage_netbsd.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
//go:build netbsd
|
||||
|
||||
package diskusage
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// New returns the disk status for dir.
|
||||
//
|
||||
// May return Unsupported error if it doesn't work on this platform.
|
||||
func New(dir string) (info Info, err error) {
|
||||
var statfs unix.Statvfs_t
|
||||
err = unix.Statvfs(dir, &statfs)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
// Note that these can be different sizes on different OSes so
|
||||
// we upcast them all to uint64
|
||||
//nolint:unconvert
|
||||
info.Free = uint64(statfs.Bfree) * uint64(statfs.Bsize)
|
||||
//nolint:unconvert
|
||||
info.Available = uint64(statfs.Bavail) * uint64(statfs.Bsize)
|
||||
//nolint:unconvert
|
||||
info.Total = uint64(statfs.Blocks) * uint64(statfs.Bsize)
|
||||
return info, nil
|
||||
}
|
27
lib/diskusage/diskusage_openbsd.go
Normal file
27
lib/diskusage/diskusage_openbsd.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
//go:build openbsd
|
||||
|
||||
package diskusage
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// New returns the disk status for dir.
|
||||
//
|
||||
// May return Unsupported error if it doesn't work on this platform.
|
||||
func New(dir string) (info Info, err error) {
|
||||
var statfs unix.Statfs_t
|
||||
err = unix.Statfs(dir, &statfs)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
// Note that these can be different sizes on different OSes so
|
||||
// we upcast them all to uint64
|
||||
//nolint:unconvert
|
||||
info.Free = uint64(statfs.F_bfree) * uint64(statfs.F_bsize)
|
||||
//nolint:unconvert
|
||||
info.Available = uint64(statfs.F_bavail) * uint64(statfs.F_bsize)
|
||||
//nolint:unconvert
|
||||
info.Total = uint64(statfs.F_blocks) * uint64(statfs.F_bsize)
|
||||
return info, nil
|
||||
}
|
23
lib/diskusage/diskusage_test.go
Normal file
23
lib/diskusage/diskusage_test.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
package diskusage
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
info, err := New(".")
|
||||
if err == ErrUnsupported {
|
||||
t.Skip(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
t.Logf("Free %16d", info.Free)
|
||||
t.Logf("Available %16d", info.Available)
|
||||
t.Logf("Total %16d", info.Total)
|
||||
assert.True(t, info.Total != 0)
|
||||
assert.True(t, info.Total > info.Free)
|
||||
assert.True(t, info.Total > info.Available)
|
||||
assert.True(t, info.Free >= info.Available)
|
||||
}
|
27
lib/diskusage/diskusage_unix.go
Normal file
27
lib/diskusage/diskusage_unix.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
//go:build aix || android || darwin || dragonfly || freebsd || ios || linux
|
||||
|
||||
package diskusage
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// New returns the disk status for dir.
|
||||
//
|
||||
// May return Unsupported error if it doesn't work on this platform.
|
||||
func New(dir string) (info Info, err error) {
|
||||
var statfs unix.Statfs_t
|
||||
err = unix.Statfs(dir, &statfs)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
// Note that these can be different sizes on different OSes so
|
||||
// we upcast them all to uint64
|
||||
//nolint:unconvert
|
||||
info.Free = uint64(statfs.Bfree) * uint64(statfs.Bsize)
|
||||
//nolint:unconvert
|
||||
info.Available = uint64(statfs.Bavail) * uint64(statfs.Bsize)
|
||||
//nolint:unconvert
|
||||
info.Total = uint64(statfs.Blocks) * uint64(statfs.Bsize)
|
||||
return info, nil
|
||||
}
|
10
lib/diskusage/diskusage_unsupported.go
Normal file
10
lib/diskusage/diskusage_unsupported.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
//go:build illumos || js || plan9 || solaris
|
||||
|
||||
package diskusage
|
||||
|
||||
// New returns the disk status for dir.
|
||||
//
|
||||
// May return Unsupported error if it doesn't work on this platform.
|
||||
func New(dir string) (info Info, err error) {
|
||||
return info, ErrUnsupported
|
||||
}
|
16
lib/diskusage/diskusage_windows.go
Normal file
16
lib/diskusage/diskusage_windows.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
//go:build windows
|
||||
|
||||
package diskusage
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// New returns the disk status for dir.
|
||||
//
|
||||
// May return Unsupported error if it doesn't work on this platform.
|
||||
func New(dir string) (info Info, err error) {
|
||||
dir16 := windows.StringToUTF16Ptr(dir)
|
||||
err = windows.GetDiskFreeSpaceEx(dir16, &info.Available, &info.Total, &info.Free)
|
||||
return info, err
|
||||
}
|
Loading…
Reference in New Issue
Block a user