@@ -24,8 +24,8 @@ def __init__(self, address, conf, log, fd=None):
2424 sock = socket .socket (self .FAMILY , socket .SOCK_STREAM )
2525 bound = False
2626 else :
27- sock = socket . fromfd ( fd , self . FAMILY , socket . SOCK_STREAM )
28- os . close ( fd )
27+ # does not duplicate the fd, this LISTEN_FDS stays at fds 3+N
28+ sock = socket . socket ( self . FAMILY , socket . SOCK_STREAM , fileno = fd )
2929 bound = True
3030
3131 self .sock = self .set_options (sock , bound = bound )
@@ -156,6 +156,12 @@ def create_sockets(conf, log, fds=None):
156156 fdaddr += list (fds )
157157 laddr = [bind for bind in addr if not isinstance (bind , int )]
158158
159+ # LISTEN_FDS=1 + fd://3
160+ uniq_fdaddr = set ()
161+ duped_fdaddr = {fd for fd in fdaddr if fd in uniq_fdaddr or uniq_fdaddr .add (fd )}
162+ if duped_fdaddr :
163+ log .warning ("Binding with fd:// is unsupported with systemd/re-exec." )
164+
159165 # check ssl config early to raise the error on startup
160166 # only the certfile is needed since it can contains the keyfile
161167 if conf .certfile and not os .path .exists (conf .certfile ):
@@ -167,9 +173,11 @@ def create_sockets(conf, log, fds=None):
167173 # sockets are already bound
168174 if fdaddr :
169175 for fd in fdaddr :
170- sock = socket .fromfd ( fd , socket .AF_UNIX , socket .SOCK_STREAM )
176+ sock = socket .socket ( socket .AF_UNIX , socket .SOCK_STREAM , fileno = fd )
171177 sock_name = sock .getsockname ()
172178 sock_type = _sock_type (sock_name )
179+ log .debug ("listen: fd %d => fd %d for %s" , fd , sock .fileno (), sock_name )
180+ sock .detach () # only created to call getsockname(), will re-attach shorty
173181 listener = sock_type (sock_name , conf , log , fd = fd )
174182 listeners .append (listener )
175183
0 commit comments