rewrite html generator with html/template
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package disk_usage
|
||||
|
||||
import "errors"
|
||||
|
||||
var ErrNotSupported = errors.New("disk_usage: not supported on this OS")
|
||||
|
||||
// Used + Free can be less than Total: space reserved for root/admin
|
||||
// is not free for this process, but not used either.
|
||||
type Usage struct {
|
||||
// size of the file system (available to this user, if there are quotas)
|
||||
Total int64
|
||||
// Total minus all free space, including reserved
|
||||
Used int64
|
||||
// available to this process
|
||||
Free int64
|
||||
}
|
||||
|
||||
// DiskUsage returns usage of the file system that contains path.
|
||||
func DiskUsage(path string) (Usage, error) {
|
||||
return diskUsage(path)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
//go:build !(linux || darwin || freebsd || windows)
|
||||
|
||||
// Fallback, so the program still builds on other OSes.
|
||||
|
||||
package disk_usage
|
||||
|
||||
func diskUsage(path string) (Usage, error) {
|
||||
return Usage{}, ErrNotSupported
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//go:build linux || darwin || freebsd
|
||||
|
||||
// "_unix" is not a special file name suffix for Go, so the OS list is in the //go:build line.
|
||||
// Not "unix": openbsd and netbsd have different Statfs_t or no syscall.Statfs.
|
||||
|
||||
package disk_usage
|
||||
|
||||
import "syscall"
|
||||
|
||||
func diskUsage(path string) (Usage, error) {
|
||||
var st syscall.Statfs_t
|
||||
if err := syscall.Statfs(path, &st); err != nil {
|
||||
return Usage{}, err
|
||||
}
|
||||
// Field types differ between OSes, int64() works for all of them.
|
||||
bsize := int64(st.Bsize)
|
||||
return Usage{
|
||||
Total: int64(st.Blocks) * bsize,
|
||||
// Bfree: all free blocks, including reserved for root
|
||||
Used: (int64(st.Blocks) - int64(st.Bfree)) * bsize,
|
||||
// Bavail: free blocks available to unprivileged users
|
||||
Free: int64(st.Bavail) * bsize,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package disk_usage
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Loaded on first call. kernel32.dll is a KnownDLL,
|
||||
// Windows always loads it from the system directory.
|
||||
var procGetDiskFreeSpaceExW = syscall.NewLazyDLL("kernel32.dll").NewProc("GetDiskFreeSpaceExW")
|
||||
|
||||
func diskUsage(path string) (Usage, error) {
|
||||
pathPtr, err := syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return Usage{}, err
|
||||
}
|
||||
// BOOL GetDiskFreeSpaceExW(LPCWSTR lpDirectoryName,
|
||||
// PULARGE_INTEGER lpFreeBytesAvailableToCaller, // respects user disk quotas
|
||||
// PULARGE_INTEGER lpTotalNumberOfBytes, // respects user disk quotas
|
||||
// PULARGE_INTEGER lpTotalNumberOfFreeBytes); // whole disk
|
||||
var freeToCaller, total, totalFree uint64
|
||||
ok, _, callErr := procGetDiskFreeSpaceExW.Call(
|
||||
uintptr(unsafe.Pointer(pathPtr)),
|
||||
uintptr(unsafe.Pointer(&freeToCaller)),
|
||||
uintptr(unsafe.Pointer(&total)),
|
||||
uintptr(unsafe.Pointer(&totalFree)))
|
||||
if ok == 0 {
|
||||
// Call always returns non-nil error, it is meaningful only if the function failed
|
||||
return Usage{}, callErr
|
||||
}
|
||||
return Usage{
|
||||
Total: int64(total),
|
||||
// with quotas totalFree can be > total
|
||||
Used: max(int64(total)-int64(totalFree), 0),
|
||||
Free: int64(freeToCaller),
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user