Skip to content

Commit

Permalink
Avoid malloc dependency in tzset (#21375)
Browse files Browse the repository at this point in the history
  • Loading branch information
sbc100 authored Feb 20, 2024
1 parent d67fa99 commit 4856d55
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/generated_struct_info32.json
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@
"TIOCGWINSZ": 21523,
"TIOCSPGRP": 21520,
"TIOCSWINSZ": 21524,
"TZNAME_MAX": 6,
"UUID_TYPE_DCE_RANDOM": 4,
"UUID_VARIANT_DCE": 1,
"W_OK": 2,
Expand Down
1 change: 1 addition & 0 deletions src/generated_struct_info64.json
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@
"TIOCGWINSZ": 21523,
"TIOCSPGRP": 21520,
"TIOCSWINSZ": 21524,
"TZNAME_MAX": 6,
"UUID_TYPE_DCE_RANDOM": 4,
"UUID_VARIANT_DCE": 1,
"W_OK": 2,
Expand Down
23 changes: 12 additions & 11 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -604,19 +604,22 @@ addToLibrary({
return ret;
},
_tzset_js__deps: ['$stringToNewUTF8'],
_tzset_js__deps: ['$stringToUTF8'],
_tzset_js__internal: true,
_tzset_js: (timezone, daylight, tzname) => {
_tzset_js: (timezone, daylight, std_name, dst_name) => {
// TODO: Use (malleable) environment variables instead of system settings.
var currentYear = new Date().getFullYear();
var winter = new Date(currentYear, 0, 1);
var summer = new Date(currentYear, 6, 1);
var winterOffset = winter.getTimezoneOffset();
var summerOffset = summer.getTimezoneOffset();
// Local standard timezone offset. Local standard time is not adjusted for daylight savings.
// This code uses the fact that getTimezoneOffset returns a greater value during Standard Time versus Daylight Saving Time (DST).
// Thus it determines the expected output during Standard Time, and it compares whether the output of the given date the same (Standard) or less (DST).
// Local standard timezone offset. Local standard time is not adjusted for
// daylight savings. This code uses the fact that getTimezoneOffset returns
// a greater value during Standard Time versus Daylight Saving Time (DST).
// Thus it determines the expected output during Standard Time, and it
// compares whether the output of the given date the same (Standard) or less
// (DST).
var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
// timezone is specified as seconds west of UTC ("The external variable
Expand All @@ -634,15 +637,13 @@ addToLibrary({
};
var winterName = extractZone(winter);
var summerName = extractZone(summer);
var winterNamePtr = stringToNewUTF8(winterName);
var summerNamePtr = stringToNewUTF8(summerName);
if (summerOffset < winterOffset) {
// Northern hemisphere
{{{ makeSetValue('tzname', '0', 'winterNamePtr', POINTER_TYPE) }}};
{{{ makeSetValue('tzname', POINTER_SIZE, 'summerNamePtr', POINTER_TYPE) }}};
stringToUTF8(winterName, std_name, {{{ cDefs.TZNAME_MAX + 1 }}});
stringToUTF8(summerName, dst_name, {{{ cDefs.TZNAME_MAX + 1 }}});
} else {
{{{ makeSetValue('tzname', '0', 'summerNamePtr', POINTER_TYPE) }}};
{{{ makeSetValue('tzname', POINTER_SIZE, 'winterNamePtr', POINTER_TYPE) }}};
stringToUTF8(winterName, dst_name, {{{ cDefs.TZNAME_MAX + 1 }}});
stringToUTF8(summerName, std_name, {{{ cDefs.TZNAME_MAX + 1 }}});
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/library_sigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ sigs = {
_munmap_js__sig: 'ippiiij',
_setitimer_js__sig: 'iid',
_timegm_js__sig: 'jp',
_tzset_js__sig: 'vppp',
_tzset_js__sig: 'vpppp',
_wasmfs_copy_preloaded_file_data__sig: 'vip',
_wasmfs_create_fetch_backend_js__sig: 'vp',
_wasmfs_create_js_file_backend_js__sig: 'vp',
Expand Down
6 changes: 6 additions & 0 deletions src/struct_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@
"X_OK"
]
},
{
"file": "limits.h",
"defines": [
"TZNAME_MAX"
]
},
{
"file": "bits/errno.h",
"defines": [
Expand Down
2 changes: 1 addition & 1 deletion system/lib/libc/emscripten_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ time_t _mktime_js(struct tm* tm);
void _localtime_js(time_t t, struct tm* __restrict__ tm);
void _gmtime_js(time_t t, struct tm* __restrict__ tm);

void _tzset_js(long* timezone, int* daylight, char** tzname);
void _tzset_js(long* timezone, int* daylight, char* std_name, char* dst_name);

const char* emscripten_pc_get_function(uintptr_t pc);
const char* emscripten_pc_get_file(uintptr_t pc);
Expand Down
8 changes: 7 additions & 1 deletion system/lib/libc/tzset.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,25 @@
* University of Illinois/NCSA Open Source License. Both these licenses can be
* found in the LICENSE file.
*/
#include <limits.h>
#include <time.h>
#include <stdbool.h>
#include <pthread.h>

#include "emscripten_internal.h"

static char std_name[TZNAME_MAX+1];
static char dst_name[TZNAME_MAX+1];

weak void tzset() {
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static _Atomic bool done_init = false;
if (!done_init) {
pthread_mutex_lock(&lock);
if (!done_init) {
_tzset_js(&timezone, &daylight, tzname);
_tzset_js(&timezone, &daylight, std_name, dst_name);
tzname[0] = std_name;
tzname[1] = dst_name;
done_init = true;
}
pthread_mutex_unlock(&lock);
Expand Down
2 changes: 1 addition & 1 deletion test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -5663,7 +5663,7 @@ def test_only_force_stdlibs(self, env, fail):
with env_modify(env):
if fail:
err = self.expect_fail(cmd)
self.assertContained('undefined symbol: malloc', err)
self.assertContained('undefined symbol: emscripten_builtin_memalign', err)
else:
err = self.run_process(cmd, stderr=PIPE).stderr
if 'EMCC_ONLY_FORCED_STDLIBS' in env:
Expand Down

0 comments on commit 4856d55

Please sign in to comment.