gopass/pkg/tempfile/file.go
Dominik Schulz 0cfa536d28
Add debug package (#1396)
This commit adds a new debug package to gopass.
It is heavily inspired by github.com/restic/restic/internal/debug
and adapted for the gopass use case.

This change allows to further trim down the source code since the
new package doesn't propagate the debug flag in the context anymore.
As such we can now omit passing ctx in most places.

In order to ensure we don't accidentially keep passing ununsed
parameters we also introduce unparam to check for extra arguments.

RELEASE_NOTES=[ENHANCEMENT] New Debug package

Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
2020-05-29 13:47:35 +02:00

85 lines
1.6 KiB
Go

// Package tempfile is a wrapper around ioutil.TempDir, providing an OO pattern
// as well as secure placement on a temporary ramdisk.
package tempfile
import (
"context"
"io/ioutil"
"os"
"path/filepath"
"github.com/pkg/errors"
)
// globalPrefix is prefixed to all temporary dirs
var globalPrefix string
// File is a temporary file
type File struct {
dir string
dev string
fh *os.File
}
// New returns a new tempfile wrapper
func New(ctx context.Context, prefix string) (*File, error) {
td, err := ioutil.TempDir(tempdirBase(), globalPrefix+prefix)
if err != nil {
return nil, err
}
tf := &File{
dir: td,
}
if err := tf.mount(ctx); err != nil {
_ = os.RemoveAll(tf.dir)
return nil, err
}
fn := filepath.Join(tf.dir, "secret")
fh, err := os.OpenFile(fn, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600)
if err != nil {
return nil, errors.Errorf("Failed to open file %s: %s", fn, err)
}
tf.fh = fh
return tf, nil
}
// Name returns the name of the tempfile
func (t *File) Name() string {
if t.fh == nil {
return ""
}
return t.fh.Name()
}
// Write implement io.Writer
func (t *File) Write(p []byte) (int, error) {
if t.fh == nil {
return 0, errors.Errorf("not initialized")
}
return t.fh.Write(p)
}
// Close implements io.WriteCloser
func (t *File) Close() error {
if t.fh == nil {
return nil
}
return t.fh.Close()
}
// Remove attempts to remove the tempfile
func (t *File) Remove(ctx context.Context) error {
_ = t.Close()
if err := t.unmount(ctx); err != nil {
return errors.Errorf("Failed to unmount %s from %s: %s", t.dev, t.dir, err)
}
if t.dir == "" {
return nil
}
return os.RemoveAll(t.dir)
}