Files
stfs/pkg/mtio/mtio_linux.go
2022-01-16 23:50:47 +01:00

118 lines
2.0 KiB
Go

//go:build linux
package mtio
import (
"syscall"
"unsafe"
)
// See https://github.com/benmcclelland/mtio
const (
mtioCpos = 0x80086d03 // Get tape position
mtioCtop = 0x40086d01 // Do magnetic tape operation
mtFsf = 1 // Forward space over FileMark, position at first record of next file
mtOffl = 7 // Rewind and put the drive offline (eject?)
mtEom = 12 // Goto end of recorded media (for appending files)
mtSeek = 22 // Seek to block
)
// position is struct for MTIOCPOS
type position struct {
blkNo int64 // Current block number
}
// operation is struct for MTIOCTOP
type operation struct {
op int16 // Operation ID
pad int16 // Padding to match C structures
count int32 // Operation count
}
type MagneticTapeIO struct{}
func (t MagneticTapeIO) GetCurrentRecordFromTape(fd uintptr) (int64, error) {
pos := &position{}
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCpos,
uintptr(unsafe.Pointer(pos)),
); err != 0 {
return 0, err
}
return pos.blkNo, nil
}
func (t MagneticTapeIO) GoToEndOfTape(fd uintptr) error {
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCtop,
uintptr(unsafe.Pointer(
&operation{
op: mtEom,
},
)),
); err != 0 {
return err
}
return nil
}
func (t MagneticTapeIO) GoToNextFileOnTape(fd uintptr) error {
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCtop,
uintptr(unsafe.Pointer(
&operation{
op: mtFsf,
count: 1,
},
)),
); err != 0 {
return err
}
return nil
}
func (t MagneticTapeIO) EjectTape(fd uintptr) error {
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCtop,
uintptr(unsafe.Pointer(
&operation{
op: mtOffl,
},
)),
); err != 0 {
return err
}
return nil
}
func (t MagneticTapeIO) SeekToRecordOnTape(fd uintptr, record int32) error {
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCtop,
uintptr(unsafe.Pointer(
&operation{
op: mtSeek,
count: record,
},
)),
); err != 0 {
return err
}
return nil
}