1 // Copyright 2015 CoreOS, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build !windows 16 // +build !windows 17 18 // Package activation implements primitives for systemd socket activation. 19 package activation 20 21 import ( 22 "os" 23 "strconv" 24 "strings" 25 "syscall" 26 ) 27 28 const ( 29 // listenFdsStart corresponds to `SD_LISTEN_FDS_START`. 30 listenFdsStart = 3 31 ) 32 33 // Files returns a slice containing a `os.File` object for each 34 // file descriptor passed to this process via systemd fd-passing protocol. 35 // 36 // The order of the file descriptors is preserved in the returned slice. 37 // `unsetEnv` is typically set to `true` in order to avoid clashes in 38 // fd usage and to avoid leaking environment flags to child processes. 39 func Files(unsetEnv bool) []*os.File { 40 if unsetEnv { 41 defer os.Unsetenv("LISTEN_PID") 42 defer os.Unsetenv("LISTEN_FDS") 43 defer os.Unsetenv("LISTEN_FDNAMES") 44 } 45 46 pid, err := strconv.Atoi(os.Getenv("LISTEN_PID")) 47 if err != nil || pid != os.Getpid() { 48 return nil 49 } 50 51 nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS")) 52 if err != nil || nfds == 0 { 53 return nil 54 } 55 56 names := strings.Split(os.Getenv("LISTEN_FDNAMES"), ":") 57 58 files := make([]*os.File, 0, nfds) 59 for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ { 60 syscall.CloseOnExec(fd) 61 name := "LISTEN_FD_" + strconv.Itoa(fd) 62 offset := fd - listenFdsStart 63 if offset < len(names) && len(names[offset]) > 0 { 64 name = names[offset] 65 } 66 files = append(files, os.NewFile(uintptr(fd), name)) 67 } 68 69 return files 70 } 71