mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33:01 +00:00 
			
		
		
		
	| @@ -171,7 +171,7 @@ static Janet cfun_array_push(int32_t argc, Janet *argv) { | |||||||
|     } |     } | ||||||
|     int32_t newcount = array->count - 1 + argc; |     int32_t newcount = array->count - 1 + argc; | ||||||
|     janet_array_ensure(array, newcount, 2); |     janet_array_ensure(array, newcount, 2); | ||||||
|     if (argc > 1) memcpy(array->data + array->count, argv + 1, (size_t) (argc - 1) * sizeof(Janet)); |     if (argc > 1) memcpy(array->data + array->count, argv + 1, (size_t)(argc - 1) * sizeof(Janet)); | ||||||
|     array->count = newcount; |     array->count = newcount; | ||||||
|     return argv[0]; |     return argv[0]; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -150,6 +150,13 @@ DEFINE_OPTLEN(buffer, BUFFER, JanetBuffer *) | |||||||
| DEFINE_OPTLEN(table, TABLE, JanetTable *) | DEFINE_OPTLEN(table, TABLE, JanetTable *) | ||||||
| DEFINE_OPTLEN(array, ARRAY, JanetArray *) | DEFINE_OPTLEN(array, ARRAY, JanetArray *) | ||||||
|  |  | ||||||
|  | const char *janet_optcstring(const Janet *argv, int32_t argc, int32_t n, const char *dflt) { | ||||||
|  |     if (n >= argc || janet_checktype(argv[n], JANET_NIL)) { | ||||||
|  |         return dflt; | ||||||
|  |     } | ||||||
|  |     return janet_getcstring(argv, n); | ||||||
|  | } | ||||||
|  |  | ||||||
| #undef DEFINE_GETTER | #undef DEFINE_GETTER | ||||||
| #undef DEFINE_OPT | #undef DEFINE_OPT | ||||||
| #undef DEFINE_OPTLEN | #undef DEFINE_OPTLEN | ||||||
|   | |||||||
| @@ -492,7 +492,7 @@ void *janet_smalloc(size_t size) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void *janet_scalloc(size_t nmemb, size_t size) { | void *janet_scalloc(size_t nmemb, size_t size) { | ||||||
|     if (nmemb && size > (size_t)-1/size) { |     if (nmemb && size > (size_t) -1 / size) { | ||||||
|         JANET_OUT_OF_MEMORY; |         JANET_OUT_OF_MEMORY; | ||||||
|     } |     } | ||||||
|     size_t n = nmemb * size; |     size_t n = nmemb * size; | ||||||
|   | |||||||
| @@ -52,6 +52,9 @@ | |||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include <sys/wait.h> | #include <sys/wait.h> | ||||||
| extern char **environ; | extern char **environ; | ||||||
|  | #ifdef JANET_THREADS | ||||||
|  | #include <pthread.h> | ||||||
|  | #endif | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /* For macos */ | /* For macos */ | ||||||
| @@ -66,6 +69,34 @@ extern char **environ; | |||||||
| void arc4random_buf(void *buf, size_t nbytes); | void arc4random_buf(void *buf, size_t nbytes); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | /* Access to some global variables should be synchronized if not in single threaded mode, as | ||||||
|  |  * setenv/getenv are not thread safe. */ | ||||||
|  | #ifdef JANET_THREADS | ||||||
|  | # ifdef JANET_WINDOWS | ||||||
|  | static int env_lock_initialized = 0; | ||||||
|  | static CRITICAL_SECTION env_lock; | ||||||
|  | static void janet_lock_environ(void) { | ||||||
|  |     EnterCriticalSection(env_lock); | ||||||
|  | } | ||||||
|  | static void janet_unlock_environ(void) { | ||||||
|  |     LeaveCriticalSection(env_lock); | ||||||
|  | } | ||||||
|  | # else | ||||||
|  | static pthread_mutex_t env_lock = PTHREAD_MUTEX_INITIALIZER; | ||||||
|  | static void janet_lock_environ(void) { | ||||||
|  |     pthread_mutex_lock(&env_lock); | ||||||
|  | } | ||||||
|  | static void janet_unlock_environ(void) { | ||||||
|  |     pthread_mutex_unlock(&env_lock); | ||||||
|  | } | ||||||
|  | # endif | ||||||
|  | #else | ||||||
|  | static void janet_lock_environ(void) { | ||||||
|  | } | ||||||
|  | static void janet_unlock_environ(void) { | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #endif /* JANET_REDCUED_OS */ | #endif /* JANET_REDCUED_OS */ | ||||||
|  |  | ||||||
| /* Core OS functions */ | /* Core OS functions */ | ||||||
| @@ -386,6 +417,7 @@ static Janet os_environ(int32_t argc, Janet *argv) { | |||||||
|     (void) argv; |     (void) argv; | ||||||
|     janet_fixarity(argc, 0); |     janet_fixarity(argc, 0); | ||||||
|     int32_t nenv = 0; |     int32_t nenv = 0; | ||||||
|  |     janet_lock_environ(); | ||||||
|     char **env = environ; |     char **env = environ; | ||||||
|     while (*env++) |     while (*env++) | ||||||
|         nenv += 1; |         nenv += 1; | ||||||
| @@ -393,7 +425,10 @@ static Janet os_environ(int32_t argc, Janet *argv) { | |||||||
|     for (int32_t i = 0; i < nenv; i++) { |     for (int32_t i = 0; i < nenv; i++) { | ||||||
|         char *e = environ[i]; |         char *e = environ[i]; | ||||||
|         char *eq = strchr(e, '='); |         char *eq = strchr(e, '='); | ||||||
|         if (!eq) janet_panic("no '=' in environ"); |         if (!eq) { | ||||||
|  |             janet_unlock_environ(); | ||||||
|  |             janet_panic("no '=' in environ"); | ||||||
|  |         } | ||||||
|         char *v = eq + 1; |         char *v = eq + 1; | ||||||
|         int32_t full_len = (int32_t) strlen(e); |         int32_t full_len = (int32_t) strlen(e); | ||||||
|         int32_t val_len = (int32_t) strlen(v); |         int32_t val_len = (int32_t) strlen(v); | ||||||
| @@ -403,6 +438,7 @@ static Janet os_environ(int32_t argc, Janet *argv) { | |||||||
|             janet_stringv((const uint8_t *)v, val_len) |             janet_stringv((const uint8_t *)v, val_len) | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  |     janet_unlock_environ(); | ||||||
|     return janet_wrap_table(t); |     return janet_wrap_table(t); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -410,11 +446,14 @@ static Janet os_getenv(int32_t argc, Janet *argv) { | |||||||
|     janet_arity(argc, 1, 2); |     janet_arity(argc, 1, 2); | ||||||
|     const char *cstr = janet_getcstring(argv, 0); |     const char *cstr = janet_getcstring(argv, 0); | ||||||
|     const char *res = getenv(cstr); |     const char *res = getenv(cstr); | ||||||
|     return res |     janet_lock_environ(); | ||||||
|            ? janet_cstringv(res) |     Janet ret = res | ||||||
|            : argc == 2 |                 ? janet_cstringv(res) | ||||||
|            ? argv[1] |                 : argc == 2 | ||||||
|            : janet_wrap_nil(); |                 ? argv[1] | ||||||
|  |                 : janet_wrap_nil(); | ||||||
|  |     janet_unlock_environ(); | ||||||
|  |     return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| static Janet os_setenv(int32_t argc, Janet *argv) { | static Janet os_setenv(int32_t argc, Janet *argv) { | ||||||
| @@ -427,11 +466,14 @@ static Janet os_setenv(int32_t argc, Janet *argv) { | |||||||
| #endif | #endif | ||||||
|     janet_arity(argc, 1, 2); |     janet_arity(argc, 1, 2); | ||||||
|     const char *ks = janet_getcstring(argv, 0); |     const char *ks = janet_getcstring(argv, 0); | ||||||
|     if (argc == 1 || janet_checktype(argv[1], JANET_NIL)) { |     const char *vs = janet_optcstring(argv, argc, 1, NULL); | ||||||
|  |     janet_lock_environ(); | ||||||
|  |     if (NULL == vs) { | ||||||
|         UNSETENV(ks); |         UNSETENV(ks); | ||||||
|     } else { |     } else { | ||||||
|         SETENV(ks, janet_getcstring(argv, 1)); |         SETENV(ks, vs); | ||||||
|     } |     } | ||||||
|  |     janet_unlock_environ(); | ||||||
|     return janet_wrap_nil(); |     return janet_wrap_nil(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1085,5 +1127,13 @@ static const JanetReg os_cfuns[] = { | |||||||
|  |  | ||||||
| /* Module entry point */ | /* Module entry point */ | ||||||
| void janet_lib_os(JanetTable *env) { | void janet_lib_os(JanetTable *env) { | ||||||
|  | #if !defined(JANET_REDUCED_OS) && defined(JANET_WINDOWS) && defined(JANET_THREADS) | ||||||
|  |     /* During start up, the top-most abstract machine (thread) | ||||||
|  |      * in the thread tree sets up the critical section. */ | ||||||
|  |     if (!env_lock_initialized) { | ||||||
|  |         InitializeCriticalSection(env_lock); | ||||||
|  |         env_lock_initialized = 1; | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|     janet_core_cfuns(env, NULL, os_cfuns); |     janet_core_cfuns(env, NULL, os_cfuns); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose