@@ -201,6 +201,36 @@ def _have_socket_hyperv():
201201        s .close ()
202202    return  True 
203203
204+ def  _query_available_service (expected_protocols , services_file  =  '/etc/services' ):
205+     if  not  os .path .exists (services_file ):
206+         return  None 
207+     services_found  =  dict ()
208+     with  open (services_file , 'r' ) as  f :
209+         for  line  in  f :
210+             line  =  line .strip ()
211+             if  line .startswith ('#' ):
212+                 # Skip comment line. 
213+                 continue 
214+             tokens  =  line .split ()
215+             if  len (tokens ) <  2 :
216+                 continue 
217+             if  '/'  not  in tokens [1 ]:
218+                 continue 
219+             try :
220+                 _ , entry_protocol  =  tokens [1 ].split ('/' )
221+             except :
222+                 continue 
223+             entry_name  =  tokens [0 ]
224+             if  entry_name  not  in services_found :
225+                 services_found [entry_name ] =  [entry_protocol ]
226+             else :
227+                 services_found [entry_name ].append (entry_protocol )
228+             for  protocol  in  expected_protocols :
229+                 if  protocol  not  in services_found [entry_name ]:
230+                     break 
231+             else :
232+                 return  entry_name 
233+     return  None 
204234
205235@contextlib .contextmanager  
206236def  socket_setdefaulttimeout (timeout ):
@@ -1259,38 +1289,6 @@ def testGetServBy(self):
12591289        # Find one service that exists, then check all the related interfaces. 
12601290        # I've ordered this by protocols that have both a tcp and udp 
12611291        # protocol, at least for modern Linuxes. 
1262-         def  query_available_service (* protocols ):
1263-             services_file  =  '/etc/services' 
1264-             if  not  os .path .exists (services_file ):
1265-                 return  None 
1266-             services_found  =  dict ()
1267-             with  open (services_file , 'r' ) as  f :
1268-                 for  line  in  f :
1269-                     line  =  line .strip ()
1270-                     if  line .startswith ('#' ):
1271-                         # Skip comment line. 
1272-                         continue 
1273-                     tokens  =  line .split ()
1274-                     if  len (tokens ) <  2 :
1275-                         continue 
1276-                     if  '/'  not  in tokens [1 ]:
1277-                         continue 
1278-                     try :
1279-                         _ , entry_protocol  =  tokens [1 ].split ('/' )
1280-                     except :
1281-                         continue 
1282-                     entry_name  =  tokens [0 ]
1283-                     if  entry_name  not  in services_found :
1284-                         services_found [entry_name ] =  [entry_protocol ]
1285-                     else :
1286-                         services_found [entry_name ].append (entry_protocol )
1287-                     for  protocol  in  protocols :
1288-                         if  protocol  not  in services_found [entry_name ]:
1289-                             break 
1290-                     else :
1291-                         return  entry_name 
1292-             return  None 
1293- 
12941292        if  (
12951293            sys .platform .startswith (
12961294                ('linux' , 'android' , 'freebsd' , 'netbsd' , 'gnukfreebsd' ))
@@ -1308,7 +1306,7 @@ def query_available_service(*protocols):
13081306            except  OSError :
13091307                pass 
13101308        else :
1311-             service  =  query_available_service ( 'tcp' )
1309+             service  =  _query_available_service (( 'tcp' ) )
13121310            if  service  is  None :
13131311                self .skipTest ('No available service found.' )
13141312            port  =  socket .getservbyname (service , 'tcp' )
0 commit comments