github.com/cnboonhan/delve@v0.0.0-20230908061759-363f2388c2fb/pkg/proc/redirector_other.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package proc
     5  
     6  import (
     7  	"crypto/rand"
     8  	"encoding/hex"
     9  	"io"
    10  	"os"
    11  	"path/filepath"
    12  	"syscall"
    13  )
    14  
    15  type openOnRead struct {
    16  	path string
    17  	rd   io.ReadCloser
    18  }
    19  
    20  func (oor *openOnRead) Read(p []byte) (n int, err error) {
    21  	if oor.rd != nil {
    22  		return oor.rd.Read(p)
    23  	}
    24  
    25  	fh, err := os.OpenFile(oor.path, os.O_RDONLY, os.ModeNamedPipe)
    26  	if err != nil {
    27  		return 0, err
    28  	}
    29  
    30  	oor.rd = fh
    31  	return oor.rd.Read(p)
    32  }
    33  
    34  func (oor *openOnRead) Close() error {
    35  	defer os.Remove(oor.path)
    36  
    37  	fh, _ := os.OpenFile(oor.path, os.O_WRONLY|syscall.O_NONBLOCK, 0)
    38  	if fh != nil {
    39  		fh.Close()
    40  	}
    41  
    42  	return oor.rd.Close()
    43  }
    44  
    45  func Redirector() (reader io.ReadCloser, output OutputRedirect, err error) {
    46  	r := make([]byte, 4)
    47  	if _, err = rand.Read(r); err != nil {
    48  		return reader, output, err
    49  	}
    50  
    51  	var path = filepath.Join(os.TempDir(), hex.EncodeToString(r))
    52  
    53  	if err = syscall.Mkfifo(path, 0o600); err != nil {
    54  		_ = os.Remove(path)
    55  		return reader, output, err
    56  	}
    57  
    58  	return &openOnRead{path: path}, OutputRedirect{Path: path}, nil
    59  }