@scriptc/runtime 0.0.0 → 0.0.2
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.
- package/LICENSE +202 -0
- package/package.json +16 -6
- package/src/scr_array.c +488 -0
- package/src/scr_assert.c +1393 -0
- package/src/scr_async.c +2593 -0
- package/src/scr_async_dyn.c +607 -0
- package/src/scr_bytes.c +1425 -0
- package/src/scr_bytes_io.c +161 -0
- package/src/scr_child.c +3587 -0
- package/src/scr_closure.c +214 -0
- package/src/scr_console.c +143 -0
- package/src/scr_cycle.c +218 -0
- package/src/scr_dc.c +805 -0
- package/src/scr_dgram.c +1007 -0
- package/src/scr_dyn_handle.c +154 -0
- package/src/scr_dyn_invoke.c +644 -0
- package/src/scr_error.c +332 -0
- package/src/scr_events.c +714 -0
- package/src/scr_events_emitter.c +699 -0
- package/src/scr_exception.c +242 -0
- package/src/scr_fetch.c +1130 -0
- package/src/scr_fetch_curl.c +654 -0
- package/src/scr_http.c +3482 -0
- package/src/scr_http2.c +3030 -0
- package/src/scr_inspect.c +803 -0
- package/src/scr_inspect_island.c +51 -0
- package/src/scr_island.c +9363 -0
- package/src/scr_json.c +2151 -0
- package/src/scr_lib.c +3612 -0
- package/src/scr_loop_epoll.c +241 -0
- package/src/scr_loop_kqueue.c +121 -0
- package/src/scr_loop_wsapoll.c +208 -0
- package/src/scr_map.c +591 -0
- package/src/scr_net.c +3017 -0
- package/src/scr_net_island.c +458 -0
- package/src/scr_number.c +115 -0
- package/src/scr_object.c +25 -0
- package/src/scr_path.c +1266 -0
- package/src/scr_platform.h +119 -0
- package/src/scr_readline.c +287 -0
- package/src/scr_regex.c +1080 -0
- package/src/scr_runtime.h +5046 -0
- package/src/scr_stream.c +2877 -0
- package/src/scr_string.c +1264 -0
- package/src/scr_symbol.c +132 -0
- package/src/scr_test.c +662 -0
- package/src/scr_tls.c +1520 -0
- package/src/scr_union.c +105 -0
- package/src/scr_url.c +911 -0
- package/src/scr_url_internal.h +29 -0
- package/src/scr_url_params.c +561 -0
- package/src/scr_watch.c +568 -0
- package/src/scr_web.c +1778 -0
- package/src/scr_win.c +76 -0
- package/src/scr_zlib.c +197 -0
- package/src/scr_zlib_island.c +15 -0
- package/vendor/README.md +52 -0
- package/vendor/curl/COPYRIGHT +534 -0
- package/vendor/curl/include/curl/curl.h +3214 -0
- package/vendor/curl/include/curl/curlver.h +79 -0
- package/vendor/curl/include/curl/easy.h +125 -0
- package/vendor/curl/include/curl/header.h +74 -0
- package/vendor/curl/include/curl/mprintf.h +52 -0
- package/vendor/curl/include/curl/multi.h +460 -0
- package/vendor/curl/include/curl/options.h +70 -0
- package/vendor/curl/include/curl/stdcheaders.h +35 -0
- package/vendor/curl/include/curl/system.h +508 -0
- package/vendor/curl/include/curl/typecheck-gcc.h +716 -0
- package/vendor/curl/include/curl/urlapi.h +149 -0
- package/vendor/curl/include/curl/websockets.h +84 -0
- package/vendor/mbedtls/LICENSE +553 -0
- package/vendor/mbedtls/include/CMakeLists.txt +22 -0
- package/vendor/mbedtls/include/mbedtls/aes.h +631 -0
- package/vendor/mbedtls/include/mbedtls/aria.h +343 -0
- package/vendor/mbedtls/include/mbedtls/asn1.h +642 -0
- package/vendor/mbedtls/include/mbedtls/asn1write.h +390 -0
- package/vendor/mbedtls/include/mbedtls/base64.h +82 -0
- package/vendor/mbedtls/include/mbedtls/bignum.h +1088 -0
- package/vendor/mbedtls/include/mbedtls/block_cipher.h +76 -0
- package/vendor/mbedtls/include/mbedtls/build_info.h +194 -0
- package/vendor/mbedtls/include/mbedtls/camellia.h +305 -0
- package/vendor/mbedtls/include/mbedtls/ccm.h +526 -0
- package/vendor/mbedtls/include/mbedtls/chacha20.h +209 -0
- package/vendor/mbedtls/include/mbedtls/chachapoly.h +351 -0
- package/vendor/mbedtls/include/mbedtls/check_config.h +1149 -0
- package/vendor/mbedtls/include/mbedtls/cipher.h +1250 -0
- package/vendor/mbedtls/include/mbedtls/cmac.h +246 -0
- package/vendor/mbedtls/include/mbedtls/compat-2.x.h +46 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +578 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h +873 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h +359 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h +145 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h +91 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_x509.h +35 -0
- package/vendor/mbedtls/include/mbedtls/config_psa.h +61 -0
- package/vendor/mbedtls/include/mbedtls/constant_time.h +36 -0
- package/vendor/mbedtls/include/mbedtls/ctr_drbg.h +596 -0
- package/vendor/mbedtls/include/mbedtls/debug.h +156 -0
- package/vendor/mbedtls/include/mbedtls/des.h +385 -0
- package/vendor/mbedtls/include/mbedtls/dhm.h +972 -0
- package/vendor/mbedtls/include/mbedtls/ecdh.h +455 -0
- package/vendor/mbedtls/include/mbedtls/ecdsa.h +674 -0
- package/vendor/mbedtls/include/mbedtls/ecjpake.h +298 -0
- package/vendor/mbedtls/include/mbedtls/ecp.h +1517 -0
- package/vendor/mbedtls/include/mbedtls/entropy.h +274 -0
- package/vendor/mbedtls/include/mbedtls/error.h +201 -0
- package/vendor/mbedtls/include/mbedtls/gcm.h +387 -0
- package/vendor/mbedtls/include/mbedtls/hkdf.h +124 -0
- package/vendor/mbedtls/include/mbedtls/hmac_drbg.h +434 -0
- package/vendor/mbedtls/include/mbedtls/lms.h +440 -0
- package/vendor/mbedtls/include/mbedtls/mbedtls_config.h +4446 -0
- package/vendor/mbedtls/include/mbedtls/md.h +526 -0
- package/vendor/mbedtls/include/mbedtls/md5.h +190 -0
- package/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h +142 -0
- package/vendor/mbedtls/include/mbedtls/net_sockets.h +299 -0
- package/vendor/mbedtls/include/mbedtls/nist_kw.h +166 -0
- package/vendor/mbedtls/include/mbedtls/oid.h +727 -0
- package/vendor/mbedtls/include/mbedtls/pem.h +160 -0
- package/vendor/mbedtls/include/mbedtls/pk.h +1303 -0
- package/vendor/mbedtls/include/mbedtls/pkcs12.h +186 -0
- package/vendor/mbedtls/include/mbedtls/pkcs5.h +198 -0
- package/vendor/mbedtls/include/mbedtls/pkcs7.h +252 -0
- package/vendor/mbedtls/include/mbedtls/platform.h +516 -0
- package/vendor/mbedtls/include/mbedtls/platform_time.h +79 -0
- package/vendor/mbedtls/include/mbedtls/platform_util.h +247 -0
- package/vendor/mbedtls/include/mbedtls/poly1305.h +168 -0
- package/vendor/mbedtls/include/mbedtls/private_access.h +20 -0
- package/vendor/mbedtls/include/mbedtls/psa_util.h +207 -0
- package/vendor/mbedtls/include/mbedtls/ripemd160.h +136 -0
- package/vendor/mbedtls/include/mbedtls/rsa.h +1170 -0
- package/vendor/mbedtls/include/mbedtls/sha1.h +219 -0
- package/vendor/mbedtls/include/mbedtls/sha256.h +200 -0
- package/vendor/mbedtls/include/mbedtls/sha3.h +172 -0
- package/vendor/mbedtls/include/mbedtls/sha512.h +208 -0
- package/vendor/mbedtls/include/mbedtls/ssl.h +5887 -0
- package/vendor/mbedtls/include/mbedtls/ssl_cache.h +187 -0
- package/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h +482 -0
- package/vendor/mbedtls/include/mbedtls/ssl_cookie.h +106 -0
- package/vendor/mbedtls/include/mbedtls/ssl_ticket.h +199 -0
- package/vendor/mbedtls/include/mbedtls/threading.h +167 -0
- package/vendor/mbedtls/include/mbedtls/timing.h +94 -0
- package/vendor/mbedtls/include/mbedtls/version.h +78 -0
- package/vendor/mbedtls/include/mbedtls/x509.h +500 -0
- package/vendor/mbedtls/include/mbedtls/x509_crl.h +184 -0
- package/vendor/mbedtls/include/mbedtls/x509_crt.h +1208 -0
- package/vendor/mbedtls/include/mbedtls/x509_csr.h +382 -0
- package/vendor/mbedtls/include/psa/build_info.h +20 -0
- package/vendor/mbedtls/include/psa/crypto.h +4998 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h +31 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h +51 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h +101 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h +49 -0
- package/vendor/mbedtls/include/psa/crypto_builtin_composites.h +214 -0
- package/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h +118 -0
- package/vendor/mbedtls/include/psa/crypto_builtin_primitives.h +114 -0
- package/vendor/mbedtls/include/psa/crypto_compat.h +230 -0
- package/vendor/mbedtls/include/psa/crypto_config.h +145 -0
- package/vendor/mbedtls/include/psa/crypto_driver_common.h +44 -0
- package/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h +151 -0
- package/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h +52 -0
- package/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h +105 -0
- package/vendor/mbedtls/include/psa/crypto_extra.h +2145 -0
- package/vendor/mbedtls/include/psa/crypto_legacy.h +88 -0
- package/vendor/mbedtls/include/psa/crypto_platform.h +102 -0
- package/vendor/mbedtls/include/psa/crypto_se_driver.h +1383 -0
- package/vendor/mbedtls/include/psa/crypto_sizes.h +1319 -0
- package/vendor/mbedtls/include/psa/crypto_struct.h +527 -0
- package/vendor/mbedtls/include/psa/crypto_types.h +508 -0
- package/vendor/mbedtls/include/psa/crypto_values.h +2782 -0
- package/vendor/mbedtls/library/aes.c +2294 -0
- package/vendor/mbedtls/library/aesce.c +624 -0
- package/vendor/mbedtls/library/aesce.h +136 -0
- package/vendor/mbedtls/library/aesni.c +846 -0
- package/vendor/mbedtls/library/aesni.h +162 -0
- package/vendor/mbedtls/library/alignment.h +704 -0
- package/vendor/mbedtls/library/aria.c +969 -0
- package/vendor/mbedtls/library/asn1parse.c +468 -0
- package/vendor/mbedtls/library/asn1write.c +440 -0
- package/vendor/mbedtls/library/base64.c +322 -0
- package/vendor/mbedtls/library/base64_internal.h +45 -0
- package/vendor/mbedtls/library/bignum.c +2583 -0
- package/vendor/mbedtls/library/bignum_core.c +1240 -0
- package/vendor/mbedtls/library/bignum_core.h +872 -0
- package/vendor/mbedtls/library/bignum_core_invasive.h +38 -0
- package/vendor/mbedtls/library/bignum_internal.h +122 -0
- package/vendor/mbedtls/library/bignum_mod.c +394 -0
- package/vendor/mbedtls/library/bignum_mod.h +452 -0
- package/vendor/mbedtls/library/bignum_mod_raw.c +276 -0
- package/vendor/mbedtls/library/bignum_mod_raw.h +416 -0
- package/vendor/mbedtls/library/bignum_mod_raw_invasive.h +34 -0
- package/vendor/mbedtls/library/block_cipher.c +207 -0
- package/vendor/mbedtls/library/block_cipher_internal.h +99 -0
- package/vendor/mbedtls/library/bn_mul.h +1094 -0
- package/vendor/mbedtls/library/camellia.c +1058 -0
- package/vendor/mbedtls/library/ccm.c +777 -0
- package/vendor/mbedtls/library/chacha20.c +563 -0
- package/vendor/mbedtls/library/chacha20_internal.h +23 -0
- package/vendor/mbedtls/library/chachapoly.c +487 -0
- package/vendor/mbedtls/library/check_crypto_config.h +136 -0
- package/vendor/mbedtls/library/cipher.c +1712 -0
- package/vendor/mbedtls/library/cipher_invasive.h +28 -0
- package/vendor/mbedtls/library/cipher_wrap.c +2482 -0
- package/vendor/mbedtls/library/cipher_wrap.h +178 -0
- package/vendor/mbedtls/library/cmac.c +1067 -0
- package/vendor/mbedtls/library/common.h +487 -0
- package/vendor/mbedtls/library/constant_time.c +247 -0
- package/vendor/mbedtls/library/constant_time_impl.h +541 -0
- package/vendor/mbedtls/library/constant_time_internal.h +579 -0
- package/vendor/mbedtls/library/ctr.h +35 -0
- package/vendor/mbedtls/library/ctr_drbg.c +1016 -0
- package/vendor/mbedtls/library/debug.c +475 -0
- package/vendor/mbedtls/library/debug_internal.h +185 -0
- package/vendor/mbedtls/library/des.c +1042 -0
- package/vendor/mbedtls/library/dhm.c +700 -0
- package/vendor/mbedtls/library/ecdh.c +696 -0
- package/vendor/mbedtls/library/ecdsa.c +858 -0
- package/vendor/mbedtls/library/ecjpake.c +1216 -0
- package/vendor/mbedtls/library/ecp.c +3674 -0
- package/vendor/mbedtls/library/ecp_curves.c +6125 -0
- package/vendor/mbedtls/library/ecp_curves_new.c +9 -0
- package/vendor/mbedtls/library/ecp_internal_alt.h +287 -0
- package/vendor/mbedtls/library/ecp_invasive.h +305 -0
- package/vendor/mbedtls/library/entropy.c +680 -0
- package/vendor/mbedtls/library/entropy_poll.c +233 -0
- package/vendor/mbedtls/library/entropy_poll.h +64 -0
- package/vendor/mbedtls/library/error.c +878 -0
- package/vendor/mbedtls/library/gcm.c +1330 -0
- package/vendor/mbedtls/library/hkdf.c +161 -0
- package/vendor/mbedtls/library/hmac_drbg.c +633 -0
- package/vendor/mbedtls/library/lmots.c +789 -0
- package/vendor/mbedtls/library/lmots.h +288 -0
- package/vendor/mbedtls/library/lms.c +778 -0
- package/vendor/mbedtls/library/md.c +1108 -0
- package/vendor/mbedtls/library/md5.c +426 -0
- package/vendor/mbedtls/library/md_psa.h +26 -0
- package/vendor/mbedtls/library/md_wrap.h +46 -0
- package/vendor/mbedtls/library/memory_buffer_alloc.c +751 -0
- package/vendor/mbedtls/library/mps_common.h +181 -0
- package/vendor/mbedtls/library/mps_error.h +89 -0
- package/vendor/mbedtls/library/mps_reader.c +538 -0
- package/vendor/mbedtls/library/mps_reader.h +366 -0
- package/vendor/mbedtls/library/mps_trace.c +112 -0
- package/vendor/mbedtls/library/mps_trace.h +154 -0
- package/vendor/mbedtls/library/net_sockets.c +694 -0
- package/vendor/mbedtls/library/nist_kw.c +729 -0
- package/vendor/mbedtls/library/oid.c +1166 -0
- package/vendor/mbedtls/library/padlock.c +157 -0
- package/vendor/mbedtls/library/padlock.h +111 -0
- package/vendor/mbedtls/library/pem.c +554 -0
- package/vendor/mbedtls/library/pk.c +1602 -0
- package/vendor/mbedtls/library/pk_ecc.c +261 -0
- package/vendor/mbedtls/library/pk_internal.h +241 -0
- package/vendor/mbedtls/library/pk_wrap.c +1618 -0
- package/vendor/mbedtls/library/pk_wrap.h +138 -0
- package/vendor/mbedtls/library/pkcs12.c +437 -0
- package/vendor/mbedtls/library/pkcs5.c +500 -0
- package/vendor/mbedtls/library/pkcs7.c +787 -0
- package/vendor/mbedtls/library/pkparse.c +1392 -0
- package/vendor/mbedtls/library/pkwrite.c +631 -0
- package/vendor/mbedtls/library/pkwrite.h +121 -0
- package/vendor/mbedtls/library/platform.c +402 -0
- package/vendor/mbedtls/library/platform_util.c +258 -0
- package/vendor/mbedtls/library/poly1305.c +492 -0
- package/vendor/mbedtls/library/psa_crypto.c +9532 -0
- package/vendor/mbedtls/library/psa_crypto_aead.c +646 -0
- package/vendor/mbedtls/library/psa_crypto_aead.h +499 -0
- package/vendor/mbedtls/library/psa_crypto_cipher.c +747 -0
- package/vendor/mbedtls/library/psa_crypto_cipher.h +316 -0
- package/vendor/mbedtls/library/psa_crypto_client.c +22 -0
- package/vendor/mbedtls/library/psa_crypto_core.h +983 -0
- package/vendor/mbedtls/library/psa_crypto_core_common.h +52 -0
- package/vendor/mbedtls/library/psa_crypto_driver_wrappers.h +2896 -0
- package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c +256 -0
- package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h +31 -0
- package/vendor/mbedtls/library/psa_crypto_ecp.c +594 -0
- package/vendor/mbedtls/library/psa_crypto_ecp.h +267 -0
- package/vendor/mbedtls/library/psa_crypto_ffdh.c +361 -0
- package/vendor/mbedtls/library/psa_crypto_ffdh.h +131 -0
- package/vendor/mbedtls/library/psa_crypto_hash.c +470 -0
- package/vendor/mbedtls/library/psa_crypto_hash.h +211 -0
- package/vendor/mbedtls/library/psa_crypto_invasive.h +92 -0
- package/vendor/mbedtls/library/psa_crypto_its.h +131 -0
- package/vendor/mbedtls/library/psa_crypto_mac.c +505 -0
- package/vendor/mbedtls/library/psa_crypto_mac.h +264 -0
- package/vendor/mbedtls/library/psa_crypto_pake.c +571 -0
- package/vendor/mbedtls/library/psa_crypto_pake.h +159 -0
- package/vendor/mbedtls/library/psa_crypto_random.c +181 -0
- package/vendor/mbedtls/library/psa_crypto_random.h +72 -0
- package/vendor/mbedtls/library/psa_crypto_random_impl.h +200 -0
- package/vendor/mbedtls/library/psa_crypto_rsa.c +714 -0
- package/vendor/mbedtls/library/psa_crypto_rsa.h +321 -0
- package/vendor/mbedtls/library/psa_crypto_se.c +373 -0
- package/vendor/mbedtls/library/psa_crypto_se.h +192 -0
- package/vendor/mbedtls/library/psa_crypto_slot_management.c +1137 -0
- package/vendor/mbedtls/library/psa_crypto_slot_management.h +344 -0
- package/vendor/mbedtls/library/psa_crypto_storage.c +481 -0
- package/vendor/mbedtls/library/psa_crypto_storage.h +392 -0
- package/vendor/mbedtls/library/psa_its_file.c +254 -0
- package/vendor/mbedtls/library/psa_util.c +614 -0
- package/vendor/mbedtls/library/psa_util_internal.h +100 -0
- package/vendor/mbedtls/library/ripemd160.c +490 -0
- package/vendor/mbedtls/library/rsa.c +3121 -0
- package/vendor/mbedtls/library/rsa_alt_helpers.c +455 -0
- package/vendor/mbedtls/library/rsa_alt_helpers.h +209 -0
- package/vendor/mbedtls/library/rsa_internal.h +188 -0
- package/vendor/mbedtls/library/sha1.c +480 -0
- package/vendor/mbedtls/library/sha256.c +983 -0
- package/vendor/mbedtls/library/sha3.c +721 -0
- package/vendor/mbedtls/library/sha512.c +1115 -0
- package/vendor/mbedtls/library/ssl_cache.c +410 -0
- package/vendor/mbedtls/library/ssl_ciphersuites.c +2050 -0
- package/vendor/mbedtls/library/ssl_ciphersuites_internal.h +154 -0
- package/vendor/mbedtls/library/ssl_client.c +1023 -0
- package/vendor/mbedtls/library/ssl_client.h +22 -0
- package/vendor/mbedtls/library/ssl_cookie.c +384 -0
- package/vendor/mbedtls/library/ssl_debug_helpers.h +85 -0
- package/vendor/mbedtls/library/ssl_debug_helpers_generated.c +251 -0
- package/vendor/mbedtls/library/ssl_misc.h +3198 -0
- package/vendor/mbedtls/library/ssl_msg.c +6619 -0
- package/vendor/mbedtls/library/ssl_ticket.c +556 -0
- package/vendor/mbedtls/library/ssl_tls.c +10234 -0
- package/vendor/mbedtls/library/ssl_tls12_client.c +3688 -0
- package/vendor/mbedtls/library/ssl_tls12_server.c +4311 -0
- package/vendor/mbedtls/library/ssl_tls13_client.c +3208 -0
- package/vendor/mbedtls/library/ssl_tls13_generic.c +1793 -0
- package/vendor/mbedtls/library/ssl_tls13_invasive.h +23 -0
- package/vendor/mbedtls/library/ssl_tls13_keys.c +1918 -0
- package/vendor/mbedtls/library/ssl_tls13_keys.h +668 -0
- package/vendor/mbedtls/library/ssl_tls13_server.c +3624 -0
- package/vendor/mbedtls/library/threading.c +193 -0
- package/vendor/mbedtls/library/threading_internal.h +28 -0
- package/vendor/mbedtls/library/timing.c +152 -0
- package/vendor/mbedtls/library/version.c +32 -0
- package/vendor/mbedtls/library/version_features.c +856 -0
- package/vendor/mbedtls/library/x509.c +1776 -0
- package/vendor/mbedtls/library/x509_create.c +570 -0
- package/vendor/mbedtls/library/x509_crl.c +708 -0
- package/vendor/mbedtls/library/x509_crt.c +3311 -0
- package/vendor/mbedtls/library/x509_csr.c +648 -0
- package/vendor/mbedtls/library/x509_internal.h +101 -0
- package/vendor/mbedtls/library/x509write.c +174 -0
- package/vendor/mbedtls/library/x509write_crt.c +688 -0
- package/vendor/mbedtls/library/x509write_csr.c +336 -0
- package/vendor/quickjs-ng/CMakeLists.txt +566 -0
- package/vendor/quickjs-ng/LICENSE +24 -0
- package/vendor/quickjs-ng/README.md +24 -0
- package/vendor/quickjs-ng/api-test.c +1195 -0
- package/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
- package/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
- package/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
- package/vendor/quickjs-ng/cutils.h +1998 -0
- package/vendor/quickjs-ng/dtoa.c +1619 -0
- package/vendor/quickjs-ng/dtoa.h +87 -0
- package/vendor/quickjs-ng/gen/function_source.c +81 -0
- package/vendor/quickjs-ng/gen/hello.c +53 -0
- package/vendor/quickjs-ng/gen/hello_module.c +106 -0
- package/vendor/quickjs-ng/gen/repl.c +3036 -0
- package/vendor/quickjs-ng/gen/standalone.c +323 -0
- package/vendor/quickjs-ng/gen/test_fib.c +81 -0
- package/vendor/quickjs-ng/libregexp-opcode.h +73 -0
- package/vendor/quickjs-ng/libregexp.c +3474 -0
- package/vendor/quickjs-ng/libregexp.h +101 -0
- package/vendor/quickjs-ng/libunicode-table.h +5173 -0
- package/vendor/quickjs-ng/libunicode.c +2069 -0
- package/vendor/quickjs-ng/libunicode.h +172 -0
- package/vendor/quickjs-ng/list.h +107 -0
- package/vendor/quickjs-ng/lre-test.c +52 -0
- package/vendor/quickjs-ng/qjs.c +762 -0
- package/vendor/quickjs-ng/qjsc.c +673 -0
- package/vendor/quickjs-ng/quickjs-atom.h +280 -0
- package/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
- package/vendor/quickjs-ng/quickjs-libc.c +5037 -0
- package/vendor/quickjs-ng/quickjs-libc.h +87 -0
- package/vendor/quickjs-ng/quickjs-opcode.h +377 -0
- package/vendor/quickjs-ng/quickjs.c +64041 -0
- package/vendor/quickjs-ng/quickjs.h +1447 -0
- package/vendor/quickjs-ng/run-test262.c +2374 -0
- package/vendor/quickjs-ng/unicode_gen.c +3121 -0
- package/vendor/quickjs-ng/unicode_gen_def.h +310 -0
- package/vendor/ryu/LICENSE-Boost +23 -0
- package/vendor/ryu/common.h +114 -0
- package/vendor/ryu/d2s.c +509 -0
- package/vendor/ryu/d2s_full_table.h +367 -0
- package/vendor/ryu/d2s_intrinsics.h +357 -0
- package/vendor/ryu/d2s_small_table.h +186 -0
- package/vendor/ryu/digit_table.h +35 -0
- package/vendor/ryu/ryu.h +46 -0
- package/vendor/zlib/LICENSE +22 -0
- package/vendor/zlib/adler32.c +164 -0
- package/vendor/zlib/compress.c +75 -0
- package/vendor/zlib/crc32.c +1049 -0
- package/vendor/zlib/crc32.h +9446 -0
- package/vendor/zlib/deflate.c +2139 -0
- package/vendor/zlib/deflate.h +377 -0
- package/vendor/zlib/gzclose.c +23 -0
- package/vendor/zlib/gzguts.h +214 -0
- package/vendor/zlib/gzlib.c +582 -0
- package/vendor/zlib/gzread.c +602 -0
- package/vendor/zlib/gzwrite.c +631 -0
- package/vendor/zlib/infback.c +628 -0
- package/vendor/zlib/inffast.c +320 -0
- package/vendor/zlib/inffast.h +11 -0
- package/vendor/zlib/inffixed.h +94 -0
- package/vendor/zlib/inflate.c +1526 -0
- package/vendor/zlib/inflate.h +126 -0
- package/vendor/zlib/inftrees.c +299 -0
- package/vendor/zlib/inftrees.h +62 -0
- package/vendor/zlib/trees.c +1117 -0
- package/vendor/zlib/trees.h +128 -0
- package/vendor/zlib/uncompr.c +85 -0
- package/vendor/zlib/zconf.h +543 -0
- package/vendor/zlib/zlib.h +1938 -0
- package/vendor/zlib/zutil.c +299 -0
- package/vendor/zlib/zutil.h +254 -0
- package/README.md +0 -3
- package/index.js +0 -2
package/src/scr_dgram.c
ADDED
|
@@ -0,0 +1,1007 @@
|
|
|
1
|
+
/* node:dgram + node:dns — UDP sockets over the event loop's readiness
|
|
2
|
+
* poller (the scr_platform.h contract — kqueue on macOS/BSD, epoll on
|
|
3
|
+
* Linux; scr_net.c has the seam's full story), and the dns.lookup slice
|
|
4
|
+
* that rides the same unit.
|
|
5
|
+
*
|
|
6
|
+
* ── Design note ──────────────────────────────────────────────────────
|
|
7
|
+
*
|
|
8
|
+
* Object model. One refcounted handle kind, a LEAN allocation (no cycle
|
|
9
|
+
* header — the ScrNetSocket precedent): ScrDgramSocket (fd, the
|
|
10
|
+
* bound/connected/closing state machine, message/listening/connect/
|
|
11
|
+
* close/error listener lists, the unref flag). Listeners MOVE in (+1)
|
|
12
|
+
* and are released when the handle settles ('close' fired, or the
|
|
13
|
+
* exit-time cleanup) — the scr_net.c ownership story verbatim, so a
|
|
14
|
+
* listener capturing its own socket cannot cycle past settlement.
|
|
15
|
+
*
|
|
16
|
+
* Event dispatch. One poller owned by this unit (lazily created), fds
|
|
17
|
+
* non-blocking. The loop (scr_async.c) calls scr_dgram_dispatch() at
|
|
18
|
+
* every turn top — the net hook's exact shape — alternating a SWEEP of
|
|
19
|
+
* deferred emits ('listening'/'connect' callbacks, bind/send failures,
|
|
20
|
+
* 'close', pending dns.lookup deliveries) with a zero-timeout poller
|
|
21
|
+
* drain (arrived datagrams, delivered macrotask-style on the main
|
|
22
|
+
* stack), stopping early when a callback enqueued microtasks or threw.
|
|
23
|
+
* Between turns the loop's idle poll(2) watches this unit's poller fd.
|
|
24
|
+
*
|
|
25
|
+
* Read model. Consumer-driven like net sockets: the read filter is armed
|
|
26
|
+
* only while a 'message' listener exists — unheard datagrams wait in
|
|
27
|
+
* the kernel's socket buffer (and drop when it fills, UDP's contract
|
|
28
|
+
* in Node too). One recvfrom(2) per datagram, one 'message' emit per
|
|
29
|
+
* datagram, rinfo parts delivered borrowed to the per-shape adapters.
|
|
30
|
+
*
|
|
31
|
+
* Send model. sendto(2) immediately — a UDP datagram either goes out or
|
|
32
|
+
* it doesn't; there is no partial-write buffering. An unbound sender
|
|
33
|
+
* implicit-binds (the kernel's ephemeral port), like Node. Send
|
|
34
|
+
* failures defer to the 'error' sweep.
|
|
35
|
+
*
|
|
36
|
+
* State errors, Node-matched: bind on a bound socket throws "Socket is
|
|
37
|
+
* already bound"; connect on a connected one "Already connected";
|
|
38
|
+
* send/close/address on a closed (or address on a never-bound) one
|
|
39
|
+
* "Not running" — all synchronous catchable Errors with Node's
|
|
40
|
+
* MESSAGES (the code/errno properties don't exist — the fs error
|
|
41
|
+
* stance, SEMANTICS.md divergence 13). Runtime failures (EADDRINUSE,
|
|
42
|
+
* unreachable sends, failed host lookups) are the async 'error' event;
|
|
43
|
+
* an 'error' with no listener prints and exits 1, the unhandled
|
|
44
|
+
* EventEmitter behavior. bind()/connect() emit 'listening' (connect
|
|
45
|
+
* implicit-binds first, so BOTH fire, Node's order) and 'connect' on
|
|
46
|
+
* the next dispatch pass — Node's next-tick emits.
|
|
47
|
+
*
|
|
48
|
+
* Loop liveness. An open (bound or connected) socket holds the loop
|
|
49
|
+
* until 'close' delivers or unref() waives it — Node's unref
|
|
50
|
+
* semantics; ref() re-arms. A created-but-never-bound socket holds
|
|
51
|
+
* nothing. Handles abandoned at exit are released by the atexit
|
|
52
|
+
* cleanup, so the RC audit stays clean.
|
|
53
|
+
*
|
|
54
|
+
* dns.lookup. getaddrinfo(AF_INET) runs AT CALL TIME — synchronously,
|
|
55
|
+
* where Node uses its threadpool (SEMANTICS.md documents the blocking
|
|
56
|
+
* divergence) — and the callback defers to the next dispatch pass, so
|
|
57
|
+
* delivery is async like Node's. Failures deliver Node's message shape
|
|
58
|
+
* ("getaddrinfo ENOTFOUND <hostname>") through the per-union adapters;
|
|
59
|
+
* the address argument is "" on failure where Node passes undefined
|
|
60
|
+
* (the string-typed slot cannot hold undefined). A pending lookup
|
|
61
|
+
* holds the loop like an in-flight request. */
|
|
62
|
+
#include "scr_platform.h"
|
|
63
|
+
#include "scr_runtime.h"
|
|
64
|
+
|
|
65
|
+
#include <errno.h>
|
|
66
|
+
#include <fcntl.h>
|
|
67
|
+
#include <stdio.h>
|
|
68
|
+
#include <stdlib.h>
|
|
69
|
+
#include <string.h>
|
|
70
|
+
#include <unistd.h>
|
|
71
|
+
#ifdef _WIN32
|
|
72
|
+
#include <winsock2.h>
|
|
73
|
+
#include <ws2tcpip.h> /* getaddrinfo/EAI_*, inet_pton/ntop, socklen_t */
|
|
74
|
+
#else
|
|
75
|
+
#include <netdb.h>
|
|
76
|
+
#include <netinet/in.h>
|
|
77
|
+
#include <arpa/inet.h>
|
|
78
|
+
#include <sys/socket.h>
|
|
79
|
+
#endif
|
|
80
|
+
|
|
81
|
+
static void scr_dgram_oom(void) {
|
|
82
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
83
|
+
abort();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#ifdef _WIN32
|
|
87
|
+
/* ── the winsock arm (scr_net.c's respelling, restated so this unit links
|
|
88
|
+
* without scr_net.c — the listener-list precedent below) ───────────────
|
|
89
|
+
* The BSD socket calls this file speaks, respelled once so every call
|
|
90
|
+
* site stays byte-identical: SOCKETs narrow through the int fd contract,
|
|
91
|
+
* failures land their WSA code in errno TRANSLATED to the POSIX constant
|
|
92
|
+
* scr_dgram_errname and the retry tests read (libuv performs the same
|
|
93
|
+
* translation for Node, so the spellings agree with the Windows oracle),
|
|
94
|
+
* and close is closesocket. WSAStartup rides scrp_poller_new
|
|
95
|
+
* (scr_loop_wsapoll.c): every socket() site is preceded by
|
|
96
|
+
* scr_dgram_poller_init(), and scr_dns_lookup initializes the poller on
|
|
97
|
+
* this arm before getaddrinfo (which needs winsock started too). The
|
|
98
|
+
* netdb surface (getaddrinfo/freeaddrinfo, the EAI_* codes) is native
|
|
99
|
+
* winsock — ws2tcpip.h spells Node's exact codes, WSAHOST_NOT_FOUND
|
|
100
|
+
* being EAI_NONAME. */
|
|
101
|
+
static int scr_dgram_w32_map_err(int e) {
|
|
102
|
+
switch (e) {
|
|
103
|
+
case WSAEWOULDBLOCK: return EAGAIN;
|
|
104
|
+
case WSAEINTR: return EINTR;
|
|
105
|
+
case WSAECONNREFUSED: return ECONNREFUSED;
|
|
106
|
+
case WSAECONNRESET: return ECONNRESET;
|
|
107
|
+
case WSAEADDRINUSE: return EADDRINUSE;
|
|
108
|
+
case WSAEACCES: return EACCES;
|
|
109
|
+
case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL;
|
|
110
|
+
case WSAEHOSTUNREACH: return EHOSTUNREACH;
|
|
111
|
+
case WSAENETUNREACH: return ENETUNREACH;
|
|
112
|
+
case WSAEMSGSIZE: return EMSGSIZE;
|
|
113
|
+
case WSAEINVAL: return EINVAL;
|
|
114
|
+
default: return e;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static void scr_dgram_w32_seterr(void) { errno = scr_dgram_w32_map_err((int)WSAGetLastError()); }
|
|
119
|
+
|
|
120
|
+
static int scr_dgram_w32_socket(int af, int type, int proto) {
|
|
121
|
+
SOCKET s = socket(af, type, proto);
|
|
122
|
+
if (s == INVALID_SOCKET) {
|
|
123
|
+
scr_dgram_w32_seterr();
|
|
124
|
+
return -1;
|
|
125
|
+
}
|
|
126
|
+
return (int)s;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static int scr_dgram_w32_bind(int fd, const struct sockaddr *sa, socklen_t len) {
|
|
130
|
+
if (bind((SOCKET)fd, sa, (int)len) != 0) {
|
|
131
|
+
scr_dgram_w32_seterr();
|
|
132
|
+
return -1;
|
|
133
|
+
}
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* UDP connect(2) is local and immediate on winsock too — no EINPROGRESS
|
|
138
|
+
* arm, unlike scr_net.c's stream wrapper. */
|
|
139
|
+
static int scr_dgram_w32_connect(int fd, const struct sockaddr *sa, socklen_t len) {
|
|
140
|
+
if (connect((SOCKET)fd, sa, (int)len) != 0) {
|
|
141
|
+
scr_dgram_w32_seterr();
|
|
142
|
+
return -1;
|
|
143
|
+
}
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static int scr_dgram_w32_getsockname(int fd, struct sockaddr *sa, socklen_t *len) {
|
|
148
|
+
int ilen = (int)*len;
|
|
149
|
+
int rc = getsockname((SOCKET)fd, sa, &ilen);
|
|
150
|
+
*len = (socklen_t)ilen;
|
|
151
|
+
if (rc != 0) {
|
|
152
|
+
scr_dgram_w32_seterr();
|
|
153
|
+
return -1;
|
|
154
|
+
}
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static int scr_dgram_w32_setsockopt(int fd, int level, int name, const void *val, socklen_t len) {
|
|
159
|
+
if (setsockopt((SOCKET)fd, level, name, (const char *)val, (int)len) != 0) {
|
|
160
|
+
scr_dgram_w32_seterr();
|
|
161
|
+
return -1;
|
|
162
|
+
}
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
static ssize_t scr_dgram_w32_sendto(int fd, const void *buf, size_t len, int flags,
|
|
167
|
+
const struct sockaddr *sa, socklen_t salen) {
|
|
168
|
+
int n = sendto((SOCKET)fd, (const char *)buf, len > 0x40000000 ? 0x40000000 : (int)len, flags,
|
|
169
|
+
sa, (int)salen);
|
|
170
|
+
if (n < 0) scr_dgram_w32_seterr();
|
|
171
|
+
return n;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
static ssize_t scr_dgram_w32_recvfrom(int fd, void *buf, size_t len, int flags,
|
|
175
|
+
struct sockaddr *sa, socklen_t *salen) {
|
|
176
|
+
int ilen = salen != NULL ? (int)*salen : 0;
|
|
177
|
+
int n = recvfrom((SOCKET)fd, (char *)buf, len > 0x40000000 ? 0x40000000 : (int)len, flags, sa,
|
|
178
|
+
salen != NULL ? &ilen : NULL);
|
|
179
|
+
if (salen != NULL) *salen = (socklen_t)ilen;
|
|
180
|
+
if (n < 0) scr_dgram_w32_seterr();
|
|
181
|
+
return n;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
static int scr_dgram_w32_close(int fd) {
|
|
185
|
+
if (closesocket((SOCKET)fd) != 0) {
|
|
186
|
+
scr_dgram_w32_seterr();
|
|
187
|
+
return -1;
|
|
188
|
+
}
|
|
189
|
+
return 0;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
#define socket(af, type, proto) scr_dgram_w32_socket((af), (type), (proto))
|
|
193
|
+
#define bind(fd, sa, len) scr_dgram_w32_bind((fd), (sa), (len))
|
|
194
|
+
#define connect(fd, sa, len) scr_dgram_w32_connect((fd), (sa), (len))
|
|
195
|
+
#define getsockname(fd, sa, len) scr_dgram_w32_getsockname((fd), (sa), (len))
|
|
196
|
+
#define setsockopt(fd, l, n, v, len) scr_dgram_w32_setsockopt((fd), (l), (n), (v), (len))
|
|
197
|
+
#define sendto(fd, buf, len, fl, sa, salen) scr_dgram_w32_sendto((fd), (buf), (len), (fl), (sa), (salen))
|
|
198
|
+
#define recvfrom(fd, buf, len, fl, sa, salen) scr_dgram_w32_recvfrom((fd), (buf), (len), (fl), (sa), (salen))
|
|
199
|
+
#define close(fd) scr_dgram_w32_close(fd)
|
|
200
|
+
#endif /* _WIN32 */
|
|
201
|
+
|
|
202
|
+
/* Nonblocking + no-inherit, the scr_net.c spelling. The win32 arm also
|
|
203
|
+
* turns OFF winsock's UDP connection-reset relay (an ICMP port-
|
|
204
|
+
* unreachable from a PAST send failing a FUTURE recvfrom with
|
|
205
|
+
* WSAECONNRESET) via SIO_UDP_CONNRESET — libuv does exactly this for
|
|
206
|
+
* every Node UDP socket, so leaving it on would diverge from the
|
|
207
|
+
* Windows oracle. */
|
|
208
|
+
static void scr_dgram_nonblock(int fd) {
|
|
209
|
+
#ifdef _WIN32
|
|
210
|
+
u_long one = 1;
|
|
211
|
+
ioctlsocket((SOCKET)fd, FIONBIO, &one);
|
|
212
|
+
SetHandleInformation((HANDLE)(SOCKET)fd, HANDLE_FLAG_INHERIT, 0);
|
|
213
|
+
#ifndef SIO_UDP_CONNRESET
|
|
214
|
+
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
|
|
215
|
+
#endif
|
|
216
|
+
BOOL off = FALSE;
|
|
217
|
+
DWORD bytes = 0;
|
|
218
|
+
WSAIoctl((SOCKET)fd, SIO_UDP_CONNRESET, &off, sizeof off, NULL, 0, &bytes, NULL, NULL);
|
|
219
|
+
#else
|
|
220
|
+
fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
221
|
+
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
|
222
|
+
#endif
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Node's error-code names for the socket errors this slice can meet. */
|
|
226
|
+
static const char *scr_dgram_errname(int err) {
|
|
227
|
+
switch (err) {
|
|
228
|
+
case EADDRINUSE: return "EADDRINUSE";
|
|
229
|
+
case EACCES: return "EACCES";
|
|
230
|
+
case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
|
|
231
|
+
case ECONNREFUSED: return "ECONNREFUSED";
|
|
232
|
+
case EHOSTUNREACH: return "EHOSTUNREACH";
|
|
233
|
+
case ENETUNREACH: return "ENETUNREACH";
|
|
234
|
+
case EMSGSIZE: return "EMSGSIZE";
|
|
235
|
+
case EINVAL: return "EINVAL";
|
|
236
|
+
default: return "EUNKNOWN";
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* ── listener lists (the scr_net.c snapshot discipline, restated so this
|
|
241
|
+
* unit links without scr_net.c) ─────────────────────────────────────── */
|
|
242
|
+
|
|
243
|
+
typedef struct {
|
|
244
|
+
ScrClosure *cb;
|
|
245
|
+
void *fn;
|
|
246
|
+
bool once;
|
|
247
|
+
} ScrDgramL;
|
|
248
|
+
|
|
249
|
+
typedef struct {
|
|
250
|
+
ScrDgramL *ls;
|
|
251
|
+
size_t n, cap;
|
|
252
|
+
} ScrDgramLs;
|
|
253
|
+
|
|
254
|
+
static void scr_dgram_ls_add(ScrDgramLs *l, ScrClosure *cb, void *fn, bool once) {
|
|
255
|
+
if (l->n == l->cap) {
|
|
256
|
+
l->cap = l->cap ? l->cap * 2 : 2;
|
|
257
|
+
l->ls = realloc(l->ls, l->cap * sizeof *l->ls);
|
|
258
|
+
if (!l->ls) scr_dgram_oom();
|
|
259
|
+
}
|
|
260
|
+
l->ls[l->n].cb = cb;
|
|
261
|
+
l->ls[l->n].fn = fn;
|
|
262
|
+
l->ls[l->n].once = once;
|
|
263
|
+
l->n++;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
static void scr_dgram_ls_drop(ScrDgramLs *l) {
|
|
267
|
+
for (size_t i = 0; i < l->n; i++) scr_closure_release(l->ls[i].cb);
|
|
268
|
+
free(l->ls);
|
|
269
|
+
l->ls = NULL;
|
|
270
|
+
l->n = l->cap = 0;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/* Snapshot for a firing pass: entries retained; `once` entries leave the
|
|
274
|
+
* LIVE list before their callback runs. */
|
|
275
|
+
static size_t scr_dgram_ls_snapshot(ScrDgramLs *l, ScrDgramL **out) {
|
|
276
|
+
size_t n = l->n;
|
|
277
|
+
if (n == 0) {
|
|
278
|
+
*out = NULL;
|
|
279
|
+
return 0;
|
|
280
|
+
}
|
|
281
|
+
ScrDgramL *snap = malloc(n * sizeof *snap);
|
|
282
|
+
if (!snap) scr_dgram_oom();
|
|
283
|
+
for (size_t i = 0; i < n; i++) {
|
|
284
|
+
snap[i] = l->ls[i];
|
|
285
|
+
scr_closure_retain(snap[i].cb);
|
|
286
|
+
}
|
|
287
|
+
size_t w = 0;
|
|
288
|
+
for (size_t i = 0; i < l->n; i++) {
|
|
289
|
+
if (l->ls[i].once) {
|
|
290
|
+
scr_closure_release(l->ls[i].cb);
|
|
291
|
+
} else {
|
|
292
|
+
l->ls[w++] = l->ls[i];
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
l->n = w;
|
|
296
|
+
*out = snap;
|
|
297
|
+
return n;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
static void scr_dgram_fire0(ScrDgramLs *l) {
|
|
301
|
+
ScrDgramL *snap;
|
|
302
|
+
size_t n = scr_dgram_ls_snapshot(l, &snap);
|
|
303
|
+
for (size_t i = 0; i < n; i++) {
|
|
304
|
+
if (!scr_exc_pending()) ((void (*)(ScrClosure *))snap[i].cb->fn)(snap[i].cb);
|
|
305
|
+
scr_closure_release(snap[i].cb);
|
|
306
|
+
}
|
|
307
|
+
free(snap);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* 'error' with NO listener is fatal, like Node's unhandled EventEmitter
|
|
311
|
+
* 'error' (the scr_net.c stance — _Exit skips atexit on purpose). */
|
|
312
|
+
static void scr_dgram_fire_err(ScrDgramLs *l, ScrStr *msg) {
|
|
313
|
+
if (l->n == 0) {
|
|
314
|
+
fflush(stdout);
|
|
315
|
+
fprintf(stderr, "Unhandled 'error' event: Error: %s\n", msg->data);
|
|
316
|
+
_Exit(1);
|
|
317
|
+
}
|
|
318
|
+
ScrDgramL *snap;
|
|
319
|
+
size_t n = scr_dgram_ls_snapshot(l, &snap);
|
|
320
|
+
for (size_t i = 0; i < n; i++) {
|
|
321
|
+
if (!scr_exc_pending()) ((ScrChildErrFn)snap[i].fn)(snap[i].cb, msg);
|
|
322
|
+
scr_closure_release(snap[i].cb);
|
|
323
|
+
}
|
|
324
|
+
free(snap);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* ── the handle ──────────────────────────────────────────────────────── */
|
|
328
|
+
|
|
329
|
+
struct ScrDgramSocket {
|
|
330
|
+
size_t rc;
|
|
331
|
+
int fd; /* -1 until bound/connected, -1 again once closed */
|
|
332
|
+
bool reuse_addr;
|
|
333
|
+
bool bound;
|
|
334
|
+
bool connected;
|
|
335
|
+
bool closing; /* close() called; 'close' fires at the next sweep */
|
|
336
|
+
bool close_emitted; /* settled: off the registry, listeners dropped */
|
|
337
|
+
bool unrefed; /* waives loop liveness, Node's unref */
|
|
338
|
+
bool read_armed;
|
|
339
|
+
bool emit_listening;
|
|
340
|
+
bool emit_connect;
|
|
341
|
+
ScrStr *pending_err; /* deferred bind/connect/send failure */
|
|
342
|
+
ScrDgramLs msg_ls, err_ls, listening_ls, close_ls, conn_ls;
|
|
343
|
+
bool in_registry;
|
|
344
|
+
struct ScrDgramSocket *next;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
#ifdef SCR_RC_AUDIT
|
|
348
|
+
static long scr_dgram_live = 0;
|
|
349
|
+
long scr_dgram_live_count(void) { return scr_dgram_live; }
|
|
350
|
+
#endif
|
|
351
|
+
|
|
352
|
+
static ScrDgramSocket *scr_dgram_socks = NULL; /* registry: +1 each, tail-appended */
|
|
353
|
+
static ScrPoller *scr_dgram_poller = NULL;
|
|
354
|
+
|
|
355
|
+
/* Pending dns.lookup deliveries (already resolved — getaddrinfo ran at
|
|
356
|
+
* the call; the sweep fires them FIFO). */
|
|
357
|
+
typedef struct ScrDnsPending {
|
|
358
|
+
ScrClosure *cb; /* +1 */
|
|
359
|
+
ScrDnsLookupFn fn;
|
|
360
|
+
ScrStr *errmsg; /* +1 or NULL (success) */
|
|
361
|
+
ScrStr *addr; /* +1 ("" on failure) */
|
|
362
|
+
double family;
|
|
363
|
+
struct ScrDnsPending *next;
|
|
364
|
+
} ScrDnsPending;
|
|
365
|
+
|
|
366
|
+
static ScrDnsPending *scr_dns_pending = NULL;
|
|
367
|
+
|
|
368
|
+
/* ── RC ──────────────────────────────────────────────────────────────── */
|
|
369
|
+
|
|
370
|
+
static void scr_dgram_close_fd_raw(int fd); /* forget-then-close, defined below */
|
|
371
|
+
|
|
372
|
+
ScrDgramSocket *scr_dgram_retain(ScrDgramSocket *s) {
|
|
373
|
+
if (s->rc != SIZE_MAX) s->rc++;
|
|
374
|
+
return s;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
void scr_dgram_release(ScrDgramSocket *s) {
|
|
378
|
+
if (!s || s->rc == SIZE_MAX) return;
|
|
379
|
+
if (--s->rc == 0) {
|
|
380
|
+
scr_dgram_ls_drop(&s->msg_ls);
|
|
381
|
+
scr_dgram_ls_drop(&s->err_ls);
|
|
382
|
+
scr_dgram_ls_drop(&s->listening_ls);
|
|
383
|
+
scr_dgram_ls_drop(&s->close_ls);
|
|
384
|
+
scr_dgram_ls_drop(&s->conn_ls);
|
|
385
|
+
scr_str_release(s->pending_err);
|
|
386
|
+
if (s->fd >= 0) scr_dgram_close_fd_raw(s->fd);
|
|
387
|
+
#ifdef SCR_RC_AUDIT
|
|
388
|
+
scr_dgram_live--;
|
|
389
|
+
#endif
|
|
390
|
+
free(s);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
void *scr_dgram_retain_v(void *p) { return scr_dgram_retain((ScrDgramSocket *)p); }
|
|
395
|
+
void scr_dgram_release_v(void *p) { scr_dgram_release((ScrDgramSocket *)p); }
|
|
396
|
+
|
|
397
|
+
/* ── poller plumbing (the scr_platform.h seam; read-only subset) ─────── */
|
|
398
|
+
|
|
399
|
+
static bool scr_dgram_poller_init(void) {
|
|
400
|
+
if (scr_dgram_poller != NULL) return true;
|
|
401
|
+
scr_dgram_poller = scrp_poller_new();
|
|
402
|
+
return scr_dgram_poller != NULL;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/* Registration failures ignored exactly as kevent's always were. */
|
|
406
|
+
static void scr_dgram_watch_read(int fd, void *udata, bool on) {
|
|
407
|
+
if (scr_dgram_poller == NULL || fd < 0) return;
|
|
408
|
+
(void)scrp_watch_read(scr_dgram_poller, fd, udata, on);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/* Forget-then-close — the epoll obligation (scr_platform.h); the kqueue
|
|
412
|
+
* backend's forget is a no-op, so macOS keeps its historical sequence. */
|
|
413
|
+
static void scr_dgram_close_fd_raw(int fd) {
|
|
414
|
+
if (fd < 0) return;
|
|
415
|
+
if (scr_dgram_poller != NULL) scrp_forget(scr_dgram_poller, fd);
|
|
416
|
+
close(fd);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/* Consumer-driven read arming (the net-socket discipline). */
|
|
420
|
+
static void scr_dgram_update_read(ScrDgramSocket *s) {
|
|
421
|
+
bool want = s->fd >= 0 && s->msg_ls.n > 0;
|
|
422
|
+
if (want && !s->read_armed) {
|
|
423
|
+
scr_dgram_watch_read(s->fd, s, true);
|
|
424
|
+
s->read_armed = true;
|
|
425
|
+
} else if (!want && s->read_armed) {
|
|
426
|
+
scr_dgram_watch_read(s->fd, s, false);
|
|
427
|
+
s->read_armed = false;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/* ── registry ────────────────────────────────────────────────────────── */
|
|
432
|
+
|
|
433
|
+
static void scr_dgram_register(ScrDgramSocket *s) {
|
|
434
|
+
if (s->in_registry) return;
|
|
435
|
+
s->in_registry = true;
|
|
436
|
+
s->next = NULL;
|
|
437
|
+
ScrDgramSocket **link = &scr_dgram_socks;
|
|
438
|
+
while (*link) link = &(*link)->next;
|
|
439
|
+
*link = scr_dgram_retain(s);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
static void scr_dgram_unregister(ScrDgramSocket *s) {
|
|
443
|
+
if (!s->in_registry) return;
|
|
444
|
+
ScrDgramSocket **link = &scr_dgram_socks;
|
|
445
|
+
while (*link && *link != s) link = &(*link)->next;
|
|
446
|
+
if (*link) {
|
|
447
|
+
*link = s->next;
|
|
448
|
+
s->next = NULL;
|
|
449
|
+
s->in_registry = false;
|
|
450
|
+
scr_dgram_release(s);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/* ── the surface ─────────────────────────────────────────────────────── */
|
|
455
|
+
|
|
456
|
+
ScrDgramSocket *scr_dgram_create(bool reuse_addr) {
|
|
457
|
+
ScrDgramSocket *s = calloc(1, sizeof *s);
|
|
458
|
+
if (!s) scr_dgram_oom();
|
|
459
|
+
s->rc = 1;
|
|
460
|
+
s->fd = -1;
|
|
461
|
+
s->reuse_addr = reuse_addr;
|
|
462
|
+
#ifdef SCR_RC_AUDIT
|
|
463
|
+
scr_dgram_live++;
|
|
464
|
+
#endif
|
|
465
|
+
return s;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
static void scr_dgram_throw(const char *msg) {
|
|
469
|
+
scr_throw_error_msg(0 /* Error */, msg, strlen(msg));
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/* Resolve a numeric host into a sockaddr_in; "" means any (bind's
|
|
473
|
+
* default), "localhost" pins to 127.0.0.1 (the net stance). False for
|
|
474
|
+
* non-numeric hosts — the caller defers Node's ENOTFOUND. */
|
|
475
|
+
static bool scr_dgram_host4(const char *host, uint16_t port, struct sockaddr_in *out) {
|
|
476
|
+
memset(out, 0, sizeof *out);
|
|
477
|
+
out->sin_family = AF_INET;
|
|
478
|
+
out->sin_port = htons(port);
|
|
479
|
+
if (host[0] == '\0') {
|
|
480
|
+
out->sin_addr.s_addr = INADDR_ANY;
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
if (strcmp(host, "localhost") == 0) host = "127.0.0.1";
|
|
484
|
+
return inet_pton(AF_INET, host, &out->sin_addr) == 1;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/* Create the fd (idempotent). Aborts only on resource exhaustion, the
|
|
488
|
+
* scr_net.c socket() stance. */
|
|
489
|
+
static void scr_dgram_ensure_fd(ScrDgramSocket *s) {
|
|
490
|
+
if (s->fd >= 0) return;
|
|
491
|
+
if (!scr_dgram_poller_init()) {
|
|
492
|
+
fputs("scriptc: event poller init failed\n", stderr);
|
|
493
|
+
abort();
|
|
494
|
+
}
|
|
495
|
+
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
496
|
+
if (fd < 0) {
|
|
497
|
+
fputs("scriptc: socket() failed\n", stderr);
|
|
498
|
+
abort();
|
|
499
|
+
}
|
|
500
|
+
scr_dgram_nonblock(fd);
|
|
501
|
+
if (s->reuse_addr) {
|
|
502
|
+
int one = 1;
|
|
503
|
+
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
|
|
504
|
+
}
|
|
505
|
+
s->fd = fd;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
static void scr_dgram_defer_err(ScrDgramSocket *s, const char *msg) {
|
|
509
|
+
if (!s->pending_err) s->pending_err = scr_str_new(msg, strlen(msg));
|
|
510
|
+
scr_dgram_register(s); /* the sweep delivers it */
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/* bind(port, host): binds NOW; 'listening' (and the bind callback) defer
|
|
514
|
+
* to the next dispatch pass. State errors throw synchronously, runtime
|
|
515
|
+
* failures defer to 'error' — both Node's split. */
|
|
516
|
+
void scr_dgram_bind(ScrDgramSocket *s, double port, ScrStr *host, ScrClosure *cb) {
|
|
517
|
+
if (s->closing || s->close_emitted) {
|
|
518
|
+
scr_closure_release(cb);
|
|
519
|
+
scr_dgram_throw("Not running");
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
if (s->bound) {
|
|
523
|
+
scr_closure_release(cb);
|
|
524
|
+
scr_dgram_throw("Socket is already bound");
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
if (cb) scr_dgram_ls_add(&s->listening_ls, cb, NULL, true);
|
|
528
|
+
struct sockaddr_in a4;
|
|
529
|
+
if (!scr_dgram_host4(host->data, (uint16_t)(int)port, &a4)) {
|
|
530
|
+
char msg[160];
|
|
531
|
+
snprintf(msg, sizeof msg, "getaddrinfo ENOTFOUND %s", host->data);
|
|
532
|
+
scr_dgram_defer_err(s, msg);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
scr_dgram_ensure_fd(s);
|
|
536
|
+
if (bind(s->fd, (struct sockaddr *)&a4, sizeof a4) != 0) {
|
|
537
|
+
int err = errno;
|
|
538
|
+
char ip[64];
|
|
539
|
+
inet_ntop(AF_INET, &a4.sin_addr, ip, sizeof ip);
|
|
540
|
+
char msg[128];
|
|
541
|
+
/* Node: "bind EADDRINUSE 0.0.0.0:4000" */
|
|
542
|
+
snprintf(msg, sizeof msg, "bind %s %s:%d", scr_dgram_errname(err), ip, (int)port);
|
|
543
|
+
close(s->fd); /* never watched: bind precedes any read arm */
|
|
544
|
+
s->fd = -1;
|
|
545
|
+
scr_dgram_defer_err(s, msg);
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
s->bound = true;
|
|
549
|
+
s->emit_listening = true;
|
|
550
|
+
scr_dgram_register(s);
|
|
551
|
+
scr_dgram_update_read(s);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/* connect(port, host): implicit-binds (Node emits 'listening' for that,
|
|
555
|
+
* then 'connect'); UDP connect(2) is local and immediate, so failures
|
|
556
|
+
* here are deferred 'error's only for bad hosts. */
|
|
557
|
+
void scr_dgram_connect(ScrDgramSocket *s, double port, ScrStr *host, ScrClosure *cb) {
|
|
558
|
+
if (s->closing || s->close_emitted) {
|
|
559
|
+
scr_closure_release(cb);
|
|
560
|
+
scr_dgram_throw("Not running");
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
if (s->connected) {
|
|
564
|
+
scr_closure_release(cb);
|
|
565
|
+
scr_dgram_throw("Already connected");
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
if (cb) scr_dgram_ls_add(&s->conn_ls, cb, NULL, true);
|
|
569
|
+
struct sockaddr_in a4;
|
|
570
|
+
if (!scr_dgram_host4(host->data, (uint16_t)(int)port, &a4) || host->len == 0) {
|
|
571
|
+
char msg[160];
|
|
572
|
+
snprintf(msg, sizeof msg, "getaddrinfo ENOTFOUND %s", host->data);
|
|
573
|
+
scr_dgram_defer_err(s, msg);
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
scr_dgram_ensure_fd(s);
|
|
577
|
+
if (!s->bound) {
|
|
578
|
+
s->bound = true;
|
|
579
|
+
s->emit_listening = true; /* Node's implicit bind emits 'listening' */
|
|
580
|
+
}
|
|
581
|
+
if (connect(s->fd, (struct sockaddr *)&a4, sizeof a4) != 0) {
|
|
582
|
+
char msg[128];
|
|
583
|
+
char ip[64];
|
|
584
|
+
inet_ntop(AF_INET, &a4.sin_addr, ip, sizeof ip);
|
|
585
|
+
snprintf(msg, sizeof msg, "connect %s %s:%d", scr_dgram_errname(errno), ip, (int)port);
|
|
586
|
+
scr_dgram_defer_err(s, msg);
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
s->connected = true;
|
|
590
|
+
s->emit_connect = true;
|
|
591
|
+
scr_dgram_register(s);
|
|
592
|
+
scr_dgram_update_read(s);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
static void scr_dgram_send_raw(ScrDgramSocket *s, const char *data, size_t len, double port,
|
|
596
|
+
ScrStr *host) {
|
|
597
|
+
if (s->closing || s->close_emitted) {
|
|
598
|
+
scr_dgram_throw("Not running");
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
if (s->connected) {
|
|
602
|
+
scr_dgram_throw("Already connected");
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
struct sockaddr_in a4;
|
|
606
|
+
if (!scr_dgram_host4(host->data, (uint16_t)(int)port, &a4) || host->len == 0) {
|
|
607
|
+
char msg[160];
|
|
608
|
+
snprintf(msg, sizeof msg, "getaddrinfo ENOTFOUND %s", host->data);
|
|
609
|
+
scr_dgram_defer_err(s, msg);
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
scr_dgram_ensure_fd(s);
|
|
613
|
+
if (!s->bound) {
|
|
614
|
+
/* Implicit ephemeral bind — Node's send-before-bind, 'listening'
|
|
615
|
+
* emits for it there too. */
|
|
616
|
+
s->bound = true;
|
|
617
|
+
s->emit_listening = true;
|
|
618
|
+
}
|
|
619
|
+
scr_dgram_register(s); /* an open sender holds the loop, like Node */
|
|
620
|
+
if (sendto(s->fd, data, len, 0, (struct sockaddr *)&a4, sizeof a4) < 0 &&
|
|
621
|
+
errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) {
|
|
622
|
+
char ip[64];
|
|
623
|
+
inet_ntop(AF_INET, &a4.sin_addr, ip, sizeof ip);
|
|
624
|
+
char msg[128];
|
|
625
|
+
snprintf(msg, sizeof msg, "send %s %s:%d", scr_dgram_errname(errno), ip, (int)port);
|
|
626
|
+
scr_dgram_defer_err(s, msg);
|
|
627
|
+
}
|
|
628
|
+
scr_dgram_update_read(s);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
void scr_dgram_send_str(ScrDgramSocket *s, ScrStr *data, double port, ScrStr *host) {
|
|
632
|
+
scr_dgram_send_raw(s, data->data, data->len, port, host);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
void scr_dgram_send_bytes(ScrDgramSocket *s, ScrBytes *data, double port, ScrStr *host) {
|
|
636
|
+
scr_dgram_send_raw(s, (const char *)data->data, data->len, port, host);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/* address() parts. The ip read carries the "Not running" throw; family
|
|
640
|
+
* and port only run after it succeeded. */
|
|
641
|
+
ScrStr *scr_dgram_addr_ip(ScrDgramSocket *s) {
|
|
642
|
+
if (s->fd < 0 || !s->bound) {
|
|
643
|
+
scr_dgram_throw("Not running");
|
|
644
|
+
return NULL;
|
|
645
|
+
}
|
|
646
|
+
struct sockaddr_storage sa;
|
|
647
|
+
socklen_t salen = sizeof sa;
|
|
648
|
+
char ip[64] = "0.0.0.0";
|
|
649
|
+
if (getsockname(s->fd, (struct sockaddr *)&sa, &salen) == 0 && sa.ss_family == AF_INET) {
|
|
650
|
+
inet_ntop(AF_INET, &((struct sockaddr_in *)&sa)->sin_addr, ip, sizeof ip);
|
|
651
|
+
}
|
|
652
|
+
return scr_str_new(ip, strlen(ip));
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
ScrStr *scr_dgram_addr_family(ScrDgramSocket *s) {
|
|
656
|
+
(void)s; /* udp4 is the one lowered type */
|
|
657
|
+
return scr_str_new("IPv4", 4);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
double scr_dgram_addr_port(ScrDgramSocket *s) {
|
|
661
|
+
struct sockaddr_storage sa;
|
|
662
|
+
socklen_t salen = sizeof sa;
|
|
663
|
+
if (s->fd >= 0 && getsockname(s->fd, (struct sockaddr *)&sa, &salen) == 0 &&
|
|
664
|
+
sa.ss_family == AF_INET) {
|
|
665
|
+
return (double)ntohs(((struct sockaddr_in *)&sa)->sin_port);
|
|
666
|
+
}
|
|
667
|
+
return 0;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/* close([cb]): the fd closes NOW; 'close' (and the callback, registered
|
|
671
|
+
* as once('close')) fires at the next sweep. Node throws "Not running"
|
|
672
|
+
* on a second close. */
|
|
673
|
+
void scr_dgram_close(ScrDgramSocket *s, ScrClosure *cb) {
|
|
674
|
+
if (s->closing || s->close_emitted) {
|
|
675
|
+
scr_closure_release(cb);
|
|
676
|
+
scr_dgram_throw("Not running");
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
if (cb) scr_dgram_ls_add(&s->close_ls, cb, NULL, true);
|
|
680
|
+
if (s->fd >= 0) {
|
|
681
|
+
scr_dgram_close_fd_raw(s->fd); /* registrations dropped, then the fd */
|
|
682
|
+
s->fd = -1;
|
|
683
|
+
s->read_armed = false;
|
|
684
|
+
}
|
|
685
|
+
s->closing = true;
|
|
686
|
+
/* Move to the registry TAIL so 'close' emits in close() CALL order
|
|
687
|
+
* (Node's per-close scheduled emit), not socket-creation order. The
|
|
688
|
+
* caller's borrowed reference keeps the handle alive across the
|
|
689
|
+
* unregister/register pair. */
|
|
690
|
+
scr_dgram_unregister(s);
|
|
691
|
+
scr_dgram_register(s); /* the sweep fires 'close' and settles */
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
void scr_dgram_unref(ScrDgramSocket *s) { s->unrefed = true; }
|
|
695
|
+
void scr_dgram_ref(ScrDgramSocket *s) { s->unrefed = false; }
|
|
696
|
+
|
|
697
|
+
void scr_dgram_on_message(ScrDgramSocket *s, ScrClosure *cb, ScrDgramMsgFn fn, bool once) {
|
|
698
|
+
if (s->close_emitted) {
|
|
699
|
+
scr_closure_release(cb);
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
scr_dgram_ls_add(&s->msg_ls, cb, (void *)fn, once);
|
|
703
|
+
scr_dgram_update_read(s);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
void scr_dgram_on_error(ScrDgramSocket *s, ScrClosure *cb, ScrChildErrFn fn, bool once) {
|
|
707
|
+
if (s->close_emitted) {
|
|
708
|
+
scr_closure_release(cb);
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
scr_dgram_ls_add(&s->err_ls, cb, (void *)fn, once);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
void scr_dgram_on_listening(ScrDgramSocket *s, ScrClosure *cb, bool once) {
|
|
715
|
+
if (s->close_emitted) {
|
|
716
|
+
scr_closure_release(cb);
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
scr_dgram_ls_add(&s->listening_ls, cb, NULL, once);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
void scr_dgram_on_close(ScrDgramSocket *s, ScrClosure *cb, bool once) {
|
|
723
|
+
if (s->close_emitted) {
|
|
724
|
+
scr_closure_release(cb);
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
scr_dgram_ls_add(&s->close_ls, cb, NULL, once);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
void scr_dgram_on_connect(ScrDgramSocket *s, ScrClosure *cb, bool once) {
|
|
731
|
+
if (s->close_emitted) {
|
|
732
|
+
scr_closure_release(cb);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
scr_dgram_ls_add(&s->conn_ls, cb, NULL, once);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/* The runtime-provided message adapters (msg/rinfo parts borrowed; the
|
|
739
|
+
* listener owns its +1 params per the universal convention). */
|
|
740
|
+
void scr_dgram_msg_thunk0(ScrClosure *cb, ScrBytes *msg, ScrStr *addr, ScrStr *family,
|
|
741
|
+
double port, double size) {
|
|
742
|
+
(void)msg; (void)addr; (void)family; (void)port; (void)size;
|
|
743
|
+
((void (*)(ScrClosure *))cb->fn)(cb);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
void scr_dgram_msg_thunk1(ScrClosure *cb, ScrBytes *msg, ScrStr *addr, ScrStr *family,
|
|
747
|
+
double port, double size) {
|
|
748
|
+
(void)addr; (void)family; (void)port; (void)size;
|
|
749
|
+
((void (*)(ScrClosure *, ScrBytes *))cb->fn)(cb, scr_bytes_retain(msg));
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/* One readable wake: recvfrom until EAGAIN, one 'message' emit per
|
|
753
|
+
* datagram (arrival-driven, like net's read chunks). */
|
|
754
|
+
static void scr_dgram_read(ScrDgramSocket *s) {
|
|
755
|
+
while (s->fd >= 0 && s->msg_ls.n > 0) {
|
|
756
|
+
char buf[65536];
|
|
757
|
+
struct sockaddr_storage from;
|
|
758
|
+
socklen_t fromlen = sizeof from;
|
|
759
|
+
ssize_t n = recvfrom(s->fd, buf, sizeof buf, 0, (struct sockaddr *)&from, &fromlen);
|
|
760
|
+
if (n < 0) {
|
|
761
|
+
if (errno == EINTR) continue;
|
|
762
|
+
return; /* EAGAIN or a transient failure: the next wake retries */
|
|
763
|
+
}
|
|
764
|
+
char ip[64] = "0.0.0.0";
|
|
765
|
+
int rport = 0;
|
|
766
|
+
if (from.ss_family == AF_INET) {
|
|
767
|
+
inet_ntop(AF_INET, &((struct sockaddr_in *)&from)->sin_addr, ip, sizeof ip);
|
|
768
|
+
rport = ntohs(((struct sockaddr_in *)&from)->sin_port);
|
|
769
|
+
}
|
|
770
|
+
ScrBytes *chunk = scr_bytes_new(SCR_BYTES_U8, (double)n);
|
|
771
|
+
memcpy(chunk->data, buf, (size_t)n);
|
|
772
|
+
ScrStr *addr = scr_str_new(ip, strlen(ip));
|
|
773
|
+
ScrStr *family = scr_str_new("IPv4", 4);
|
|
774
|
+
ScrDgramL *snap;
|
|
775
|
+
size_t nl = scr_dgram_ls_snapshot(&s->msg_ls, &snap);
|
|
776
|
+
for (size_t i = 0; i < nl; i++) {
|
|
777
|
+
if (!scr_exc_pending()) {
|
|
778
|
+
((ScrDgramMsgFn)snap[i].fn)(snap[i].cb, chunk, addr, family, (double)rport, (double)n);
|
|
779
|
+
}
|
|
780
|
+
scr_closure_release(snap[i].cb);
|
|
781
|
+
}
|
|
782
|
+
free(snap);
|
|
783
|
+
scr_bytes_release(chunk);
|
|
784
|
+
scr_str_release(addr);
|
|
785
|
+
scr_str_release(family);
|
|
786
|
+
if (scr_exc_pending()) return;
|
|
787
|
+
scr_dgram_update_read(s); /* a once-listener may have been the last consumer */
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/* ── dns.lookup ──────────────────────────────────────────────────────── */
|
|
792
|
+
|
|
793
|
+
void scr_dns_lookup(ScrStr *hostname, double family, ScrClosure *cb, ScrDnsLookupFn fn) {
|
|
794
|
+
(void)family; /* the frontend pinned 4; AF_INET below IS that pin */
|
|
795
|
+
#ifdef _WIN32
|
|
796
|
+
/* getaddrinfo needs winsock started (WSANOTINITIALISED otherwise); the
|
|
797
|
+
* poller owns WSAStartup on this arm, so a lookup-only program rides
|
|
798
|
+
* the same init the socket paths do. */
|
|
799
|
+
(void)scr_dgram_poller_init();
|
|
800
|
+
#endif
|
|
801
|
+
ScrDnsPending *p = calloc(1, sizeof *p);
|
|
802
|
+
if (!p) scr_dgram_oom();
|
|
803
|
+
p->cb = cb; /* moves */
|
|
804
|
+
p->fn = fn;
|
|
805
|
+
p->family = 4;
|
|
806
|
+
struct addrinfo hints;
|
|
807
|
+
memset(&hints, 0, sizeof hints);
|
|
808
|
+
hints.ai_family = AF_INET;
|
|
809
|
+
hints.ai_socktype = SOCK_DGRAM;
|
|
810
|
+
struct addrinfo *res = NULL;
|
|
811
|
+
int rc = getaddrinfo(hostname->data, NULL, &hints, &res);
|
|
812
|
+
if (rc == 0 && res) {
|
|
813
|
+
char ip[64] = "0.0.0.0";
|
|
814
|
+
inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, ip, sizeof ip);
|
|
815
|
+
p->addr = scr_str_new(ip, strlen(ip));
|
|
816
|
+
} else {
|
|
817
|
+
/* Node maps name-not-found (and macOS's EAI_NODATA) to ENOTFOUND;
|
|
818
|
+
* everything else surfaces its EAI_* name. Message shape:
|
|
819
|
+
* "getaddrinfo ENOTFOUND <hostname>". */
|
|
820
|
+
const char *code =
|
|
821
|
+
(rc == EAI_NONAME
|
|
822
|
+
#ifdef EAI_NODATA
|
|
823
|
+
|| rc == EAI_NODATA
|
|
824
|
+
#endif
|
|
825
|
+
)
|
|
826
|
+
? "ENOTFOUND"
|
|
827
|
+
: rc == EAI_AGAIN ? "EAI_AGAIN"
|
|
828
|
+
: "EAI_FAIL";
|
|
829
|
+
char msg[192];
|
|
830
|
+
snprintf(msg, sizeof msg, "getaddrinfo %s %s", code, hostname->data);
|
|
831
|
+
p->errmsg = scr_str_new(msg, strlen(msg));
|
|
832
|
+
p->addr = scr_str_new("", 0);
|
|
833
|
+
}
|
|
834
|
+
if (res) freeaddrinfo(res);
|
|
835
|
+
/* FIFO append: deliveries fire in call order at the next sweep. */
|
|
836
|
+
ScrDnsPending **link = &scr_dns_pending;
|
|
837
|
+
while (*link) link = &(*link)->next;
|
|
838
|
+
*link = p;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
void scr_dns_thunk0(ScrClosure *cb, ScrStr *errmsg, ScrStr *addr, double family) {
|
|
842
|
+
(void)errmsg; (void)addr; (void)family;
|
|
843
|
+
((void (*)(ScrClosure *))cb->fn)(cb);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/* ── the sweep: deferred emits ───────────────────────────────────────── */
|
|
847
|
+
|
|
848
|
+
static bool scr_dgram_flags_pending(void) {
|
|
849
|
+
if (scr_dns_pending) return true;
|
|
850
|
+
for (ScrDgramSocket *s = scr_dgram_socks; s; s = s->next) {
|
|
851
|
+
if (s->pending_err || s->emit_listening || s->emit_connect) return true;
|
|
852
|
+
if (s->closing && !s->close_emitted) return true;
|
|
853
|
+
}
|
|
854
|
+
return false;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
static void scr_dgram_sweep(void) {
|
|
858
|
+
ScrDgramSocket *s = scr_dgram_socks;
|
|
859
|
+
while (s) {
|
|
860
|
+
ScrDgramSocket *next = s->next; /* may unregister below */
|
|
861
|
+
scr_dgram_retain(s); /* callbacks may drop every other ref */
|
|
862
|
+
if (s->emit_listening) {
|
|
863
|
+
s->emit_listening = false;
|
|
864
|
+
scr_dgram_fire0(&s->listening_ls);
|
|
865
|
+
if (scr_exc_pending()) {
|
|
866
|
+
scr_dgram_release(s);
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
if (s->emit_connect) {
|
|
871
|
+
s->emit_connect = false;
|
|
872
|
+
scr_dgram_fire0(&s->conn_ls);
|
|
873
|
+
if (scr_exc_pending()) {
|
|
874
|
+
scr_dgram_release(s);
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
if (s->pending_err) {
|
|
879
|
+
ScrStr *msg = s->pending_err;
|
|
880
|
+
s->pending_err = NULL;
|
|
881
|
+
scr_dgram_fire_err(&s->err_ls, msg);
|
|
882
|
+
scr_str_release(msg);
|
|
883
|
+
if (scr_exc_pending()) {
|
|
884
|
+
scr_dgram_release(s);
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
/* A failed bind/connect/send on a never-opened socket leaves it
|
|
888
|
+
* inert: if nothing keeps it live (not bound, not closing), settle
|
|
889
|
+
* it off the registry so the loop can drain — pre-failure
|
|
890
|
+
* listeners drop, the net failed-listen stance. */
|
|
891
|
+
if (s->fd < 0 && !s->closing && !s->close_emitted) {
|
|
892
|
+
s->close_emitted = true;
|
|
893
|
+
scr_dgram_ls_drop(&s->msg_ls);
|
|
894
|
+
scr_dgram_ls_drop(&s->err_ls);
|
|
895
|
+
scr_dgram_ls_drop(&s->listening_ls);
|
|
896
|
+
scr_dgram_ls_drop(&s->close_ls);
|
|
897
|
+
scr_dgram_ls_drop(&s->conn_ls);
|
|
898
|
+
scr_dgram_unregister(s);
|
|
899
|
+
if (scr_exc_pending()) {
|
|
900
|
+
scr_dgram_release(s);
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
if (s->closing && !s->close_emitted) {
|
|
906
|
+
s->close_emitted = true;
|
|
907
|
+
scr_dgram_fire0(&s->close_ls);
|
|
908
|
+
/* settle: listeners drop (the cycle story), off the registry */
|
|
909
|
+
scr_dgram_ls_drop(&s->msg_ls);
|
|
910
|
+
scr_dgram_ls_drop(&s->err_ls);
|
|
911
|
+
scr_dgram_ls_drop(&s->listening_ls);
|
|
912
|
+
scr_dgram_ls_drop(&s->close_ls);
|
|
913
|
+
scr_dgram_ls_drop(&s->conn_ls);
|
|
914
|
+
scr_dgram_unregister(s);
|
|
915
|
+
if (scr_exc_pending()) {
|
|
916
|
+
scr_dgram_release(s);
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
scr_dgram_release(s);
|
|
921
|
+
s = next;
|
|
922
|
+
}
|
|
923
|
+
/* dns deliveries AFTER the socket emits: Node's numeric/nextTick-ish
|
|
924
|
+
* bind emits land before a threadpool lookup's completion — the
|
|
925
|
+
* observed interleave the differential fixtures pin. */
|
|
926
|
+
while (scr_dns_pending) {
|
|
927
|
+
ScrDnsPending *p = scr_dns_pending;
|
|
928
|
+
scr_dns_pending = p->next;
|
|
929
|
+
if (!scr_exc_pending()) p->fn(p->cb, p->errmsg, p->addr, p->family);
|
|
930
|
+
scr_closure_release(p->cb);
|
|
931
|
+
scr_str_release(p->errmsg);
|
|
932
|
+
scr_str_release(p->addr);
|
|
933
|
+
free(p);
|
|
934
|
+
if (scr_exc_pending()) return;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/* ── the loop hooks (scr_async.c) ────────────────────────────────────── */
|
|
939
|
+
|
|
940
|
+
static bool scr_dgram_pending(void) {
|
|
941
|
+
if (scr_dns_pending) return true;
|
|
942
|
+
for (ScrDgramSocket *s = scr_dgram_socks; s; s = s->next) {
|
|
943
|
+
/* Undelivered emits hold the loop even on an unref'd socket (they
|
|
944
|
+
* are due NOW); otherwise an open registered socket holds it unless
|
|
945
|
+
* unref() waived that — Node's unref semantics. */
|
|
946
|
+
if (s->pending_err || s->emit_listening || s->emit_connect ||
|
|
947
|
+
(s->closing && !s->close_emitted)) {
|
|
948
|
+
return true;
|
|
949
|
+
}
|
|
950
|
+
if (!s->unrefed) return true;
|
|
951
|
+
}
|
|
952
|
+
return false;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
static int scr_dgram_pollfd(void) {
|
|
956
|
+
return scr_dgram_poller != NULL ? scrp_poller_fd(scr_dgram_poller) : -1;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
static void scr_dgram_dispatch(void) {
|
|
960
|
+
if (!scr_dgram_socks && !scr_dns_pending) return;
|
|
961
|
+
for (;;) {
|
|
962
|
+
scr_dgram_sweep();
|
|
963
|
+
if (scr_exc_pending()) return;
|
|
964
|
+
if (scr_dgram_poller == NULL) return;
|
|
965
|
+
ScrPollerEvent evs[64];
|
|
966
|
+
int n = scrp_drain(scr_dgram_poller, evs, 64);
|
|
967
|
+
for (int i = 0; i < n; i++) {
|
|
968
|
+
ScrDgramSocket *s = (ScrDgramSocket *)evs[i].udata;
|
|
969
|
+
if (!s || s->fd < 0) continue; /* closed earlier in this batch */
|
|
970
|
+
scr_dgram_read(s);
|
|
971
|
+
if (scr_exc_pending()) return;
|
|
972
|
+
}
|
|
973
|
+
if (!scr_dgram_flags_pending()) return;
|
|
974
|
+
if (scr_loop_has_ready()) return; /* microtasks interleave first */
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/* Exit-time registry cleanup (the scr_net.c precedent): sockets a
|
|
979
|
+
* program legitimately leaves live at exit release their listeners and
|
|
980
|
+
* registry references so the RC audit sees a clean heap. */
|
|
981
|
+
static void scr_dgram_cleanup_atexit(void) {
|
|
982
|
+
while (scr_dgram_socks) {
|
|
983
|
+
ScrDgramSocket *s = scr_dgram_socks;
|
|
984
|
+
scr_dgram_ls_drop(&s->msg_ls);
|
|
985
|
+
scr_dgram_ls_drop(&s->err_ls);
|
|
986
|
+
scr_dgram_ls_drop(&s->listening_ls);
|
|
987
|
+
scr_dgram_ls_drop(&s->close_ls);
|
|
988
|
+
scr_dgram_ls_drop(&s->conn_ls);
|
|
989
|
+
scr_dgram_unregister(s);
|
|
990
|
+
}
|
|
991
|
+
while (scr_dns_pending) {
|
|
992
|
+
ScrDnsPending *p = scr_dns_pending;
|
|
993
|
+
scr_dns_pending = p->next;
|
|
994
|
+
scr_closure_release(p->cb);
|
|
995
|
+
scr_str_release(p->errmsg);
|
|
996
|
+
scr_str_release(p->addr);
|
|
997
|
+
free(p);
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
void scr_dgram_install(void) {
|
|
1002
|
+
static bool installed = false;
|
|
1003
|
+
if (installed) return;
|
|
1004
|
+
installed = true;
|
|
1005
|
+
atexit(scr_dgram_cleanup_atexit);
|
|
1006
|
+
scr_loop_set_dgram(&scr_dgram_pending, &scr_dgram_dispatch, &scr_dgram_pollfd);
|
|
1007
|
+
}
|