github.com/artpar/rclone@v1.67.3/cmd/serve/docker/unix.go (about)

     1  //go:build linux || freebsd
     2  
     3  package docker
     4  
     5  import (
     6  	"fmt"
     7  	"net"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"github.com/artpar/rclone/lib/file"
    12  )
    13  
    14  func newUnixListener(path string, gid int) (net.Listener, string, error) {
    15  	// try systemd socket activation
    16  	fds := systemdActivationFiles()
    17  	switch len(fds) {
    18  	case 0:
    19  		// fall thru
    20  	case 1:
    21  		listener, err := net.FileListener(fds[0])
    22  		return listener, "", err
    23  	default:
    24  		return nil, "", fmt.Errorf("expected only one socket from systemd, got %d", len(fds))
    25  	}
    26  
    27  	// create socket ourselves
    28  	if filepath.Ext(path) == "" {
    29  		path += ".sock"
    30  	}
    31  	if !filepath.IsAbs(path) {
    32  		path = filepath.Join(sockDir, path)
    33  	}
    34  
    35  	if err := file.MkdirAll(filepath.Dir(path), 0755); err != nil {
    36  		return nil, "", err
    37  	}
    38  	if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
    39  		return nil, "", err
    40  	}
    41  
    42  	listener, err := net.Listen("unix", path)
    43  	if err != nil {
    44  		return nil, "", err
    45  	}
    46  
    47  	if err = os.Chmod(path, 0660); err != nil {
    48  		return nil, "", err
    49  	}
    50  	if os.Geteuid() == 0 {
    51  		if err = os.Chown(path, 0, gid); err != nil {
    52  			return nil, "", err
    53  		}
    54  	}
    55  
    56  	// we don't use spec file with unix sockets
    57  	return listener, path, nil
    58  }