gitee.com/mysnapcore/mysnapd@v0.1.0/netutil/activation.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2015-2019 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package netutil 21 22 import ( 23 "fmt" 24 "net" 25 "os" 26 "runtime" 27 unix "syscall" 28 29 "github.com/coreos/go-systemd/activation" 30 31 "gitee.com/mysnapcore/mysnapd/logger" 32 ) 33 34 // GetListener tries to get a listener for the given socket path from 35 // the listener map, and if it fails it tries to set it up directly. 36 func GetListener(socketPath string, listenerMap map[string]net.Listener) (net.Listener, error) { 37 if listener, ok := listenerMap[socketPath]; ok { 38 return listener, nil 39 } 40 41 if c, err := net.Dial("unix", socketPath); err == nil { 42 c.Close() 43 return nil, fmt.Errorf("socket %q already in use", socketPath) 44 } 45 46 if err := os.Remove(socketPath); err != nil && !os.IsNotExist(err) { 47 return nil, err 48 } 49 50 address, err := net.ResolveUnixAddr("unix", socketPath) 51 if err != nil { 52 return nil, err 53 } 54 55 runtime.LockOSThread() 56 oldmask := unix.Umask(0111) 57 listener, err := net.ListenUnix("unix", address) 58 unix.Umask(oldmask) 59 runtime.UnlockOSThread() 60 if err != nil { 61 return nil, err 62 } 63 64 logger.Debugf("socket %q was not activated; listening", socketPath) 65 66 return listener, nil 67 } 68 69 // ActivationListeners builds a map of addresses to listeners that were passed 70 // during systemd activation 71 func ActivationListeners() (lns map[string]net.Listener, err error) { 72 // pass false to keep LISTEN_* environment variables passed by systemd 73 files := activation.Files(false) 74 lns = make(map[string]net.Listener, len(files)) 75 76 for _, f := range files { 77 ln, err := net.FileListener(f) 78 if err != nil { 79 return nil, err 80 } 81 addr := ln.Addr().String() 82 lns[addr] = ln 83 } 84 return lns, nil 85 }