github.com/apptainer/singularity@v3.1.1+incompatible/pkg/util/unix/socket.go (about) 1 // Copyright (c) 2018, Sylabs Inc. All rights reserved. 2 // This software is licensed under a 3-clause BSD license. Please consult the 3 // LICENSE.md file distributed with the sources of this project regarding your 4 // rights to use or distribute this software. 5 6 package unix 7 8 import ( 9 "fmt" 10 "net" 11 "os" 12 "path/filepath" 13 "runtime" 14 "syscall" 15 ) 16 17 // Listen wraps net.Listen to handle 108 characters issue 18 func Listen(path string) (net.Listener, error) { 19 socket := path 20 21 if len(path) >= 108 { 22 runtime.LockOSThread() 23 defer runtime.UnlockOSThread() 24 25 cwd, err := os.Getwd() 26 if err != nil { 27 return nil, fmt.Errorf("failed to get current working directory: %s", err) 28 } 29 defer os.Chdir(cwd) 30 31 dir := filepath.Dir(path) 32 socket = filepath.Base(path) 33 34 if err := os.Chdir(dir); err != nil { 35 return nil, fmt.Errorf("failed to go into %s: %s", dir, err) 36 } 37 } 38 39 return net.Listen("unix", socket) 40 } 41 42 // Dial wraps net.Dial to handle 108 characters issue 43 func Dial(path string) (net.Conn, error) { 44 socket := path 45 46 if len(path) >= 108 { 47 runtime.LockOSThread() 48 defer runtime.UnlockOSThread() 49 50 cwd, err := os.Getwd() 51 if err != nil { 52 return nil, fmt.Errorf("failed to get current working directory: %s", err) 53 } 54 defer os.Chdir(cwd) 55 56 dir := filepath.Dir(path) 57 socket = filepath.Base(path) 58 59 if err := os.Chdir(dir); err != nil { 60 return nil, fmt.Errorf("failed to go into %s: %s", dir, err) 61 } 62 } 63 64 return net.Dial("unix", socket) 65 } 66 67 // CreateSocket creates an unix socket and returns connection listener. 68 func CreateSocket(path string) (net.Listener, error) { 69 oldmask := syscall.Umask(0177) 70 defer syscall.Umask(oldmask) 71 return Listen(path) 72 } 73 74 // WriteSocket writes data over unix socket 75 func WriteSocket(path string, data []byte) error { 76 c, err := Dial(path) 77 78 if err != nil { 79 return fmt.Errorf("failed to connect to %s socket: %s", path, err) 80 } 81 defer c.Close() 82 83 if _, err := c.Write(data); err != nil { 84 return fmt.Errorf("failed to send data over socket: %s", err) 85 } 86 87 return nil 88 }