zeroc-ice 3.8.2 → 3.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. checksums.yaml +4 -4
  2. data/dist/IceRuby/Communicator.cpp +26 -9
  3. data/dist/IceRuby/Config.h +0 -12
  4. data/dist/IceRuby/Connection.cpp +18 -9
  5. data/dist/IceRuby/DefaultSliceLoader.h +1 -1
  6. data/dist/IceRuby/Endpoint.cpp +21 -8
  7. data/dist/IceRuby/Operation.cpp +7 -5
  8. data/dist/IceRuby/Properties.cpp +3 -4
  9. data/dist/IceRuby/Proxy.cpp +11 -19
  10. data/dist/IceRuby/RubySliceLoader.cpp +1 -1
  11. data/dist/IceRuby/RubySliceLoader.h +6 -0
  12. data/dist/IceRuby/Types.cpp +162 -138
  13. data/dist/IceRuby/Types.h +68 -28
  14. data/dist/IceRuby/Util.cpp +14 -78
  15. data/dist/IceRuby/Util.h +7 -17
  16. data/dist/ice/cpp/include/Ice/Communicator.h +31 -8
  17. data/dist/ice/cpp/include/Ice/Config.h +2 -2
  18. data/dist/ice/cpp/include/Ice/Connection.h +24 -8
  19. data/dist/ice/cpp/include/Ice/CtrlCHandler.h +1 -1
  20. data/dist/ice/cpp/include/Ice/Demangle.h +1 -1
  21. data/dist/ice/cpp/include/Ice/Endpoint.h +4 -4
  22. data/dist/ice/cpp/include/Ice/Initialize.h +4 -4
  23. data/dist/ice/cpp/include/Ice/InputStream.h +5 -5
  24. data/dist/ice/cpp/include/Ice/Instrumentation.h +13 -7
  25. data/dist/ice/cpp/include/Ice/LocalExceptions.h +5 -5
  26. data/dist/ice/cpp/include/Ice/Logger.h +7 -0
  27. data/dist/ice/cpp/include/Ice/LoggerUtil.h +1 -1
  28. data/dist/ice/cpp/include/Ice/Object.h +10 -8
  29. data/dist/ice/cpp/include/Ice/ObjectAdapter.h +1 -1
  30. data/dist/ice/cpp/include/Ice/OutgoingAsync.h +5 -2
  31. data/dist/ice/cpp/include/Ice/OutgoingResponse.h +2 -1
  32. data/dist/ice/cpp/include/Ice/OutputStream.h +7 -6
  33. data/dist/ice/cpp/include/Ice/PluginFactory.h +1 -1
  34. data/dist/ice/cpp/include/Ice/Properties.h +3 -3
  35. data/dist/ice/cpp/include/Ice/Proxy.h +192 -50
  36. data/dist/ice/cpp/include/Ice/SSL/ClientAuthenticationOptions.h +3 -3
  37. data/dist/ice/cpp/include/Ice/SSL/EndpointInfo.h +1 -1
  38. data/dist/ice/cpp/include/Ice/SSL/ServerAuthenticationOptions.h +5 -5
  39. data/dist/ice/cpp/include/Ice/ServantLocator.h +1 -1
  40. data/dist/ice/cpp/include/Ice/Service.h +2 -5
  41. data/dist/ice/cpp/include/Ice/SliceLoader.h +1 -1
  42. data/dist/ice/cpp/include/Ice/SlicedData.h +5 -3
  43. data/dist/ice/cpp/include/Ice/StreamHelpers.h +1 -1
  44. data/dist/ice/cpp/include/Ice/StreamableTraits.h +2 -2
  45. data/dist/ice/cpp/include/Ice/StringConverter.h +2 -3
  46. data/dist/ice/cpp/include/Ice/StringUtil.h +2 -7
  47. data/dist/ice/cpp/include/Ice/UUID.h +1 -0
  48. data/dist/ice/cpp/include/Ice/Value.h +2 -2
  49. data/dist/ice/cpp/include/generated/Ice/BuiltinSequences.h +2 -2
  50. data/dist/ice/cpp/include/generated/Ice/Context.h +2 -2
  51. data/dist/ice/cpp/include/generated/Ice/EndpointTypes.h +2 -2
  52. data/dist/ice/cpp/include/generated/Ice/Identity.h +2 -2
  53. data/dist/ice/cpp/include/generated/Ice/Locator.h +50 -14
  54. data/dist/ice/cpp/include/generated/Ice/LocatorRegistry.h +38 -11
  55. data/dist/ice/cpp/include/generated/Ice/Metrics.h +94 -39
  56. data/dist/ice/cpp/include/generated/Ice/OperationMode.h +2 -2
  57. data/dist/ice/cpp/include/generated/Ice/Process.h +34 -8
  58. data/dist/ice/cpp/include/generated/Ice/PropertiesAdmin.h +42 -11
  59. data/dist/ice/cpp/include/generated/Ice/PropertyDict.h +2 -2
  60. data/dist/ice/cpp/include/generated/Ice/RemoteLogger.h +93 -40
  61. data/dist/ice/cpp/include/generated/Ice/ReplyStatus.h +2 -2
  62. data/dist/ice/cpp/include/generated/Ice/Router.h +50 -14
  63. data/dist/ice/cpp/include/generated/Ice/SliceChecksumDict.h +2 -2
  64. data/dist/ice/cpp/include/generated/Ice/Version.h +2 -2
  65. data/dist/ice/cpp/include/generated/IceDiscovery/Lookup.h +66 -14
  66. data/dist/ice/cpp/include/generated/IceLocatorDiscovery/Lookup.h +34 -8
  67. data/dist/ice/cpp/src/Ice/AddDefaultPluginFactories_all.cpp +1 -1
  68. data/dist/ice/cpp/src/Ice/Base64.cpp +47 -137
  69. data/dist/ice/cpp/src/Ice/Base64.h +2 -2
  70. data/dist/ice/cpp/src/Ice/BatchRequestQueue.cpp +28 -13
  71. data/dist/ice/cpp/src/Ice/BatchRequestQueue.h +5 -1
  72. data/dist/ice/cpp/src/Ice/Buffer.cpp +1 -1
  73. data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.cpp +1 -1
  74. data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.h +1 -1
  75. data/dist/ice/cpp/src/Ice/Communicator.cpp +4 -3
  76. data/dist/ice/cpp/src/Ice/CommunicatorFlushBatchAsync.cpp +8 -0
  77. data/dist/ice/cpp/src/Ice/ConnectRequestHandler.cpp +5 -15
  78. data/dist/ice/cpp/src/Ice/ConnectRequestHandler.h +1 -1
  79. data/dist/ice/cpp/src/Ice/ConnectionFactory.cpp +6 -8
  80. data/dist/ice/cpp/src/Ice/ConnectionFactory.h +0 -3
  81. data/dist/ice/cpp/src/Ice/ConnectionI.cpp +94 -99
  82. data/dist/ice/cpp/src/Ice/ConnectionI.h +11 -8
  83. data/dist/ice/cpp/src/Ice/ConsoleUtil.cpp +1 -1
  84. data/dist/ice/cpp/src/Ice/DefaultsAndOverrides.cpp +10 -14
  85. data/dist/ice/cpp/src/Ice/EndpointI.h +1 -1
  86. data/dist/ice/cpp/src/Ice/FileUtil.cpp +12 -12
  87. data/dist/ice/cpp/src/Ice/FixedRequestHandler.cpp +1 -1
  88. data/dist/ice/cpp/src/Ice/FixedRequestHandler.h +1 -1
  89. data/dist/ice/cpp/src/Ice/HttpParser.h +0 -2
  90. data/dist/ice/cpp/src/Ice/IdleTimeoutTransceiverDecorator.cpp +6 -3
  91. data/dist/ice/cpp/src/Ice/IncomingRequest.cpp +1 -3
  92. data/dist/ice/cpp/src/Ice/InputStream.cpp +23 -19
  93. data/dist/ice/cpp/src/Ice/Instance.cpp +73 -50
  94. data/dist/ice/cpp/src/Ice/Instance.h +1 -6
  95. data/dist/ice/cpp/src/Ice/LocalExceptions.cpp +1 -1
  96. data/dist/ice/cpp/src/Ice/LocatorInfo.cpp +2 -2
  97. data/dist/ice/cpp/src/Ice/LoggerAdminI.cpp +13 -18
  98. data/dist/ice/cpp/src/Ice/LoggerI.cpp +1 -1
  99. data/dist/ice/cpp/src/Ice/LoggerI.h +2 -2
  100. data/dist/ice/cpp/src/Ice/MetricsAdminI.h +6 -1
  101. data/dist/ice/cpp/src/Ice/MetricsObserverI.h +22 -18
  102. data/dist/ice/cpp/src/Ice/NativePropertiesAdmin.cpp +5 -2
  103. data/dist/ice/cpp/src/Ice/Network.cpp +168 -103
  104. data/dist/ice/cpp/src/Ice/Network.h +12 -7
  105. data/dist/ice/cpp/src/Ice/NetworkProxy.cpp +17 -6
  106. data/dist/ice/cpp/src/Ice/NetworkProxy.h +2 -1
  107. data/dist/ice/cpp/src/Ice/Object.cpp +1 -1
  108. data/dist/ice/cpp/src/Ice/ObjectAdapterI.cpp +56 -19
  109. data/dist/ice/cpp/src/Ice/OpaqueEndpointI.cpp +10 -10
  110. data/dist/ice/cpp/src/Ice/Options.cpp +7 -2
  111. data/dist/ice/cpp/src/Ice/OutgoingAsync.cpp +1 -1
  112. data/dist/ice/cpp/src/Ice/OutputStream.cpp +4 -4
  113. data/dist/ice/cpp/src/Ice/PluginManagerI.cpp +7 -1
  114. data/dist/ice/cpp/src/Ice/Properties.cpp +26 -16
  115. data/dist/ice/cpp/src/Ice/PropertyUtil.cpp +1 -1
  116. data/dist/ice/cpp/src/Ice/ProtocolInstance.cpp +0 -11
  117. data/dist/ice/cpp/src/Ice/ProtocolInstance.h +1 -2
  118. data/dist/ice/cpp/src/Ice/Proxy.cpp +9 -1
  119. data/dist/ice/cpp/src/Ice/ProxyAsync.cpp +110 -13
  120. data/dist/ice/cpp/src/Ice/Random.cpp +68 -7
  121. data/dist/ice/cpp/src/Ice/Random.h +6 -2
  122. data/dist/ice/cpp/src/Ice/Reference.cpp +22 -11
  123. data/dist/ice/cpp/src/Ice/Reference.h +3 -0
  124. data/dist/ice/cpp/src/Ice/ReferenceFactory.cpp +10 -0
  125. data/dist/ice/cpp/src/Ice/RequestHandler.h +3 -1
  126. data/dist/ice/cpp/src/Ice/RequestHandlerCache.cpp +1 -1
  127. data/dist/ice/cpp/src/Ice/RequestHandlerCache.h +1 -1
  128. data/dist/ice/cpp/src/Ice/ResourceConfig.h +3 -3
  129. data/dist/ice/cpp/src/Ice/RetryQueue.cpp +8 -12
  130. data/dist/ice/cpp/src/Ice/SHA1.cpp +11 -11
  131. data/dist/ice/cpp/src/Ice/SSL/DistinguishedName.cpp +0 -6
  132. data/dist/ice/cpp/src/Ice/SSL/DistinguishedName.h +0 -6
  133. data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.cpp +15 -1
  134. data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.cpp +77 -27
  135. data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.h +2 -1
  136. data/dist/ice/cpp/src/Ice/SSL/RFC2253.cpp +2 -2
  137. data/dist/ice/cpp/src/Ice/SSL/SSLUtil.cpp +39 -34
  138. data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.cpp +130 -52
  139. data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.cpp +64 -33
  140. data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.h +0 -1
  141. data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.cpp +3 -3
  142. data/dist/ice/cpp/src/Ice/SSL/SecureTransportTransceiverI.cpp +9 -3
  143. data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.cpp +73 -51
  144. data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.h +0 -8
  145. data/dist/ice/cpp/src/Ice/Selector.cpp +13 -11
  146. data/dist/ice/cpp/src/Ice/ServantManager.cpp +3 -3
  147. data/dist/ice/cpp/src/Ice/Service.cpp +33 -115
  148. data/dist/ice/cpp/src/Ice/StreamSocket.cpp +33 -40
  149. data/dist/ice/cpp/src/Ice/StreamSocket.h +4 -4
  150. data/dist/ice/cpp/src/Ice/StringConverter.cpp +1 -1
  151. data/dist/ice/cpp/src/Ice/StringUtil.cpp +12 -21
  152. data/dist/ice/cpp/src/Ice/SysLoggerI.cpp +136 -100
  153. data/dist/ice/cpp/src/Ice/SysLoggerI.h +7 -3
  154. data/dist/ice/cpp/src/Ice/SystemdJournalI.cpp +1 -1
  155. data/dist/ice/cpp/src/Ice/TcpAcceptor.cpp +7 -7
  156. data/dist/ice/cpp/src/Ice/TcpAcceptor.h +2 -1
  157. data/dist/ice/cpp/src/Ice/TcpBufSize.h +40 -0
  158. data/dist/ice/cpp/src/Ice/TcpConnector.cpp +5 -2
  159. data/dist/ice/cpp/src/Ice/TcpConnector.h +2 -0
  160. data/dist/ice/cpp/src/Ice/TcpTransceiver.cpp +6 -2
  161. data/dist/ice/cpp/src/Ice/ThreadPool.cpp +2 -8
  162. data/dist/ice/cpp/src/Ice/ThreadPool.h +0 -2
  163. data/dist/ice/cpp/src/Ice/Timer.cpp +7 -3
  164. data/dist/ice/cpp/src/Ice/UUID.cpp +1 -2
  165. data/dist/ice/cpp/src/Ice/UdpEndpointI.cpp +4 -1
  166. data/dist/ice/cpp/src/Ice/UdpTransceiver.cpp +136 -123
  167. data/dist/ice/cpp/src/Ice/UdpTransceiver.h +3 -4
  168. data/dist/ice/cpp/src/Ice/WSTransceiver.cpp +96 -27
  169. data/dist/ice/cpp/src/Ice/WSTransceiver.h +1 -1
  170. data/dist/ice/cpp/src/Ice/generated/BuiltinSequences.cpp +2 -2
  171. data/dist/ice/cpp/src/Ice/generated/Context.cpp +2 -2
  172. data/dist/ice/cpp/src/Ice/generated/EndpointTypes.cpp +2 -2
  173. data/dist/ice/cpp/src/Ice/generated/Identity.cpp +2 -2
  174. data/dist/ice/cpp/src/Ice/generated/Locator.cpp +2 -2
  175. data/dist/ice/cpp/src/Ice/generated/LocatorRegistry.cpp +2 -2
  176. data/dist/ice/cpp/src/Ice/generated/Metrics.cpp +2 -2
  177. data/dist/ice/cpp/src/Ice/generated/OperationMode.cpp +2 -2
  178. data/dist/ice/cpp/src/Ice/generated/Process.cpp +2 -2
  179. data/dist/ice/cpp/src/Ice/generated/PropertiesAdmin.cpp +2 -2
  180. data/dist/ice/cpp/src/Ice/generated/PropertyDict.cpp +2 -2
  181. data/dist/ice/cpp/src/Ice/generated/RemoteLogger.cpp +2 -2
  182. data/dist/ice/cpp/src/Ice/generated/ReplyStatus.cpp +2 -2
  183. data/dist/ice/cpp/src/Ice/generated/Router.cpp +2 -2
  184. data/dist/ice/cpp/src/Ice/generated/SliceChecksumDict.cpp +2 -2
  185. data/dist/ice/cpp/src/Ice/generated/Version.cpp +2 -2
  186. data/dist/ice/cpp/src/IceDiscovery/LookupI.cpp +47 -9
  187. data/dist/ice/cpp/src/IceDiscovery/LookupI.h +8 -3
  188. data/dist/ice/cpp/src/IceDiscovery/generated/Lookup.cpp +2 -2
  189. data/dist/ice/cpp/src/IceLocatorDiscovery/PluginI.cpp +43 -14
  190. data/dist/ice/cpp/src/IceLocatorDiscovery/generated/Lookup.cpp +2 -2
  191. data/dist/ice/cpp/src/Slice/DocCommentParser.cpp +26 -20
  192. data/dist/ice/cpp/src/Slice/DocCommentParser.h +2 -2
  193. data/dist/ice/cpp/src/Slice/FileTracker.cpp +3 -11
  194. data/dist/ice/cpp/src/Slice/FileTracker.h +0 -2
  195. data/dist/ice/cpp/src/Slice/Grammar.cpp +211 -210
  196. data/dist/ice/cpp/src/Slice/MetadataValidation.cpp +10 -9
  197. data/dist/ice/cpp/src/Slice/Parser.cpp +28 -20
  198. data/dist/ice/cpp/src/Slice/Parser.h +3 -4
  199. data/dist/ice/cpp/src/Slice/Preprocessor.cpp +3 -11
  200. data/dist/ice/cpp/src/Slice/Preprocessor.h +0 -2
  201. data/dist/ice/cpp/src/Slice/Scanner.cpp +3 -3
  202. data/dist/ice/cpp/src/Slice/SliceUtil.cpp +197 -114
  203. data/dist/ice/cpp/src/Slice/StringLiteralUtil.cpp +0 -2
  204. data/dist/ice/cpp/src/Slice/Util.h +21 -9
  205. data/dist/ice/cpp/src/slice2rb/Ruby.cpp +7 -3
  206. data/dist/ice/cpp/src/slice2rb/RubyUtil.cpp +16 -12
  207. data/dist/ice/cpp/src/slice2rb/RubyUtil.h +3 -3
  208. data/dist/ice/slice/Glacier2/Router.ice +3 -3
  209. data/dist/ice/slice/Ice/Metrics.ice +6 -5
  210. data/dist/ice/slice/Ice/RemoteLogger.ice +5 -5
  211. data/dist/ice/slice/IceGrid/Admin.ice +9 -9
  212. data/dist/ice/slice/IceGrid/Descriptor.ice +5 -5
  213. data/dist/ice/slice/IceStorm/Metrics.ice +1 -1
  214. data/dist/lib/Glacier2/Metrics.rb +1 -1
  215. data/dist/lib/Glacier2/PermissionsVerifier.rb +1 -1
  216. data/dist/lib/Glacier2/Router.rb +2 -2
  217. data/dist/lib/Glacier2/SSLInfo.rb +1 -1
  218. data/dist/lib/Glacier2/Session.rb +1 -1
  219. data/dist/lib/Ice/BuiltinSequences.rb +1 -1
  220. data/dist/lib/Ice/CompressBatch.rb +1 -2
  221. data/dist/lib/Ice/Context.rb +1 -1
  222. data/dist/lib/Ice/EndpointSelectionType.rb +1 -2
  223. data/dist/lib/Ice/EndpointTypes.rb +1 -1
  224. data/dist/lib/Ice/Identity.rb +1 -1
  225. data/dist/lib/Ice/IdentitySpaceship.rb +1 -0
  226. data/dist/lib/Ice/Locator.rb +1 -1
  227. data/dist/lib/Ice/LocatorRegistry.rb +1 -1
  228. data/dist/lib/Ice/Metrics.rb +1 -1
  229. data/dist/lib/Ice/OperationMode.rb +2 -3
  230. data/dist/lib/Ice/Process.rb +1 -1
  231. data/dist/lib/Ice/PropertiesAdmin.rb +1 -1
  232. data/dist/lib/Ice/PropertyDict.rb +1 -1
  233. data/dist/lib/Ice/RemoteLogger.rb +2 -3
  234. data/dist/lib/Ice/ReplyStatus.rb +2 -3
  235. data/dist/lib/Ice/Router.rb +1 -1
  236. data/dist/lib/Ice/SliceChecksumDict.rb +1 -1
  237. data/dist/lib/Ice/SliceUtil.rb +2 -2
  238. data/dist/lib/Ice/Struct.rb +1 -0
  239. data/dist/lib/Ice/ToStringMode.rb +1 -2
  240. data/dist/lib/Ice/Value.rb +2 -2
  241. data/dist/lib/Ice/Version.rb +1 -1
  242. data/dist/lib/IceBox/ServiceManager.rb +1 -1
  243. data/dist/lib/IceGrid/Admin.rb +3 -4
  244. data/dist/lib/IceGrid/Descriptor.rb +1 -1
  245. data/dist/lib/IceGrid/Exception.rb +1 -1
  246. data/dist/lib/IceGrid/FileParser.rb +1 -1
  247. data/dist/lib/IceGrid/Registry.rb +2 -3
  248. data/dist/lib/IceGrid/Session.rb +2 -2
  249. data/dist/lib/IceGrid/UserAccountMapper.rb +1 -1
  250. data/dist/lib/IceStorm/IceStorm.rb +1 -1
  251. data/dist/lib/IceStorm/Metrics.rb +1 -1
  252. data/extconf.rb +1 -1
  253. data/ice.gemspec +3 -3
  254. metadata +4 -5
  255. data/dist/ice/cpp/src/Ice/DLLMain.cpp +0 -40
  256. data/dist/ice/cpp/src/Ice/UndefSysMacros.h +0 -37
@@ -206,25 +206,6 @@ Ice::SSL::SecureTransport::sslErrorToString(OSStatus status)
206
206
  }
207
207
 
208
208
  #if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
209
- CFDictionaryRef
210
- Ice::SSL::SecureTransport::getCertificateProperty(SecCertificateRef cert, CFTypeRef key)
211
- {
212
- UniqueRef<CFDictionaryRef> property;
213
- UniqueRef<CFArrayRef> keys(CFArrayCreate(nullptr, &key, 1, &kCFTypeArrayCallBacks));
214
- UniqueRef<CFErrorRef> err;
215
- UniqueRef<CFDictionaryRef> values(SecCertificateCopyValues(cert, keys.get(), &err.get()));
216
- if (err)
217
- {
218
- ostringstream os;
219
- os << "SSL transport: error getting property for certificate:\n" << sslErrorToString(err);
220
- throw CertificateReadException(__FILE__, __LINE__, os.str());
221
- }
222
-
223
- assert(values);
224
- property.retain(static_cast<CFDictionaryRef>(CFDictionaryGetValue(values.get(), key)));
225
- return property.release();
226
- }
227
-
228
209
  namespace
229
210
  {
230
211
  //
@@ -264,12 +245,10 @@ namespace
264
245
  memset(&params, 0, sizeof(params));
265
246
  params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
266
247
  params.flags |= kSecKeyNoAccessControl;
267
- UniqueRef<CFStringRef> passphraseHolder;
268
- if (!passphrase.empty())
269
- {
270
- passphraseHolder.reset(toCFString(passphrase));
271
- params.passphrase = passphraseHolder.get();
272
- }
248
+ // Always pass a passphrase, even an empty one: SecItemImport rejects a PKCS12 file with
249
+ // errSecPassphraseRequired when params.passphrase is null, without looking at the file contents.
250
+ UniqueRef<CFStringRef> passphraseHolder(toCFString(passphrase));
251
+ params.passphrase = passphraseHolder.get();
273
252
 
274
253
  UniqueRef<CFArrayRef> items;
275
254
  SecExternalItemType importType = type;
@@ -277,6 +256,26 @@ namespace
277
256
  UniqueRef<CFStringRef> path(toCFString(file));
278
257
  OSStatus err = SecItemImport(data.get(), path.get(), &format, &importType, 0, &params, keychain, &items.get());
279
258
 
259
+ if (err == errSecPkcs12VerifyFailure && passphrase.empty())
260
+ {
261
+ // There are two encodings of the empty PKCS12 password, and they derive different keys. RFC 7292
262
+ // appendix B.1 formats every password as a NULL-terminated UTF-16BE string, which makes the empty
263
+ // password two 0x00 bytes; appendix B.2 step 3 instead notes that an empty password gives an empty
264
+ // block. openssl and keytool write the first, .NET writes either one depending on whether the
265
+ // password is "" or null.
266
+ //
267
+ // SecItemImport reads a CFString passphrase as the second encoding and a CFData passphrase as the
268
+ // raw password bytes, so retry with the two bytes appendix B.1 asks for. This mirrors .NET's own
269
+ // PKCS12 reader, which retries the other encoding when MAC verification fails.
270
+ const uint8_t emptyPassword[2] = {0, 0};
271
+ UniqueRef<CFDataRef> dataPassphrase(
272
+ CFDataCreate(kCFAllocatorDefault, emptyPassword, sizeof(emptyPassword)));
273
+ params.passphrase = dataPassphrase.get();
274
+ importType = type;
275
+ format = type == kSecItemTypeUnknown ? kSecFormatPKCS12 : kSecFormatUnknown;
276
+ err = SecItemImport(data.get(), path.get(), &format, &importType, 0, &params, keychain, &items.get());
277
+ }
278
+
280
279
  if (err != noErr)
281
280
  {
282
281
  ostringstream os;
@@ -421,6 +420,20 @@ namespace
421
420
  }
422
421
  }
423
422
 
423
+ // A certificate must expose a Subject Key Identifier to be imported into the keychain: the SKI is used
424
+ // both to locate an already-imported certificate (the query below) and as the key label that pairs the
425
+ // private key with the certificate (further down). Reject a certificate without one with a clear error
426
+ // instead of passing a null value to CFDictionarySetValue, which aborts the process. Certificates without
427
+ // a Subject Key Identifier are uncommon in practice, so rejecting them is acceptable.
428
+ if (!hash)
429
+ {
430
+ throw CertificateReadException(
431
+ __FILE__,
432
+ __LINE__,
433
+ "SSL transport: the certificate for key file '" + file +
434
+ "' has no Subject Key Identifier extension and cannot be imported into the macOS keychain");
435
+ }
436
+
424
437
  const void* values[] = {keychain};
425
438
  UniqueRef<CFArrayRef> searchList(CFArrayCreate(kCFAllocatorDefault, values, 1, &kCFTypeArrayCallBacks));
426
439
 
@@ -510,8 +523,8 @@ namespace
510
523
  // kSecKeyLabel attribute should match the subject key identifier.
511
524
  //
512
525
  vector<SecKeychainAttribute> attributes;
513
- if (hash)
514
526
  {
527
+ // hash is guaranteed non-null here: loadPrivateKey rejects certificates without a Subject Key Identifier.
515
528
  SecKeychainAttribute attr;
516
529
  attr.tag = kSecKeyLabel;
517
530
  attr.data = const_cast<UInt8*>(CFDataGetBytePtr(hash.get()));
@@ -536,7 +549,7 @@ namespace
536
549
  }
537
550
 
538
551
  SecKeychainAttributeList attrs;
539
- attrs.attr = &attributes[0];
552
+ attrs.attr = attributes.data();
540
553
  attrs.count = static_cast<UInt32>(attributes.size());
541
554
  SecKeychainItemModifyAttributesAndData(reinterpret_cast<SecKeychainItemRef>(key.get()), &attrs, 0, nullptr);
542
555
 
@@ -594,10 +607,21 @@ namespace
594
607
  break;
595
608
  }
596
609
 
597
- vector<byte> data(IceInternal::Base64::decode(string(&buffer[startpos], size)));
610
+ vector<std::byte> data;
611
+ try
612
+ {
613
+ data = IceInternal::Base64::decode(string(&buffer[startpos], size));
614
+ }
615
+ catch (const std::invalid_argument&)
616
+ {
617
+ throw InitializationException(
618
+ __FILE__,
619
+ __LINE__,
620
+ "SSL transport: certificate " + file + " is not a valid PEM-encoded certificate");
621
+ }
598
622
  UniqueRef<CFDataRef> certdata(CFDataCreate(
599
623
  kCFAllocatorDefault,
600
- reinterpret_cast<uint8_t*>(&data[0]),
624
+ reinterpret_cast<uint8_t*>(data.data()),
601
625
  static_cast<CFIndex>(data.size())));
602
626
  UniqueRef<SecCertificateRef> cert(SecCertificateCreateWithData(0, certdata.get()));
603
627
  if (!cert)
@@ -681,7 +705,7 @@ Ice::SSL::SecureTransport::loadCertificateChain(
681
705
  if (!chain)
682
706
  {
683
707
  ostringstream os;
684
- os << "SSL transport: couldn't find identity in file " << file;
708
+ os << "SSL transport: could not find identity in file " << file;
685
709
  throw InitializationException(__FILE__, __LINE__, os.str());
686
710
  }
687
711
  #else
@@ -698,7 +722,7 @@ Ice::SSL::SecureTransport::loadCertificateChain(
698
722
  if (SecCertificateGetTypeID() != CFGetTypeID(cert))
699
723
  {
700
724
  ostringstream os;
701
- os << "SSL transport: couldn't find certificate in '" << file << "'";
725
+ os << "SSL transport: could not find certificate in '" << file << "'";
702
726
  throw CertificateReadException(__FILE__, __LINE__, os.str());
703
727
  }
704
728
 
@@ -715,21 +739,6 @@ Ice::SSL::SecureTransport::loadCertificateChain(
715
739
  return chain.release();
716
740
  }
717
741
 
718
- SecCertificateRef
719
- Ice::SSL::SecureTransport::loadCertificate(const string& file)
720
- {
721
- UniqueRef<SecCertificateRef> cert;
722
- #if defined(ICE_USE_SECURE_TRANSPORT_IOS)
723
- UniqueRef<CFArrayRef> certs(loadCerts(file));
724
- assert(CFArrayGetCount(certs.get()) > 0);
725
- cert.retain((SecCertificateRef)CFArrayGetValueAtIndex(certs.get(), 0));
726
- #else
727
- UniqueRef<CFArrayRef> items(loadKeychainItems(file, kSecItemTypeCertificate, nullptr, ""));
728
- cert.retain((SecCertificateRef)CFArrayGetValueAtIndex(items.get(), 0));
729
- #endif
730
- return cert.release();
731
- }
732
-
733
742
  CFArrayRef
734
743
  Ice::SSL::SecureTransport::loadCACertificates(const string& file)
735
744
  {
@@ -857,7 +866,8 @@ Ice::SSL::SecureTransport::findCertificateChain(
857
866
  {
858
867
  throw InitializationException(__FILE__, __LINE__, "SSL transport: invalid value '" + value + "'");
859
868
  }
860
- UniqueRef<CFDataRef> v(CFDataCreate(kCFAllocatorDefault, &buffer[0], static_cast<CFIndex>(buffer.size())));
869
+ UniqueRef<CFDataRef> v(
870
+ CFDataCreate(kCFAllocatorDefault, buffer.data(), static_cast<CFIndex>(buffer.size())));
861
871
  CFDictionarySetValue(
862
872
  query.get(),
863
873
  field == "SUBJECTKEYID" ? kSecAttrSubjectKeyID : kSecAttrSerialNumber,
@@ -932,16 +942,28 @@ Ice::SSL::SecureTransport::findCertificateChain(
932
942
  if (err != noErr)
933
943
  {
934
944
  ostringstream os;
935
- os << "SSL transport: couldn't create identity for certificate found in the keychain:\n"
945
+ os << "SSL transport: could not create identity for certificate found in the keychain:\n"
936
946
  << sslErrorToString(err);
937
947
  throw InitializationException(__FILE__, __LINE__, os.str());
938
948
  }
939
949
 
940
- // Now lookup the identity with the label
950
+ // Now lookup the identity with the label. We match the identity by the certificate's label, so the
951
+ // certificate must have one; reject it with a clear error rather than passing a null value to
952
+ // CFDictionarySetValue (which aborts the process).
953
+ const void* label = CFDictionaryGetValue(attributes.get(), kSecAttrLabel);
954
+ if (label == nullptr)
955
+ {
956
+ throw InitializationException(
957
+ __FILE__,
958
+ __LINE__,
959
+ "SSL transport: could not create identity for certificate found in the keychain: the certificate has no "
960
+ "label attribute");
961
+ }
962
+
941
963
  query.reset(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
942
964
  CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne);
943
965
  CFDictionarySetValue(query.get(), kSecClass, kSecClassIdentity);
944
- CFDictionarySetValue(query.get(), kSecAttrLabel, (CFDataRef)CFDictionaryGetValue(attributes.get(), kSecAttrLabel));
966
+ CFDictionarySetValue(query.get(), kSecAttrLabel, label);
945
967
  CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue);
946
968
  err = SecItemCopyMatching(query.get(), (CFTypeRef*)&identity.get());
947
969
  if (err == noErr)
@@ -958,7 +980,7 @@ Ice::SSL::SecureTransport::findCertificateChain(
958
980
  if (err != noErr)
959
981
  {
960
982
  ostringstream os;
961
- os << "SSL transport: couldn't create identity for certificate found in the keychain:\n"
983
+ os << "SSL transport: could not create identity for certificate found in the keychain:\n"
962
984
  << sslErrorToString(err);
963
985
  throw InitializationException(__FILE__, __LINE__, os.str());
964
986
  }
@@ -13,13 +13,6 @@ namespace Ice::SSL::SecureTransport
13
13
  std::string sslErrorToString(CFErrorRef);
14
14
  std::string sslErrorToString(OSStatus);
15
15
 
16
- # if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
17
- //
18
- // Retrieve a certificate property
19
- //
20
- CFDictionaryRef getCertificateProperty(SecCertificateRef, CFTypeRef);
21
- # endif
22
-
23
16
  //
24
17
  // Read certificate from a file.
25
18
  //
@@ -30,7 +23,6 @@ namespace Ice::SSL::SecureTransport
30
23
  const std::string&,
31
24
  const std::string&);
32
25
 
33
- SecCertificateRef loadCertificate(const std::string&);
34
26
  ICE_API CFArrayRef loadCACertificates(const std::string&);
35
27
  ICE_API CFArrayRef findCertificateChain(const std::string&, const std::string&, const std::string&);
36
28
 
@@ -127,10 +127,10 @@ Selector::getNextHandler(SocketOperation& status, DWORD& count, int& error, int
127
127
  }
128
128
  else
129
129
  {
130
- // This indicates a internal error with the IOCP completion port, we log the error and abort.
130
+ // This indicates an internal error with the IOCP completion port, we log the error and abort.
131
131
  Ice::SocketException ex(__FILE__, __LINE__, err);
132
132
  Ice::Error out(_instance->initializationData().logger);
133
- out << "couldn't dequeue packet from completion port:\n" << ex;
133
+ out << "could not dequeue packet from completion port:\n" << ex;
134
134
  std::abort();
135
135
  }
136
136
  }
@@ -478,7 +478,7 @@ Selector::startSelect()
478
478
 
479
479
  //
480
480
  // If there are ready handlers, don't block in select, just do a non-blocking
481
- // select to retrieve new ready handlers from the Java selector.
481
+ // select to retrieve new ready handlers from the selector.
482
482
  //
483
483
  _selectNow = !_readyHandlers.empty();
484
484
  }
@@ -556,7 +556,7 @@ Selector::select(int timeout)
556
556
  }
557
557
  else if (timeout > 0)
558
558
  {
559
- // kqueue use seconds, epoll use milliseconds
559
+ // kqueue uses seconds, epoll uses milliseconds
560
560
  # ifdef ICE_USE_EPOLL
561
561
  timeout = timeout * 1000;
562
562
  # endif
@@ -570,17 +570,17 @@ Selector::select(int timeout)
570
570
  while (true)
571
571
  {
572
572
  # if defined(ICE_USE_EPOLL)
573
- _count = epoll_wait(_queueFd, &_events[0], _events.size(), timeout);
573
+ _count = epoll_wait(_queueFd, _events.data(), _events.size(), timeout);
574
574
  # else // ICE_USE_KQUEUE
575
575
  assert(!_events.empty());
576
576
  if (timeout >= 0)
577
577
  {
578
578
  timespec ts{.tv_sec = timeout, .tv_nsec = 0};
579
- _count = kevent(_queueFd, nullptr, 0, &_events[0], static_cast<int>(_events.size()), &ts);
579
+ _count = kevent(_queueFd, nullptr, 0, _events.data(), static_cast<int>(_events.size()), &ts);
580
580
  }
581
581
  else
582
582
  {
583
- _count = kevent(_queueFd, nullptr, 0, &_events[0], static_cast<int>(_events.size()), nullptr);
583
+ _count = kevent(_queueFd, nullptr, 0, _events.data(), static_cast<int>(_events.size()), nullptr);
584
584
  }
585
585
  # endif
586
586
 
@@ -591,7 +591,7 @@ Selector::select(int timeout)
591
591
  continue;
592
592
  }
593
593
 
594
- // This indicates a internal error with the selector, we log the error and abort.
594
+ // This indicates an internal error with the selector, we log the error and abort.
595
595
  Ice::SocketException ex(__FILE__, __LINE__, IceInternal::getSocketErrno());
596
596
  Ice::Error out(_instance->initializationData().logger);
597
597
  out << "selector failed:\n" << ex;
@@ -640,9 +640,9 @@ Selector::updateSelector()
640
640
  {
641
641
  int rs = kevent(
642
642
  _queueFd,
643
- &_changes[0],
643
+ _changes.data(),
644
644
  static_cast<int>(_changes.size()),
645
- &_changes[0],
645
+ _changes.data(),
646
646
  static_cast<int>(_changes.size()),
647
647
  &zeroTimeout);
648
648
  if (rs < 0)
@@ -1120,6 +1120,9 @@ Selector::finish(EventHandler* handler, bool closeNow)
1120
1120
  void
1121
1121
  Selector::ready(EventHandler* handler, SocketOperation status, bool value)
1122
1122
  {
1123
+ // Hold _mutex across the read-modify-write of handler->_ready. The run-loop thread reads _ready under _mutex
1124
+ // (in startSelect/finishSelect, via EventHandlerWrapper), so updating it unlocked here would be a data race.
1125
+ lock_guard lock(_mutex);
1123
1126
  if (((handler->_ready & status) != 0) == value)
1124
1127
  {
1125
1128
  return; // Nothing to do if ready state already correctly set.
@@ -1134,7 +1137,6 @@ Selector::ready(EventHandler* handler, SocketOperation status, bool value)
1134
1137
  handler->_ready = static_cast<SocketOperation>(handler->_ready & ~status);
1135
1138
  }
1136
1139
 
1137
- lock_guard lock(_mutex);
1138
1140
  std::map<EventHandler*, EventHandlerWrapperPtr>::iterator p = _wrappers.find(handler);
1139
1141
  assert(p != _wrappers.end());
1140
1142
  p->second->checkReady();
@@ -184,7 +184,7 @@ IceInternal::ServantManager::findServant(const Identity& ident, const string_vie
184
184
  lock_guard lock(_mutex);
185
185
 
186
186
  //
187
- // This assert is not valid if the adapter dispatch incoming
187
+ // This assert is not valid if the adapter dispatches incoming
188
188
  // requests from bidir connections. This method might be called if
189
189
  // requests are received over the bidir connection after the
190
190
  // adapter was deactivated.
@@ -277,7 +277,7 @@ IceInternal::ServantManager::hasServant(const Identity& ident) const
277
277
  lock_guard lock(_mutex);
278
278
 
279
279
  //
280
- // This assert is not valid if the adapter dispatch incoming
280
+ // This assert is not valid if the adapter dispatches incoming
281
281
  // requests from bidir connections. This method might be called if
282
282
  // requests are received over the bidir connection after the
283
283
  // adapter was deactivated.
@@ -360,7 +360,7 @@ IceInternal::ServantManager::findServantLocator(const string_view category) cons
360
360
  lock_guard lock(_mutex);
361
361
 
362
362
  //
363
- // This assert is not valid if the adapter dispatch incoming
363
+ // This assert is not valid if the adapter dispatches incoming
364
364
  // requests from bidir connections. This method might be called if
365
365
  // requests are received over the bidir connection after the
366
366
  // adapter was deactivated.
@@ -11,7 +11,9 @@
11
11
  # include <winsock2.h>
12
12
  #else
13
13
  # include "Network.h"
14
+ # include <algorithm>
14
15
  # include <csignal>
16
+ # include <sys/resource.h>
15
17
  # include <sys/stat.h>
16
18
  # include <sys/types.h>
17
19
  # ifdef ICE_USE_SYSTEMD
@@ -172,93 +174,6 @@ namespace
172
174
  DeregisterEventSource(_source);
173
175
  }
174
176
 
175
- static void addKeys(const string& source, const StringConverterPtr& stringConverter)
176
- {
177
- HKEY hKey;
178
- DWORD d;
179
- //
180
- // Don't need to use a wide string converter as the wide string is passed
181
- // to Windows API.
182
- //
183
- LSTATUS err = RegCreateKeyExW(
184
- HKEY_LOCAL_MACHINE,
185
- stringToWstring(createKey(source), stringConverter).c_str(),
186
- 0,
187
- const_cast<wchar_t*>(L"REG_SZ"),
188
- REG_OPTION_NON_VOLATILE,
189
- KEY_ALL_ACCESS,
190
- 0,
191
- &hKey,
192
- &d);
193
-
194
- if (err != ERROR_SUCCESS)
195
- {
196
- throw SyscallException{__FILE__, __LINE__, "RegCreateKeyExW failed", static_cast<DWORD>(err)};
197
- }
198
-
199
- //
200
- // Get the filename of this DLL.
201
- //
202
- wchar_t path[_MAX_PATH];
203
- assert(_module != 0);
204
- if (!GetModuleFileNameW(_module, path, _MAX_PATH))
205
- {
206
- DWORD error = GetLastError();
207
- RegCloseKey(hKey);
208
- throw SyscallException{__FILE__, __LINE__, "GetModuleFileNameW failed", error};
209
- }
210
-
211
- //
212
- // The event resources are bundled into this DLL, therefore
213
- // the "EventMessageFile" key should contain the path to this
214
- // DLL.
215
- //
216
- err = RegSetValueExW(
217
- hKey,
218
- L"EventMessageFile",
219
- 0,
220
- REG_EXPAND_SZ,
221
- reinterpret_cast<unsigned char*>(path),
222
- static_cast<DWORD>((wcslen(path) * sizeof(wchar_t)) + 1));
223
-
224
- if (err == ERROR_SUCCESS)
225
- {
226
- //
227
- // The "TypesSupported" key indicates the supported event
228
- // types.
229
- //
230
- DWORD typesSupported = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
231
- err = RegSetValueExW(
232
- hKey,
233
- L"TypesSupported",
234
- 0,
235
- REG_DWORD,
236
- reinterpret_cast<unsigned char*>(&typesSupported),
237
- sizeof(typesSupported));
238
- }
239
- if (err != ERROR_SUCCESS)
240
- {
241
- RegCloseKey(hKey);
242
- throw SyscallException{__FILE__, __LINE__, "RegSetValueExW failed", static_cast<DWORD>(err)};
243
- }
244
-
245
- RegCloseKey(hKey);
246
- }
247
-
248
- static void removeKeys(const string& source, const StringConverterPtr& stringConverter)
249
- {
250
- //
251
- // Don't need to use a wide string converter as the wide string is passed
252
- // to Windows API.
253
- //
254
- LSTATUS err =
255
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, stringToWstring(createKey(source), stringConverter).c_str());
256
- if (err != ERROR_SUCCESS)
257
- {
258
- throw SyscallException{__FILE__, __LINE__, "RegDeleteKeyW failed", static_cast<DWORD>(err)};
259
- }
260
- }
261
-
262
177
  virtual void print(const string& prefix, const string& message)
263
178
  {
264
179
  string s;
@@ -379,8 +294,6 @@ namespace
379
294
  ReportEventW(_source, EVENTLOG_ERROR_TYPE, 0, EVENT_LOGGER_MSG, 0, 1, 0, messages, 0);
380
295
  }
381
296
 
382
- static void setModuleHandle(HMODULE module) { _module = module; }
383
-
384
297
  private:
385
298
  static string mangleSource(string name)
386
299
  {
@@ -395,22 +308,9 @@ namespace
395
308
  return name;
396
309
  }
397
310
 
398
- static string createKey(string name)
399
- {
400
- //
401
- // The registry key is:
402
- //
403
- // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application.
404
- //
405
- return "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" + mangleSource(name);
406
- }
407
-
408
311
  StringConverterPtr _stringConverter;
409
312
  HANDLE _source;
410
- static HMODULE _module;
411
313
  };
412
-
413
- HMODULE SMEventLoggerI::_module = 0;
414
314
  }
415
315
 
416
316
  #endif
@@ -425,6 +325,7 @@ Ice::Service::~Service()
425
325
  {
426
326
  _instance = nullptr;
427
327
  delete ctrlCHandler;
328
+ ctrlCHandler = nullptr;
428
329
  }
429
330
 
430
331
  bool
@@ -816,12 +717,6 @@ Ice::Service::configureService(const string& name)
816
717
  _name = name;
817
718
  }
818
719
 
819
- void
820
- Ice::Service::setModuleHandle(HMODULE module)
821
- {
822
- SMEventLoggerI::setModuleHandle(module);
823
- }
824
-
825
720
  #else
826
721
 
827
722
  void
@@ -1385,7 +1280,10 @@ ServiceStatusManager::stopUpdate()
1385
1280
  }
1386
1281
  }
1387
1282
 
1388
- thread.join();
1283
+ if (thread.joinable())
1284
+ {
1285
+ thread.join();
1286
+ }
1389
1287
  }
1390
1288
 
1391
1289
  void
@@ -1469,7 +1367,8 @@ Ice::Service::runDaemon(int argc, char* argv[], InitializationData initData)
1469
1367
  char c = 0;
1470
1368
  while (true)
1471
1369
  {
1472
- if (read(fds[0], &c, 1) == -1)
1370
+ ssize_t rc = read(fds[0], &c, 1);
1371
+ if (rc == -1)
1473
1372
  {
1474
1373
  if (IceInternal::interrupted())
1475
1374
  {
@@ -1483,6 +1382,20 @@ Ice::Service::runDaemon(int argc, char* argv[], InitializationData initData)
1483
1382
  consoleErr << IceInternal::errorToString(errno) << endl;
1484
1383
  _exit(EXIT_FAILURE);
1485
1384
  }
1385
+ else if (rc == 0)
1386
+ {
1387
+ //
1388
+ // EOF before the readiness byte: the daemon exited during startup without signaling readiness
1389
+ // (e.g. it was killed by a signal or aborted in a plug-in). Report a failure so supervisors don't
1390
+ // conclude the service started successfully.
1391
+ //
1392
+ if (argv[0])
1393
+ {
1394
+ consoleErr << argv[0] << ": ";
1395
+ }
1396
+ consoleErr << "daemon exited during startup before signaling readiness" << endl;
1397
+ _exit(EXIT_FAILURE);
1398
+ }
1486
1399
  break;
1487
1400
  }
1488
1401
 
@@ -1494,7 +1407,7 @@ Ice::Service::runDaemon(int argc, char* argv[], InitializationData initData)
1494
1407
  ssize_t rs;
1495
1408
  char s[16];
1496
1409
  string message;
1497
- while ((rs = read(fds[0], &s, 16)) > 0)
1410
+ while ((rs = read(fds[0], s, sizeof(s))) > 0)
1498
1411
  {
1499
1412
  message.append(s, static_cast<size_t>(rs));
1500
1413
  }
@@ -1579,13 +1492,18 @@ Ice::Service::runDaemon(int argc, char* argv[], InitializationData initData)
1579
1492
  // have an opportunity to use stdin/stdout/stderr if necessary. This also
1580
1493
  // conveniently allows the Ice.PrintProcessId property to work as expected.
1581
1494
  //
1582
- int fdMax = static_cast<int>(sysconf(_SC_OPEN_MAX));
1583
- if (fdMax <= 0)
1495
+ // Bound the probe loop by the soft RLIMIT_NOFILE — the kernel never allocates a
1496
+ // descriptor at or above it — capped so the loop stays cheap even with a very large
1497
+ // limit (such as LimitNOFILE=infinity under systemd).
1498
+ //
1499
+ rlim_t fdMax = 1 << 20;
1500
+ rlimit fdLimit{};
1501
+ if (getrlimit(RLIMIT_NOFILE, &fdLimit) == 0)
1584
1502
  {
1585
- throw SyscallException{__FILE__, __LINE__, "sysconf failed", errno};
1503
+ fdMax = std::min(fdMax, fdLimit.rlim_cur);
1586
1504
  }
1587
1505
 
1588
- for (int i = 0; i < fdMax; ++i)
1506
+ for (int i = 0; i < static_cast<int>(fdMax); ++i)
1589
1507
  {
1590
1508
  if (fcntl(i, F_GETFL) != -1)
1591
1509
  {