in reply to Re^5: Standard way to convert timezone in multithreaded script
in thread Standard way to convert timezone in multithreaded script

My environment is CentOS 5.2, libc-2.5, perl-5.10.0

I've been playing with 5.10.1 under Ubuntu 9.10:

mehere@mehere-desktop:~/test$ gcc --version gcc (Ubuntu 4.4.1-4ubuntu8) 4.4.1 Copyright (C) 2009 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There i +s NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR +POSE.

...but, as a guest running within a VirtualBox on a Vista host.

Ie. I have little faith that anything that works (or fails) here will produce the same results under any other circumstances :)

(P.S.) You aren't the first to be bitten by the "malloc thing" in XS code. Truth beknown--if they'd all admit to it--we've all been there.

Your discovery regarding not requiring tzset() in the main thread are interesting. It stimulates several possibilities. And when I am less sleep deprived, I may persue them to a (minorly) significant conclusion.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP PCW It is as I've been saying!(Audio until 20090817)

Replies are listed 'Best First'.
Re^7: Standard way to convert timezone in multithreaded script
by whale2 (Novice) on Nov 25, 2009 at 15:03 UTC
    this XS proved to work:
    #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include <time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> MODULE = tztime PACKAGE = tztime long tz_mktime(sec, min, hour, mday, mon, year, tz_name) int sec int min int hour int mday int mon int year char *tz_name CODE: long epoch; struct tm tz_tm; char *old_tz; const char *tz_p; bool restore = FALSE; tz_tm.tm_sec = sec; tz_tm.tm_min = min; tz_tm.tm_hour = hour; tz_tm.tm_mday = mday; tz_tm.tm_mon = mon; tz_tm.tm_year = year; tz_tm.tm_wday = 0; tz_tm.tm_yday = 0; tz_tm.tm_isdst = -1; tz_p = getenv("TZ"); if(tz_p != NULL) { restore = TRUE; old_tz = malloc(strlen(tz_p) + 1); if(old_tz == NULL) { XSRETURN_UNDEF; } strncpy(old_tz,tz_p,strlen(tz_p) + 1); } setenv("TZ",tz_name,1); tzset(); epoch = (long)mktime(&tz_tm); if(restore) { putenv(old_tz); free(old_tz); } else { unsetenv("TZ"); } tzset(); RETVAL = epoch; OUTPUT: RETVAL void tz_gettime(epoch, tz_name) long epoch char *tz_name; PPCODE: struct tm tz_tm; char *old_tz; const char *tz_p; bool restore = FALSE; tz_p = getenv("TZ"); if(tz_p != NULL) { restore = TRUE; old_tz = malloc(strlen(tz_p) + 1); if(old_tz == NULL) { XPUSHs(sv_2mortal(newSVnv(errno))); } strncpy(old_tz,tz_p,strlen(tz_p) + 1); } setenv("TZ",tz_name,1); tzset(); localtime_r(&epoch,&tz_tm); if(restore) { putenv(old_tz); free(old_tz); } else { unsetenv("TZ"); } tzset(); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_sec))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_min))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_hour))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_mday))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_mon))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_year))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_wday))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_yday))); XPUSHs(sv_2mortal(newSVnv(tz_tm.tm_isdst)));