@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_events.c
ADDED
|
@@ -0,0 +1,714 @@
|
|
|
1
|
+
/* Process events and stdin streaming — the OPTIONAL half of the event
|
|
2
|
+
* loop: signal handlers (process.on/once/off of SIGINT/SIGTERM), the
|
|
3
|
+
* process 'exit' event, and the piped-stdin surface ('data'/'end'/'error'
|
|
4
|
+
* listeners plus the for-await chunk source). This translation unit links
|
|
5
|
+
* ONLY into binaries whose IR uses those surfaces (moduleUsesProcessEvents
|
|
6
|
+
* — the scr_regex/scr_fetch/scr_zlib gating precedent), and the emitted
|
|
7
|
+
* main calls scr_events_install() before %main, which points the loop's
|
|
8
|
+
* nullable event hooks (scr_async.c) and scr_lib.c's process.exit /
|
|
9
|
+
* stdin.destroy hooks here. Programs that never touch these surfaces pay
|
|
10
|
+
* zero bytes and keep their exact historical link line. */
|
|
11
|
+
#define _XOPEN_SOURCE 700
|
|
12
|
+
#include "scr_runtime.h"
|
|
13
|
+
|
|
14
|
+
#include <errno.h>
|
|
15
|
+
#include <fcntl.h>
|
|
16
|
+
#include <signal.h>
|
|
17
|
+
#include <stdio.h>
|
|
18
|
+
#include <stdlib.h>
|
|
19
|
+
#include <string.h>
|
|
20
|
+
#ifdef _WIN32
|
|
21
|
+
/* The Windows arm: CRT signal() stands in for sigaction (msvcrt routes
|
|
22
|
+
* Ctrl-C/Ctrl-Break through its own SetConsoleCtrlHandler onto a separate
|
|
23
|
+
* thread and RESETS the disposition to SIG_DFL before each delivery — the
|
|
24
|
+
* handler re-arms itself), the readability probe is PeekNamedPipe /
|
|
25
|
+
* WaitForSingleObject instead of poll(2), and there is NO self-pipe: the
|
|
26
|
+
* loop's win32 idle sleep is the capped nanosleep in scr_async.c, so the
|
|
27
|
+
* handler's flag alone suffices and the cap bounds delivery latency.
|
|
28
|
+
* read(2) on fd 0 is mingw's CRT read — fd 0 is already _O_BINARY
|
|
29
|
+
* (scr_console.c's install). */
|
|
30
|
+
#include <io.h>
|
|
31
|
+
#include <unistd.h> /* mingw-w64 ships one: read */
|
|
32
|
+
#include <windows.h>
|
|
33
|
+
#else
|
|
34
|
+
#include <poll.h>
|
|
35
|
+
#include <unistd.h>
|
|
36
|
+
#endif
|
|
37
|
+
|
|
38
|
+
static void scr_events_oom(void) {
|
|
39
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
40
|
+
abort();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* ── process signal events (process.on("SIGINT" | "SIGTERM")) ─────────
|
|
44
|
+
* Classic self-pipe integration: a watched signal's sigaction handler
|
|
45
|
+
* (installed WITHOUT SA_RESTART) sets a per-signal flag and writes one
|
|
46
|
+
* byte into the wake pipe. The loop drains flags at every turn and the
|
|
47
|
+
* idle sleeps either get EINTR'd by the handler (nanosleep, kevent) or
|
|
48
|
+
* poll on the wake pipe directly, so a byte written before the sleep
|
|
49
|
+
* entered still wakes it — no lost-wakeup race. Listeners run on the main
|
|
50
|
+
* stack like timer callbacks (macrotasks). Node semantics matched:
|
|
51
|
+
* watching a signal replaces its default disposition (Ctrl-C no longer
|
|
52
|
+
* kills), removing the LAST listener restores it, `once` listeners are
|
|
53
|
+
* removed BEFORE they run, and signal listeners do NOT keep the loop
|
|
54
|
+
* alive — the exhaustion test ignores them, exactly Node. Multiple
|
|
55
|
+
* deliveries between two loop turns coalesce into one dispatch (the
|
|
56
|
+
* kernel coalesces pending non-RT signals the same way). */
|
|
57
|
+
|
|
58
|
+
typedef struct {
|
|
59
|
+
ScrClosure *cb; /* owned */
|
|
60
|
+
bool once;
|
|
61
|
+
} ScrSigListener;
|
|
62
|
+
|
|
63
|
+
typedef struct ScrSigReg {
|
|
64
|
+
int sig;
|
|
65
|
+
#ifdef _WIN32
|
|
66
|
+
void (*prev)(int); /* restored when the last listener leaves */
|
|
67
|
+
#else
|
|
68
|
+
struct sigaction prev; /* restored when the last listener leaves */
|
|
69
|
+
#endif
|
|
70
|
+
ScrSigListener *ls;
|
|
71
|
+
size_t n, cap;
|
|
72
|
+
struct ScrSigReg *next;
|
|
73
|
+
} ScrSigReg;
|
|
74
|
+
|
|
75
|
+
/* Classic signal numbers only (SIGINT 2 / SIGTERM 15 today; every POSIX
|
|
76
|
+
* classic fits) — NSIG is not visible under strict _XOPEN_SOURCE. */
|
|
77
|
+
#define SCR_SIG_MAX 32
|
|
78
|
+
|
|
79
|
+
static ScrSigReg *scr_sig_regs = NULL;
|
|
80
|
+
static size_t scr_sig_watched = 0; /* watched signal COUNT (regs) */
|
|
81
|
+
static volatile sig_atomic_t scr_sig_flag[SCR_SIG_MAX];
|
|
82
|
+
static volatile sig_atomic_t scr_sig_any = 0;
|
|
83
|
+
static int scr_wake_pipe[2] = {-1, -1};
|
|
84
|
+
|
|
85
|
+
static void scr_sig_handler(int sig) {
|
|
86
|
+
if (sig < 0 || sig >= SCR_SIG_MAX) return;
|
|
87
|
+
#ifdef _WIN32
|
|
88
|
+
/* msvcrt reset the disposition to SIG_DFL before this call (SysV
|
|
89
|
+
* semantics); re-arm so the next delivery reaches us too. Only ever
|
|
90
|
+
* runs while a registration exists — dropping the last listener
|
|
91
|
+
* restores the previous disposition below. */
|
|
92
|
+
signal(sig, scr_sig_handler);
|
|
93
|
+
#endif
|
|
94
|
+
scr_sig_flag[sig] = 1;
|
|
95
|
+
scr_sig_any = 1;
|
|
96
|
+
if (scr_wake_pipe[1] >= 0) {
|
|
97
|
+
ssize_t ignored = write(scr_wake_pipe[1], "s", 1);
|
|
98
|
+
(void)ignored; /* a full pipe still wakes the poller */
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static void scr_sig_reg_drop(ScrSigReg *reg);
|
|
103
|
+
|
|
104
|
+
/* Half of the exit-time cleanup (registered by scr_events_install;
|
|
105
|
+
* atexit LIFO puts it BEFORE the RC audit): releases signal listeners a
|
|
106
|
+
* program legitimately leaves registered at exit — handlers installed for
|
|
107
|
+
* the process's whole life (the long-lived CLI shape), like Node — so the audit
|
|
108
|
+
* never mistakes them for leaks. */
|
|
109
|
+
static void scr_sig_cleanup(void) {
|
|
110
|
+
while (scr_sig_regs) {
|
|
111
|
+
ScrSigReg *reg = scr_sig_regs;
|
|
112
|
+
for (size_t i = 0; i < reg->n; i++) scr_closure_release(reg->ls[i].cb);
|
|
113
|
+
reg->n = 0;
|
|
114
|
+
scr_sig_reg_drop(reg);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static void scr_wake_pipe_init(void) {
|
|
119
|
+
#ifdef _WIN32
|
|
120
|
+
/* No self-pipe: the win32 loop never polls fds (scr_async.c's capped
|
|
121
|
+
* nanosleep takes the idle sleep), so the handler's flag is the whole
|
|
122
|
+
* wake path and the fds stay -1 — every pipe use below is guarded. */
|
|
123
|
+
return;
|
|
124
|
+
#else
|
|
125
|
+
if (scr_wake_pipe[0] >= 0) return;
|
|
126
|
+
if (pipe(scr_wake_pipe) != 0) {
|
|
127
|
+
scr_wake_pipe[0] = scr_wake_pipe[1] = -1;
|
|
128
|
+
return; /* sleeps still wake via EINTR; only the tiny race widens */
|
|
129
|
+
}
|
|
130
|
+
for (int i = 0; i < 2; i++) {
|
|
131
|
+
fcntl(scr_wake_pipe[i], F_SETFL, O_NONBLOCK);
|
|
132
|
+
fcntl(scr_wake_pipe[i], F_SETFD, FD_CLOEXEC);
|
|
133
|
+
}
|
|
134
|
+
#endif
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static void scr_wake_pipe_drain(void) {
|
|
138
|
+
if (scr_wake_pipe[0] < 0) return;
|
|
139
|
+
char buf[64];
|
|
140
|
+
while (read(scr_wake_pipe[0], buf, sizeof buf) > 0) {}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
void scr_signal_on(double signum, ScrClosure *cb /*moves*/, bool once) {
|
|
144
|
+
int sig = (int)signum;
|
|
145
|
+
if (sig <= 0 || sig >= SCR_SIG_MAX) {
|
|
146
|
+
scr_closure_release(cb); /* frontend only emits classic signals */
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
ScrSigReg *reg = scr_sig_regs;
|
|
150
|
+
while (reg && reg->sig != sig) reg = reg->next;
|
|
151
|
+
if (!reg) {
|
|
152
|
+
reg = calloc(1, sizeof *reg);
|
|
153
|
+
if (!reg) scr_events_oom();
|
|
154
|
+
reg->sig = sig;
|
|
155
|
+
reg->next = scr_sig_regs;
|
|
156
|
+
scr_sig_regs = reg;
|
|
157
|
+
scr_sig_watched++;
|
|
158
|
+
scr_wake_pipe_init();
|
|
159
|
+
#ifdef _WIN32
|
|
160
|
+
reg->prev = signal(sig, scr_sig_handler);
|
|
161
|
+
if (reg->prev == SIG_ERR) reg->prev = SIG_DFL;
|
|
162
|
+
#else
|
|
163
|
+
struct sigaction sa;
|
|
164
|
+
memset(&sa, 0, sizeof sa);
|
|
165
|
+
sa.sa_handler = scr_sig_handler;
|
|
166
|
+
sigemptyset(&sa.sa_mask);
|
|
167
|
+
sa.sa_flags = 0; /* NO SA_RESTART: idle sleeps must EINTR */
|
|
168
|
+
sigaction(sig, &sa, ®->prev);
|
|
169
|
+
#endif
|
|
170
|
+
}
|
|
171
|
+
if (reg->n == reg->cap) {
|
|
172
|
+
reg->cap = reg->cap ? reg->cap * 2 : 2;
|
|
173
|
+
reg->ls = realloc(reg->ls, reg->cap * sizeof *reg->ls);
|
|
174
|
+
if (!reg->ls) scr_events_oom();
|
|
175
|
+
}
|
|
176
|
+
reg->ls[reg->n].cb = cb;
|
|
177
|
+
reg->ls[reg->n].once = once;
|
|
178
|
+
reg->n++;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static void scr_sig_reg_drop(ScrSigReg *reg) {
|
|
182
|
+
#ifdef _WIN32
|
|
183
|
+
signal(reg->sig, reg->prev); /* default disposition back */
|
|
184
|
+
#else
|
|
185
|
+
sigaction(reg->sig, ®->prev, NULL); /* default disposition back */
|
|
186
|
+
#endif
|
|
187
|
+
ScrSigReg **link = &scr_sig_regs;
|
|
188
|
+
while (*link != reg) link = &(*link)->next;
|
|
189
|
+
*link = reg->next;
|
|
190
|
+
scr_sig_watched--;
|
|
191
|
+
free(reg->ls);
|
|
192
|
+
free(reg);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
void scr_signal_off(double signum, ScrClosure *cb /*borrowed*/) {
|
|
196
|
+
int sig = (int)signum;
|
|
197
|
+
ScrSigReg *reg = scr_sig_regs;
|
|
198
|
+
while (reg && reg->sig != sig) reg = reg->next;
|
|
199
|
+
if (!reg) return;
|
|
200
|
+
for (size_t i = 0; i < reg->n; i++) {
|
|
201
|
+
if (reg->ls[i].cb == cb) { /* first match, like Node's removeListener */
|
|
202
|
+
scr_closure_release(reg->ls[i].cb);
|
|
203
|
+
memmove(reg->ls + i, reg->ls + i + 1, (reg->n - i - 1) * sizeof *reg->ls);
|
|
204
|
+
reg->n--;
|
|
205
|
+
if (reg->n == 0) scr_sig_reg_drop(reg);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* One dispatch pass: every flagged signal fires its listener SNAPSHOT
|
|
212
|
+
* (Node emits over a copy — a listener removed mid-emit still runs for
|
|
213
|
+
* this delivery; one added mid-emit waits for the next). `once` entries
|
|
214
|
+
* leave the live list BEFORE their callback runs; an emptied list
|
|
215
|
+
* restores the default disposition, so the next delivery of that signal
|
|
216
|
+
* kills the process — Node-exact. A throw stops the pass and leaves the
|
|
217
|
+
* exception for the loop. */
|
|
218
|
+
static void scr_signals_drain(void) {
|
|
219
|
+
if (!scr_sig_any) return;
|
|
220
|
+
scr_sig_any = 0;
|
|
221
|
+
ScrSigReg *reg = scr_sig_regs;
|
|
222
|
+
while (reg) {
|
|
223
|
+
ScrSigReg *next = reg->next; /* reg may drop below */
|
|
224
|
+
if (scr_sig_flag[reg->sig]) {
|
|
225
|
+
scr_sig_flag[reg->sig] = 0;
|
|
226
|
+
size_t n = reg->n;
|
|
227
|
+
ScrSigListener *snap = malloc(n * sizeof *snap);
|
|
228
|
+
if (!snap) scr_events_oom();
|
|
229
|
+
for (size_t i = 0; i < n; i++) {
|
|
230
|
+
snap[i] = reg->ls[i];
|
|
231
|
+
scr_closure_retain(snap[i].cb);
|
|
232
|
+
}
|
|
233
|
+
bool dropped = false;
|
|
234
|
+
for (size_t i = 0; i < n; i++) {
|
|
235
|
+
if (snap[i].once && !dropped) {
|
|
236
|
+
/* remove from the live list before invoking */
|
|
237
|
+
for (size_t j = 0; j < reg->n; j++) {
|
|
238
|
+
if (reg->ls[j].cb == snap[i].cb) {
|
|
239
|
+
scr_closure_release(reg->ls[j].cb);
|
|
240
|
+
memmove(reg->ls + j, reg->ls + j + 1, (reg->n - j - 1) * sizeof *reg->ls);
|
|
241
|
+
reg->n--;
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (reg->n == 0) {
|
|
246
|
+
scr_sig_reg_drop(reg);
|
|
247
|
+
dropped = true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (!scr_exc_pending()) {
|
|
251
|
+
((void (*)(ScrClosure *))snap[i].cb->fn)(snap[i].cb);
|
|
252
|
+
}
|
|
253
|
+
scr_closure_release(snap[i].cb);
|
|
254
|
+
}
|
|
255
|
+
free(snap);
|
|
256
|
+
if (scr_exc_pending()) return;
|
|
257
|
+
}
|
|
258
|
+
reg = next;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* ── process.stdin events and async iteration ─────────────────────────
|
|
263
|
+
* The honest piped-stdin slice: 'data'/'end'/'error' listeners (on/once)
|
|
264
|
+
* and the for-await chunk source. fd 0 is watched with poll(2) only
|
|
265
|
+
* while a CONSUMER exists — a 'data' listener or a parked for-await
|
|
266
|
+
* chunk promise — which is also the loop's keep-alive test: Node keeps
|
|
267
|
+
* the process alive for a flowing stdin and lets it exit once nothing
|
|
268
|
+
* consumes. One poll wake = one read(2) = one chunk (up to 64KB, like
|
|
269
|
+
* libuv's pipe reads); EOF fires 'end' (once semantics respected),
|
|
270
|
+
* settles a parked chunk promise with the EMPTY sentinel, and drops the
|
|
271
|
+
* remaining listeners — after 'end' nothing fires again. destroy()
|
|
272
|
+
* tears everything down the same way (Node's destroyed stream delivers
|
|
273
|
+
* nothing more; a for-await running at destroy time ends instead of
|
|
274
|
+
* throwing Node's premature-close error — documented divergence). A
|
|
275
|
+
* read(2) failure fires 'error' listeners (the Error is built by the
|
|
276
|
+
* child err adapters — same shape) and then ends the stream; with no
|
|
277
|
+
* listener it is treated as EOF (piped fd 0 read errors are not
|
|
278
|
+
* meaningfully reachable). */
|
|
279
|
+
|
|
280
|
+
typedef struct {
|
|
281
|
+
ScrClosure *cb; /* owned */
|
|
282
|
+
void (*fn)(ScrClosure *cb, ScrBytes *chunk); /* adapter: chunk borrowed */
|
|
283
|
+
bool once;
|
|
284
|
+
} ScrStdinDataL;
|
|
285
|
+
|
|
286
|
+
typedef struct {
|
|
287
|
+
ScrClosure *cb; /* owned */
|
|
288
|
+
bool once;
|
|
289
|
+
} ScrStdinEndL;
|
|
290
|
+
|
|
291
|
+
typedef struct {
|
|
292
|
+
ScrClosure *cb; /* owned */
|
|
293
|
+
ScrChildErrFn fn; /* the child error adapters fit exactly */
|
|
294
|
+
bool once;
|
|
295
|
+
} ScrStdinErrL;
|
|
296
|
+
|
|
297
|
+
static ScrStdinDataL *scr_stdin_data = NULL;
|
|
298
|
+
static size_t scr_stdin_ndata = 0, scr_stdin_data_cap = 0;
|
|
299
|
+
static ScrStdinEndL *scr_stdin_end = NULL;
|
|
300
|
+
static size_t scr_stdin_nend = 0, scr_stdin_end_cap = 0;
|
|
301
|
+
static ScrStdinErrL *scr_stdin_err = NULL;
|
|
302
|
+
static size_t scr_stdin_nerr = 0, scr_stdin_err_cap = 0;
|
|
303
|
+
static ScrPromise *scr_stdin_waiter = NULL; /* parked for-await next() */
|
|
304
|
+
static bool scr_stdin_eof = false;
|
|
305
|
+
static bool scr_stdin_destroyed = false;
|
|
306
|
+
|
|
307
|
+
void scr_stdin_on_data(ScrClosure *cb /*moves*/, void (*fn)(ScrClosure *, ScrBytes *),
|
|
308
|
+
bool once) {
|
|
309
|
+
if (scr_stdin_eof || scr_stdin_destroyed) {
|
|
310
|
+
scr_closure_release(cb); /* never fires again, like Node post-'end' */
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (scr_stdin_ndata == scr_stdin_data_cap) {
|
|
314
|
+
scr_stdin_data_cap = scr_stdin_data_cap ? scr_stdin_data_cap * 2 : 2;
|
|
315
|
+
scr_stdin_data = realloc(scr_stdin_data, scr_stdin_data_cap * sizeof *scr_stdin_data);
|
|
316
|
+
if (!scr_stdin_data) scr_events_oom();
|
|
317
|
+
}
|
|
318
|
+
scr_stdin_data[scr_stdin_ndata].cb = cb;
|
|
319
|
+
scr_stdin_data[scr_stdin_ndata].fn = fn;
|
|
320
|
+
scr_stdin_data[scr_stdin_ndata].once = once;
|
|
321
|
+
scr_stdin_ndata++;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
void scr_stdin_on_end(ScrClosure *cb /*moves*/, bool once) {
|
|
325
|
+
if (scr_stdin_eof || scr_stdin_destroyed) {
|
|
326
|
+
scr_closure_release(cb);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (scr_stdin_nend == scr_stdin_end_cap) {
|
|
330
|
+
scr_stdin_end_cap = scr_stdin_end_cap ? scr_stdin_end_cap * 2 : 2;
|
|
331
|
+
scr_stdin_end = realloc(scr_stdin_end, scr_stdin_end_cap * sizeof *scr_stdin_end);
|
|
332
|
+
if (!scr_stdin_end) scr_events_oom();
|
|
333
|
+
}
|
|
334
|
+
scr_stdin_end[scr_stdin_nend].cb = cb;
|
|
335
|
+
scr_stdin_end[scr_stdin_nend].once = once;
|
|
336
|
+
scr_stdin_nend++;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
void scr_stdin_on_error(ScrClosure *cb /*moves*/, ScrChildErrFn fn, bool once) {
|
|
340
|
+
if (scr_stdin_eof || scr_stdin_destroyed) {
|
|
341
|
+
scr_closure_release(cb);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (scr_stdin_nerr == scr_stdin_err_cap) {
|
|
345
|
+
scr_stdin_err_cap = scr_stdin_err_cap ? scr_stdin_err_cap * 2 : 2;
|
|
346
|
+
scr_stdin_err = realloc(scr_stdin_err, scr_stdin_err_cap * sizeof *scr_stdin_err);
|
|
347
|
+
if (!scr_stdin_err) scr_events_oom();
|
|
348
|
+
}
|
|
349
|
+
scr_stdin_err[scr_stdin_nerr].cb = cb;
|
|
350
|
+
scr_stdin_err[scr_stdin_nerr].fn = fn;
|
|
351
|
+
scr_stdin_err[scr_stdin_nerr].once = once;
|
|
352
|
+
scr_stdin_nerr++;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/* Removal by closure identity — node:readline's close() detaches its
|
|
356
|
+
* shared consumer so the loop stops waiting on fd 0 (Node's
|
|
357
|
+
* pause-on-close). Safe mid-dispatch: the service pass runs over a
|
|
358
|
+
* snapshot, exactly like the once-removal. No-op for unknown closures. */
|
|
359
|
+
void scr_stdin_remove_data(ScrClosure *cb) {
|
|
360
|
+
for (size_t j = 0; j < scr_stdin_ndata; j++) {
|
|
361
|
+
if (scr_stdin_data[j].cb == cb) {
|
|
362
|
+
scr_closure_release(scr_stdin_data[j].cb);
|
|
363
|
+
memmove(scr_stdin_data + j, scr_stdin_data + j + 1,
|
|
364
|
+
(scr_stdin_ndata - j - 1) * sizeof *scr_stdin_data);
|
|
365
|
+
scr_stdin_ndata--;
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/* True once the stream can never deliver again (EOF seen, or destroyed) —
|
|
372
|
+
* node:readline's created-after-the-end probe. */
|
|
373
|
+
bool scr_stdin_ended(void) { return scr_stdin_eof || scr_stdin_destroyed; }
|
|
374
|
+
|
|
375
|
+
/* The loop keep-alive/watch predicate: a consumer exists and the stream
|
|
376
|
+
* can still deliver. 'end'/'error' listeners alone do not keep the loop
|
|
377
|
+
* alive (a paused Node stdin with only those never flows — the process
|
|
378
|
+
* exits with them registered). */
|
|
379
|
+
static bool scr_stdin_watching(void) {
|
|
380
|
+
return !scr_stdin_eof && !scr_stdin_destroyed &&
|
|
381
|
+
(scr_stdin_ndata > 0 || scr_stdin_waiter != NULL);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
bool scr_stdin_pending(void) { return scr_stdin_watching(); }
|
|
385
|
+
|
|
386
|
+
static void scr_stdin_drop_listeners(void) {
|
|
387
|
+
for (size_t i = 0; i < scr_stdin_ndata; i++) scr_closure_release(scr_stdin_data[i].cb);
|
|
388
|
+
for (size_t i = 0; i < scr_stdin_nend; i++) scr_closure_release(scr_stdin_end[i].cb);
|
|
389
|
+
for (size_t i = 0; i < scr_stdin_nerr; i++) scr_closure_release(scr_stdin_err[i].cb);
|
|
390
|
+
free(scr_stdin_data);
|
|
391
|
+
free(scr_stdin_end);
|
|
392
|
+
free(scr_stdin_err);
|
|
393
|
+
scr_stdin_data = NULL;
|
|
394
|
+
scr_stdin_end = NULL;
|
|
395
|
+
scr_stdin_err = NULL;
|
|
396
|
+
scr_stdin_ndata = scr_stdin_nend = scr_stdin_nerr = 0;
|
|
397
|
+
scr_stdin_data_cap = scr_stdin_end_cap = scr_stdin_err_cap = 0;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* Settles the parked for-await promise with the empty DONE sentinel (a
|
|
401
|
+
* POSIX read never delivers an empty data chunk, so the sentinel cannot
|
|
402
|
+
* collide with real data). */
|
|
403
|
+
static void scr_stdin_settle_done(void) {
|
|
404
|
+
if (!scr_stdin_waiter) return;
|
|
405
|
+
ScrPromise *p = scr_stdin_waiter;
|
|
406
|
+
scr_stdin_waiter = NULL;
|
|
407
|
+
ScrBytes *empty = scr_bytes_new(SCR_BYTES_U8, 0);
|
|
408
|
+
scr_promise_fulfill_ref(p, empty, scr_bytes_retain_v, scr_bytes_release_v, NULL);
|
|
409
|
+
scr_promise_release(p);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/* EOF/teardown shared tail: 'end' fires (snapshot; once semantics are
|
|
413
|
+
* moot — everything drops right after), the parked promise settles done,
|
|
414
|
+
* and every listener is released. */
|
|
415
|
+
static void scr_stdin_finish(bool fire_end) {
|
|
416
|
+
scr_stdin_eof = true;
|
|
417
|
+
if (fire_end) {
|
|
418
|
+
size_t n = scr_stdin_nend;
|
|
419
|
+
ScrStdinEndL *snap = malloc(n * sizeof *snap);
|
|
420
|
+
if (!snap) scr_events_oom();
|
|
421
|
+
for (size_t i = 0; i < n; i++) {
|
|
422
|
+
snap[i] = scr_stdin_end[i];
|
|
423
|
+
scr_closure_retain(snap[i].cb);
|
|
424
|
+
}
|
|
425
|
+
for (size_t i = 0; i < n; i++) {
|
|
426
|
+
if (!scr_exc_pending()) {
|
|
427
|
+
((void (*)(ScrClosure *))snap[i].cb->fn)(snap[i].cb);
|
|
428
|
+
}
|
|
429
|
+
scr_closure_release(snap[i].cb);
|
|
430
|
+
}
|
|
431
|
+
free(snap);
|
|
432
|
+
}
|
|
433
|
+
scr_stdin_settle_done();
|
|
434
|
+
scr_stdin_drop_listeners();
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/* process.stdin.destroy(): tear the stream down — nothing fires after,
|
|
438
|
+
* the loop stops watching, and a parked for-await ends. */
|
|
439
|
+
void scr_stdin_destroy(void) {
|
|
440
|
+
if (scr_stdin_destroyed) return;
|
|
441
|
+
scr_stdin_destroyed = true;
|
|
442
|
+
scr_stdin_settle_done();
|
|
443
|
+
scr_stdin_drop_listeners();
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/* The for-await chunk source: a +1 promise of the NEXT chunk (fulfilled
|
|
447
|
+
* from the poll wake), or of the empty done sentinel at EOF/teardown.
|
|
448
|
+
* One parked promise at a time — concurrent iterations of process.stdin
|
|
449
|
+
* would share deliveries (nothing real does this). */
|
|
450
|
+
ScrPromise *scr_stdin_next_chunk(void) {
|
|
451
|
+
if (scr_stdin_eof || scr_stdin_destroyed) {
|
|
452
|
+
ScrPromise *p = scr_promise_new();
|
|
453
|
+
ScrBytes *empty = scr_bytes_new(SCR_BYTES_U8, 0);
|
|
454
|
+
scr_promise_fulfill_ref(p, empty, scr_bytes_retain_v, scr_bytes_release_v, NULL);
|
|
455
|
+
return p;
|
|
456
|
+
}
|
|
457
|
+
if (!scr_stdin_waiter) scr_stdin_waiter = scr_promise_new();
|
|
458
|
+
return scr_promise_retain(scr_stdin_waiter);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/* One service pass, called at loop turns while watching: a zero-timeout
|
|
462
|
+
* poll probes readability (the idle sleep already waited on fd 0), one
|
|
463
|
+
* read(2) takes what arrived, and the chunk goes to the 'data' listeners
|
|
464
|
+
* (snapshot; `once` entries leave the live list before running) — or,
|
|
465
|
+
* with no listener, to the parked for-await promise. Node's stream would
|
|
466
|
+
* buffer a chunk nobody consumes; this slice never reads without a
|
|
467
|
+
* consumer, so the pipe itself is the buffer (backpressure, not loss). */
|
|
468
|
+
static void scr_stdin_service(void) {
|
|
469
|
+
if (!scr_stdin_watching()) return;
|
|
470
|
+
#ifdef _WIN32
|
|
471
|
+
/* The poll(2)-probe's win32 spelling, by handle type: a PIPE (the
|
|
472
|
+
* harness/ssh shape) answers PeekNamedPipe — bytes available, or a
|
|
473
|
+
* FALSE return once the writer closed (broken pipe), where read(2)
|
|
474
|
+
* below delivers the EOF; a CONSOLE answers a zero-timeout wait on the
|
|
475
|
+
* input handle (cooked mode — a read may still block until Enter, the
|
|
476
|
+
* interactive line-buffering Node's cooked stdin shows too); disk
|
|
477
|
+
* files are always readable. A missing handle falls through to read,
|
|
478
|
+
* whose 0/-1 ends the stream. */
|
|
479
|
+
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
|
|
480
|
+
if (h != NULL && h != INVALID_HANDLE_VALUE) {
|
|
481
|
+
DWORD type = GetFileType(h);
|
|
482
|
+
if (type == FILE_TYPE_PIPE) {
|
|
483
|
+
DWORD avail = 0;
|
|
484
|
+
if (PeekNamedPipe(h, NULL, 0, NULL, &avail, NULL) && avail == 0) return;
|
|
485
|
+
} else if (type == FILE_TYPE_CHAR) {
|
|
486
|
+
if (WaitForSingleObject(h, 0) != WAIT_OBJECT_0) return;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
#else
|
|
490
|
+
struct pollfd pfd = {0 /* stdin */, POLLIN, 0};
|
|
491
|
+
int rc = poll(&pfd, 1, 0);
|
|
492
|
+
if (rc <= 0 || !(pfd.revents & (POLLIN | POLLHUP | POLLERR))) return;
|
|
493
|
+
#endif
|
|
494
|
+
char buf[65536];
|
|
495
|
+
ssize_t n = read(0, buf, sizeof buf);
|
|
496
|
+
if (n < 0) {
|
|
497
|
+
if (errno == EINTR || errno == EAGAIN) return;
|
|
498
|
+
/* Real read failure: 'error' listeners get Node's Error shape via the
|
|
499
|
+
* child adapters; the stream then ends silently (no 'end' after
|
|
500
|
+
* 'error', like Node). No listener: treated as EOF. */
|
|
501
|
+
if (scr_stdin_nerr > 0) {
|
|
502
|
+
char msg[64];
|
|
503
|
+
snprintf(msg, sizeof msg, "read E%d", errno);
|
|
504
|
+
ScrStr *m = scr_str_new(msg, strlen(msg));
|
|
505
|
+
size_t nl = scr_stdin_nerr;
|
|
506
|
+
ScrStdinErrL *snap = malloc(nl * sizeof *snap);
|
|
507
|
+
if (!snap) scr_events_oom();
|
|
508
|
+
for (size_t i = 0; i < nl; i++) {
|
|
509
|
+
snap[i] = scr_stdin_err[i];
|
|
510
|
+
scr_closure_retain(snap[i].cb);
|
|
511
|
+
}
|
|
512
|
+
for (size_t i = 0; i < nl; i++) {
|
|
513
|
+
if (!scr_exc_pending()) snap[i].fn(snap[i].cb, m);
|
|
514
|
+
scr_closure_release(snap[i].cb);
|
|
515
|
+
}
|
|
516
|
+
free(snap);
|
|
517
|
+
scr_str_release(m);
|
|
518
|
+
scr_stdin_finish(false);
|
|
519
|
+
} else {
|
|
520
|
+
scr_stdin_finish(true);
|
|
521
|
+
}
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
if (n == 0) {
|
|
525
|
+
scr_stdin_finish(true); /* EOF: 'end' fires, iteration ends */
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
ScrBytes *chunk = scr_bytes_new(SCR_BYTES_U8, (double)n);
|
|
529
|
+
memcpy(chunk->data, buf, (size_t)n);
|
|
530
|
+
if (scr_stdin_ndata > 0) {
|
|
531
|
+
size_t nd = scr_stdin_ndata;
|
|
532
|
+
ScrStdinDataL *snap = malloc(nd * sizeof *snap);
|
|
533
|
+
if (!snap) scr_events_oom();
|
|
534
|
+
for (size_t i = 0; i < nd; i++) {
|
|
535
|
+
snap[i] = scr_stdin_data[i];
|
|
536
|
+
scr_closure_retain(snap[i].cb);
|
|
537
|
+
}
|
|
538
|
+
for (size_t i = 0; i < nd; i++) {
|
|
539
|
+
if (snap[i].once) {
|
|
540
|
+
for (size_t j = 0; j < scr_stdin_ndata; j++) {
|
|
541
|
+
if (scr_stdin_data[j].cb == snap[i].cb) {
|
|
542
|
+
scr_closure_release(scr_stdin_data[j].cb);
|
|
543
|
+
memmove(scr_stdin_data + j, scr_stdin_data + j + 1,
|
|
544
|
+
(scr_stdin_ndata - j - 1) * sizeof *scr_stdin_data);
|
|
545
|
+
scr_stdin_ndata--;
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (!scr_exc_pending()) snap[i].fn(snap[i].cb, chunk);
|
|
551
|
+
scr_closure_release(snap[i].cb);
|
|
552
|
+
}
|
|
553
|
+
free(snap);
|
|
554
|
+
} else if (scr_stdin_waiter) {
|
|
555
|
+
ScrPromise *p = scr_stdin_waiter;
|
|
556
|
+
scr_stdin_waiter = NULL;
|
|
557
|
+
scr_promise_fulfill_ref(p, scr_bytes_retain(chunk), scr_bytes_retain_v,
|
|
558
|
+
scr_bytes_release_v, NULL);
|
|
559
|
+
scr_promise_release(p);
|
|
560
|
+
}
|
|
561
|
+
scr_bytes_release(chunk);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/* ── the process 'exit' event ─────────────────────────────────────────
|
|
565
|
+
* Listeners run SYNCHRONOUSLY when the process exits: at the end of a
|
|
566
|
+
* normal run (the unit's atexit, registered by scr_events_install after
|
|
567
|
+
* scr_init's hooks, so it runs BEFORE the RC audit/flush by LIFO) and
|
|
568
|
+
* inside process.exit() (scr_lib.c calls through scr_process_exit_hook
|
|
569
|
+
* before its deliberate _Exit — Node runs 'exit' listeners on explicit
|
|
570
|
+
* exits too). The code argument: process.exit's real code on that path;
|
|
571
|
+
* on the atexit path the hint kept in scr_async.c — 0 unless the
|
|
572
|
+
* uncaught-exception or unhandled-rejection reporters marked the run as
|
|
573
|
+
* failing (they set 1 exactly when main returns 1). Signal deaths skip
|
|
574
|
+
* Node's 'exit' event alike. `once` and `off` follow the signal
|
|
575
|
+
* registry's rules; anything a listener schedules can never run (the
|
|
576
|
+
* loop is gone), exactly Node's contract. */
|
|
577
|
+
|
|
578
|
+
typedef struct {
|
|
579
|
+
ScrClosure *cb; /* owned */
|
|
580
|
+
void (*fn)(ScrClosure *cb, double code); /* adapter: 0-param or (code) */
|
|
581
|
+
bool once;
|
|
582
|
+
} ScrExitListener;
|
|
583
|
+
|
|
584
|
+
static ScrExitListener *scr_exit_ls = NULL;
|
|
585
|
+
static size_t scr_exit_n = 0, scr_exit_cap = 0;
|
|
586
|
+
static bool scr_exit_ran = false;
|
|
587
|
+
|
|
588
|
+
void scr_run_exit_listeners(double code) {
|
|
589
|
+
if (scr_exit_ran) return; /* process.exit inside a listener: no recursion */
|
|
590
|
+
scr_exit_ran = true;
|
|
591
|
+
scr_process_in_exit = true; /* process._exiting — Node's flag */
|
|
592
|
+
for (size_t i = 0; i < scr_exit_n; i++) {
|
|
593
|
+
scr_exit_ls[i].fn(scr_exit_ls[i].cb, code);
|
|
594
|
+
if (scr_exc_pending()) {
|
|
595
|
+
/* Node: a throw in an 'exit' listener is fatal (exit code 7). */
|
|
596
|
+
scr_exc_print_uncaught();
|
|
597
|
+
fflush(stdout);
|
|
598
|
+
_Exit(7);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
for (size_t i = 0; i < scr_exit_n; i++) scr_closure_release(scr_exit_ls[i].cb);
|
|
602
|
+
free(scr_exit_ls);
|
|
603
|
+
scr_exit_ls = NULL;
|
|
604
|
+
scr_exit_n = scr_exit_cap = 0;
|
|
605
|
+
/* Ticks the listeners enqueued never run (Node drops the queue at
|
|
606
|
+
* exit) — release them here or the RC audit counts them as leaks (the
|
|
607
|
+
* loop's own teardown already ran, before these listeners). */
|
|
608
|
+
scr_nticks_teardown();
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
void scr_process_on_exit(ScrClosure *cb /*moves*/, void (*fn)(ScrClosure *, double),
|
|
612
|
+
bool once) {
|
|
613
|
+
if (scr_exit_ran) {
|
|
614
|
+
scr_closure_release(cb);
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (scr_exit_n == scr_exit_cap) {
|
|
618
|
+
scr_exit_cap = scr_exit_cap ? scr_exit_cap * 2 : 2;
|
|
619
|
+
scr_exit_ls = realloc(scr_exit_ls, scr_exit_cap * sizeof *scr_exit_ls);
|
|
620
|
+
if (!scr_exit_ls) scr_events_oom();
|
|
621
|
+
}
|
|
622
|
+
scr_exit_ls[scr_exit_n].cb = cb;
|
|
623
|
+
scr_exit_ls[scr_exit_n].fn = fn;
|
|
624
|
+
scr_exit_ls[scr_exit_n].once = once;
|
|
625
|
+
scr_exit_n++;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
void scr_process_off_exit(ScrClosure *cb /*borrowed*/) {
|
|
629
|
+
for (size_t i = 0; i < scr_exit_n; i++) {
|
|
630
|
+
if (scr_exit_ls[i].cb == cb) {
|
|
631
|
+
scr_closure_release(scr_exit_ls[i].cb);
|
|
632
|
+
memmove(scr_exit_ls + i, scr_exit_ls + i + 1, (scr_exit_n - i - 1) * sizeof *scr_exit_ls);
|
|
633
|
+
scr_exit_n--;
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/* The runtime-provided exit listener adapters (the code is a plain
|
|
640
|
+
* double — no program types needed). */
|
|
641
|
+
void scr_exit_thunk0(ScrClosure *cb, double code) {
|
|
642
|
+
(void)code;
|
|
643
|
+
((void (*)(ScrClosure *))cb->fn)(cb);
|
|
644
|
+
}
|
|
645
|
+
void scr_exit_thunk_code(ScrClosure *cb, double code) {
|
|
646
|
+
((void (*)(ScrClosure *, double))cb->fn)(cb, code);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/* The runtime-provided stdin data adapters. */
|
|
650
|
+
void scr_stdin_data_thunk0(ScrClosure *cb, ScrBytes *chunk) {
|
|
651
|
+
(void)chunk;
|
|
652
|
+
((void (*)(ScrClosure *))cb->fn)(cb);
|
|
653
|
+
}
|
|
654
|
+
void scr_stdin_data_thunk_bytes(ScrClosure *cb, ScrBytes *chunk) {
|
|
655
|
+
/* The listener owns its +1 param per the universal convention. */
|
|
656
|
+
((void (*)(ScrClosure *, ScrBytes *))cb->fn)(cb, scr_bytes_retain(chunk));
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
/* ── the loop hooks (see scr_async.c) ─────────────────────────────────── */
|
|
661
|
+
|
|
662
|
+
static bool scr_events_pending(void) { return scr_stdin_pending(); }
|
|
663
|
+
|
|
664
|
+
static bool scr_events_watching(void) {
|
|
665
|
+
return scr_sig_watched > 0 || scr_stdin_pending();
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/* One dispatch pass at a loop turn: wake-pipe bytes are consumed (safe
|
|
669
|
+
* any time), flagged signals fire, and stdin is probed/served. */
|
|
670
|
+
static void scr_events_dispatch(void) {
|
|
671
|
+
scr_wake_pipe_drain();
|
|
672
|
+
scr_signals_drain();
|
|
673
|
+
if (scr_exc_pending()) return;
|
|
674
|
+
scr_stdin_service();
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/* Fds the loop's idle poll(2) should watch (POLLIN): the wake pipe while
|
|
678
|
+
* any signal is watched, fd 0 while stdin has a consumer. */
|
|
679
|
+
static int scr_events_pollfds(int out[2]) {
|
|
680
|
+
int n = 0;
|
|
681
|
+
if (scr_sig_watched > 0 && scr_wake_pipe[0] >= 0) out[n++] = scr_wake_pipe[0];
|
|
682
|
+
if (scr_stdin_pending()) out[n++] = 0;
|
|
683
|
+
return n;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/* The atexit half of the 'exit' event: normal termination reports the
|
|
687
|
+
* abnormal-exit hint (0 unless the uncaught/unhandled reporters noted 1 —
|
|
688
|
+
* exactly when main returns 1). */
|
|
689
|
+
static void scr_exit_atexit(void) { scr_run_exit_listeners((double)scr_exit_code_hint_get()); }
|
|
690
|
+
|
|
691
|
+
/* Exit-time registry cleanup: listeners a program leaves registered at
|
|
692
|
+
* exit are Node-legitimate, not leaks — signal handlers for the process's
|
|
693
|
+
* whole life, and stdin listeners for events that never came (the
|
|
694
|
+
* data-wins-the-race shape leaves its once-'end'/'error' listeners
|
|
695
|
+
* parked). Registered BEFORE the exit-event atexit, so by LIFO the 'exit'
|
|
696
|
+
* listeners fire first, then everything releases, then the RC audit sees
|
|
697
|
+
* a clean heap. */
|
|
698
|
+
static void scr_events_cleanup_atexit(void) {
|
|
699
|
+
scr_sig_cleanup();
|
|
700
|
+
scr_stdin_settle_done();
|
|
701
|
+
scr_stdin_drop_listeners();
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
void scr_events_install(void) {
|
|
705
|
+
static bool installed = false;
|
|
706
|
+
if (installed) return;
|
|
707
|
+
installed = true;
|
|
708
|
+
atexit(scr_events_cleanup_atexit);
|
|
709
|
+
atexit(scr_exit_atexit);
|
|
710
|
+
scr_loop_set_events(&scr_events_pending, &scr_events_watching, &scr_events_dispatch,
|
|
711
|
+
&scr_events_pollfds);
|
|
712
|
+
scr_process_exit_hook = &scr_run_exit_listeners;
|
|
713
|
+
scr_stdin_destroy_hook = &scr_stdin_destroy;
|
|
714
|
+
}
|