refactor: Use explicit reader/writer instead of filepath for drive
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
package tape
|
||||
|
||||
import "os"
|
||||
|
||||
func OpenTapeReadOnly(drive string) (f *os.File, isRegular bool, err error) {
|
||||
fileDescription, err := os.Stat(drive)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
isRegular = fileDescription.Mode().IsRegular()
|
||||
if isRegular {
|
||||
f, err = os.Open(drive)
|
||||
if err != nil {
|
||||
return f, isRegular, err
|
||||
}
|
||||
|
||||
return f, isRegular, nil
|
||||
}
|
||||
|
||||
f, err = os.OpenFile(drive, os.O_RDONLY, os.ModeCharDevice)
|
||||
if err != nil {
|
||||
return f, isRegular, err
|
||||
}
|
||||
|
||||
return f, isRegular, nil
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package tape
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bufio"
|
||||
"os"
|
||||
|
||||
"github.com/pojntfx/stfs/internal/ioext"
|
||||
"github.com/pojntfx/stfs/internal/mtio"
|
||||
)
|
||||
|
||||
func OpenTapeWriteOnly(drive string, recordSize int, overwrite bool) (tw *tar.Writer, isRegular bool, cleanup func(dirty *bool) error, err error) {
|
||||
stat, err := os.Stat(drive)
|
||||
if err == nil {
|
||||
isRegular = stat.Mode().IsRegular()
|
||||
} else {
|
||||
if os.IsNotExist(err) {
|
||||
isRegular = true
|
||||
} else {
|
||||
return nil, false, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var f *os.File
|
||||
if isRegular {
|
||||
f, err = os.OpenFile(drive, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
return nil, false, nil, err
|
||||
}
|
||||
|
||||
// No need to go to end manually due to `os.O_APPEND`
|
||||
} else {
|
||||
f, err = os.OpenFile(drive, os.O_APPEND|os.O_WRONLY, os.ModeCharDevice)
|
||||
if err != nil {
|
||||
return nil, false, nil, err
|
||||
}
|
||||
|
||||
if !overwrite {
|
||||
// Go to end of tape
|
||||
if err := mtio.GoToEndOfTape(f); err != nil {
|
||||
return nil, false, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var bw *bufio.Writer
|
||||
var counter *ioext.CounterWriter
|
||||
if isRegular {
|
||||
tw = tar.NewWriter(f)
|
||||
} else {
|
||||
bw = bufio.NewWriterSize(f, mtio.BlockSize*recordSize)
|
||||
counter = &ioext.CounterWriter{Writer: bw, BytesRead: 0}
|
||||
tw = tar.NewWriter(counter)
|
||||
}
|
||||
|
||||
return tw, isRegular, func(dirty *bool) error {
|
||||
// Only write the trailer if we wrote to the archive
|
||||
if *dirty {
|
||||
if err := tw.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !isRegular {
|
||||
if mtio.BlockSize*recordSize-counter.BytesRead > 0 {
|
||||
// Fill the rest of the record with zeros
|
||||
if _, err := bw.Write(make([]byte, mtio.BlockSize*recordSize-counter.BytesRead)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := bw.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return f.Close()
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package tarext
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bufio"
|
||||
"io"
|
||||
|
||||
"github.com/pojntfx/stfs/internal/ioext"
|
||||
"github.com/pojntfx/stfs/internal/mtio"
|
||||
)
|
||||
|
||||
func NewTapeWriter(f io.Writer, isRegular bool, recordSize int) (tw *tar.Writer, cleanup func(dirty *bool) error, err error) {
|
||||
var bw *bufio.Writer
|
||||
var counter *ioext.CounterWriter
|
||||
if isRegular {
|
||||
tw = tar.NewWriter(f)
|
||||
} else {
|
||||
bw = bufio.NewWriterSize(f, mtio.BlockSize*recordSize)
|
||||
counter = &ioext.CounterWriter{Writer: bw, BytesRead: 0}
|
||||
tw = tar.NewWriter(counter)
|
||||
}
|
||||
|
||||
return tw, func(dirty *bool) error {
|
||||
// Only write the trailer if we wrote to the archive
|
||||
if *dirty {
|
||||
if err := tw.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !isRegular {
|
||||
if mtio.BlockSize*recordSize-counter.BytesRead > 0 {
|
||||
// Fill the rest of the record with zeros
|
||||
if _, err := bw.Write(make([]byte, mtio.BlockSize*recordSize-counter.BytesRead)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := bw.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user