Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible bug using POSIX::strftime Digital UNIX Perl 5.005_03 #514

Closed
p5pRT opened this issue Sep 13, 1999 · 7 comments
Closed

Possible bug using POSIX::strftime Digital UNIX Perl 5.005_03 #514

p5pRT opened this issue Sep 13, 1999 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 13, 1999

Migrated from rt.perl.org#1361 (status was 'resolved')

Searchable as RT1361$

@p5pRT
Copy link
Author

p5pRT commented Sep 13, 1999

From phil@finchcomputer.com

I believe I have found a bug in Perl > 5.004_04 (possibly only Perl
5.005+) using POSIX​::strftime. I've been using POSIX​::strftime to
print out formatted times obtained through Perl's gmtime call.
Everything is fine when not going through strftime
(i.e. scalar(gmtime)) or using Perl 5.004_01-5.004_04, but when format
the times through strftime 5.005_03 it seems to get confused about
daylight savings times even though I'm passing it a full array from
gmtime.

The problem seems to be that strftime C module calls mktime() which
sets (or actually improperly re-sets) "isdst" in the data structure I
passed to it causing time to be 1 hour off with data structures that
would land within my DST period. I think stftime shouldn't be calling
mktime but I'm not 100% sure. This didn't used to happen (perl
5.004_01-03 anyway) and with 5.005 it breaks my database application.

Should I not use strftime? Is strftime supposed to call mktime? It
seems a bit dangerous to assume the programmer actually wants this
behavior but maybe I'm missing something here.

The *real* world where I've run into problems, gmtime sets tm_isdst to
0 appropriately, but using POSIX​::strftime make things look like
daylight savings time apparently!

% /opt/dtv/bin/perl -e '@​tmp=gmtime;use POSIX; print scalar(gmtime),
  " or (@​tmp)\n",POSIX​::strftime("%Y %m %d %H​:%M​:%S", @​tmp), "\n"' ;
  Fri Sep 3 00​:46​:11 1999 or (11 46 0 3 8 99 5 245 0)
  1999 09 03 01​:46​:11

% /opt/dtv/bin/perl -e '@​tmp=gmtime;use POSIX; print scalar(gmtime),
  " or (@​tmp) ",POSIX​::strftime("%Y %m %d %H​:%M​:%S", @​tmp), "\n"' ;
  Fri Sep 3 00​:57​:37 1999 or (37 57 0 3 8 99 5 245 0)
  1999 09 03 01​:57​:37

The equivalent C code that works without this problem.

Details, including output from perlbug below, and I believe I've found
a fix for it (not sure if it's the proper fix or not since I may be
missing somethinge here) the diff is included below...

Phil
--
Phillip E. Lobbes http​://www.finchcomputer.com/ (818)550-9060
phil@​finchcomputer.com

Details...

* The system (Digital UNIX 4, Perl 5.005_03)​:
  bambam% uname -a
  OSF1 bambam V4.0 1091 alpha

* The problematic type of Perl program (NOTE​: note 1hr difference!)​:
  #!/opt/dtv/bin/perl
  use POSIX;
  @​tmp=gmtime;
  print(scalar(gmtime), " or (@​tmp)\n",
  POSIX​::strftime("%Y %m %d %H​:%M​:%S", @​tmp),
  "\n");
  Fri Sep 3 00​:46​:11 1999 or (11 46 0 3 8 99 5 245 0)
  1999 09 03 01​:46​:11

* Sample C code that works...
  #include <time.h>
  #include <stdio.h>
  #define SLENGTH 80
 
  main() {
  char nowstr[SLENGTH];
  time_t nowbin;
  const struct tm *nowstruct;
 
  if (time(&nowbin) == (time_t) - 1)
  printf("Could not get time of day from time()\n");
 
  nowstruct = gmtime(&nowbin);
  printf("isdst bef %d\n", nowstruct->tm_isdst);
  if (strftime(nowstr, SLENGTH, "%Y %m %d %H​:%M​:%S", nowstruct) ==
  (size_t) 0)
  printf("Could not get string from strftime()\n");
  printf("Today's date gm bef is %s\n", nowstr);
 
  mktime(nowstruct);
  printf("isdst aft %d\n", nowstruct->tm_isdst);
  if (strftime(nowstr, SLENGTH, "%Y %m %d %H​:%M​:%S", nowstruct) ==
  (size_t) 0)
  printf("Could not get string from strftime()\n");
 
  printf("Today's date gm aft is %s\n", nowstr);
  }

* Output from the system date call and from the C code. The first time
  is the expected time, the second time emulates the Perl POSIX module
  behavior...

  % date -u
  Mon Sep 13 21​:34​:52 UTC 1999
  % a.out
  isdst bef 0
  Today's date gm bef is 1999 09 13 21​:34​:53
  isdst aft 1
  Today's date gm aft is 1999 09 13 22​:34​:53

* POSSIBLE FIX​: Output from diff directory is perl5.005_03/ext/POSIX...
  % diff POSIX.xs POSIX.xs.ORIG
  3632c3632
  < /* BAD resets ISDST settings​: (void) mktime(&mytm); */
  ---
  > (void) mktime(&mytm);

* bambam% /opt/dtv/perl/5.005_03/bin/perlbug -d -v
Site configuration information for perl 5.00503​:

Configured by lobbesp at Mon Jul 19 10​:56​:06 PDT 1999.

Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration​:
  Platform​:
  osname=dec_osf, osvers=4.0, archname=alpha-dec_osf
  uname='osf1 bambam v4.0 1091 alpha '
  hint=recommended, useposix=true, d_sigaction=define
  usethreads=undef useperlio=undef d_sfio=undef
  Compiler​:
  cc='cc', optimize='-O4', gccversion=
  cppflags='-std -ieee -D_INTRINSICS -I/usr/local/include -I/opt/local/include -DLANGUAGE_C'
  ccflags ='-std -fprm d -ieee -D_INTRINSICS -I/usr/local/include -I/opt/local/include -DLANGUAGE_C'
  stdchar='unsigned char', d_stdstdio=define, usevfork=false
  intsize=4, longsize=8, ptrsize=8, doublesize=8
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
  alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries​:
  ld='ld', ldflags =' -L/usr/local/lib -L/opt/local/lib'
  libpth=/usr/local/lib /opt/local/lib /usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /var/shlib
  libs=-ldbm -ldb -lm
  libc=/usr/shlib/libc.so, so=so, useshrplib=true, libperl=libperl.so
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' -Wl,-rpath,/opt/dtv/perl/5.005_03/lib/5.00503/alpha-dec_osf/CORE'
  cccdlflags=' ', lddlflags='-shared -expect_unresolved "*" -O4 -msym -s -L/usr/local/lib -L/opt/local/lib'

Locally applied patches​:
 


@​INC for perl 5.00503​:
  /opt/dtv/perl/5.005_03/lib/5.00503/alpha-dec_osf
  /opt/dtv/perl/5.005_03/lib/5.00503
  /opt/dtv/perl/5.005_03/lib/site_perl/5.005/alpha-dec_osf
  /opt/dtv/perl/5.005_03/lib/site_perl/5.005
  .


Environment for perl 5.00503​:
  HOME=/home/lobbesp
  LANG (unset)
  LANGUAGE (unset)
  LD_LIBRARY_PATH=/oracle/app/oracle/product/8.0.5/lib
  LOGDIR (unset)
  PATH=/home/lobbesp/bin​:/home/lobbesp/X/bin​:/home/lobbesp/scripts​:/usr/bin​:.​:/oracle/app/oracle/product/8.0.5/bin​:/oracle/app/oracle/product/8.0.5/obackup/bin​:/sbin​:/usr/sbin​:/usr/bin/X11​:/usr/ccs/bin​:/home/lobbesp/site/bin​:/home/lobbesp/scripts​:/usr/local/bin​:/opt/dtv/bin​:/usr/dt​:.
  PERL_BADLANG (unset)
  SHELL=/usr/local/bin/tcsh

Complete configuration data for perl 5.00503​:

Author=''
CONFIG='true'
Date='$Date'
Header=''
Id='$Id'
Locker=''
Log='$Log'
Mcc='Mcc'
PATCHLEVEL='5'
RCSfile='$RCSfile'
Revision='$Revision'
SUBVERSION='3'
Source=''
State=''
_a='.a'
_exe=''
_o='.o'
afs='false'
alignbytes='8'
ansi2knr=''
aphostname=''
apiversion='5.005'
ar='ar'
archlib='/opt/dtv/perl/5.005_03/lib/5.00503/alpha-dec_osf'
archlibexp='/opt/dtv/perl/5.005_03/lib/5.00503/alpha-dec_osf'
archname='alpha-dec_osf'
archobjs=''
awk='awk'
baserev='5.0'
bash=''
bin='/opt/dtv/perl/5.005_03/bin'
binexp='/opt/dtv/perl/5.005_03/bin'
bison=''
byacc='byacc'
byteorder='12345678'
c='\c'
castflags='0'
cat='cat'
cc='cc'
cccdlflags=' '
ccdlflags=' -Wl,-rpath,/opt/dtv/perl/5.005_03/lib/5.00503/alpha-dec_osf/CORE'
ccflags='-std -fprm d -ieee -D_INTRINSICS -I/usr/local/include -I/opt/local/include -DLANGUAGE_C'
ccsymbols='LANGUAGE_C=1 SYSTYPE_BSD=1 _LONGLONG=1 __ALPHA=1 __Alpha_AXP=1 __DATE__="Jul __DECC=1 __DECC_MODE_COMMON=1 __DECC_VER=50890011 __IEEE_FLOAT=1 __INITIAL_POINTER_SIZE=0 __LANGUAGE_C__=1 __PRAGMA_ENVIRONMENT=1 __TIME__="10​:57​:09" __X_FLOAT=0'
cf_by='lobbesp'
cf_email='lobbesp@​bambam.directv.com'
cf_time='Mon Jul 19 10​:56​:06 PDT 1999'
chgrp=''
chmod=''
chown=''
clocktype='clock_t'
comm='comm'
compress=''
config_arg0='Configure'
config_arg1='-ds'
config_arg2='-e'
config_arg3='-Dprefix=/opt/dtv/perl/5.005_03'
config_argc='3'
config_args='-ds -e -Dprefix=/opt/dtv/perl/5.005_03'
contains='grep'
cp='cp'
cpio=''
cpp='cpp'
cpp_stuff='42'
cppccsymbols='_SYSTYPE_BSD=1 __alpha=1 __osf__=1 __unix__=1 unix=1'
cppflags='-std -ieee -D_INTRINSICS -I/usr/local/include -I/opt/local/include -DLANGUAGE_C'
cpplast=''
cppminus=''
cpprun='/usr/bin/cpp'
cppstdin='cppstdin'
cppsymbols=''
cryptlib=''
csh='csh'
d_Gconvert='gcvt((x),(n),(b))'
d_access='define'
d_alarm='define'
d_archlib='define'
d_attribut=''
d_bcmp='define'
d_bcopy='define'
d_bsd=''
d_bsdgetpgrp=''
d_bsdsetpgrp='define'
d_bzero='define'
d_casti32=''
d_castneg='define'
d_charvspr=''
d_chown='define'
d_chroot='define'
d_chsize=''
d_closedir='define'
d_const='define'
d_crypt='define'
d_csh='define'
d_cuserid='define'
d_dbl_dig='define'
d_difftime='define'
d_dirnamlen='define'
d_dlerror='define'
d_dlopen='define'
d_dlsymun=''
d_dosuid=''
d_dup2='define'
d_endgrent='define'
d_endhent='define'
d_endnent='define'
d_endpent='define'
d_endpwent='define'
d_endsent='define'
d_eofnblk='define'
d_eunice=''
d_fchmod='define'
d_fchown='define'
d_fcntl='define'
d_fd_macros='define'
d_fd_set='define'
d_fds_bits='define'
d_fgetpos='define'
d_flexfnam='define'
d_flock='define'
d_fork='define'
d_fpathconf='define'
d_fsetpos='define'
d_fstatfs='define'
d_fstatvfs='define'
d_ftime=''
d_getgrent='define'
d_getgrps='define'
d_gethbyaddr='define'
d_gethbyname='define'
d_gethent='define'
d_gethname=''
d_gethostprotos='define'
d_getlogin='define'
d_getmntent=''
d_getnbyaddr='define'
d_getnbyname='define'
d_getnent='define'
d_getnetprotos='define'
d_getpbyname='define'
d_getpbynumber='define'
d_getpent='define'
d_getpgid='define'
d_getpgrp='define'
d_getpgrp2=''
d_getppid='define'
d_getprior='define'
d_getprotoprotos='define'
d_getpwent='define'
d_getsbyname='define'
d_getsbyport='define'
d_getsent='define'
d_getservprotos='define'
d_gettimeod='define'
d_gnulibc=''
d_grpasswd='define'
d_hasmntopt=''
d_htonl='define'
d_index=''
d_inetaton='define'
d_isascii='define'
d_killpg='define'
d_lchown='define'
d_link='define'
d_locconv='define'
d_lockf='define'
d_longdbl='define'
d_longlong='define'
d_lstat='define'
d_mblen='define'
d_mbstowcs='define'
d_mbtowc='define'
d_memcmp='define'
d_memcpy='define'
d_memmove='define'
d_memset='define'
d_mkdir='define'
d_mkfifo='define'
d_mktime='define'
d_msg='define'
d_msgctl='define'
d_msgget='define'
d_msgrcv='define'
d_msgsnd='define'
d_mymalloc='define'
d_nice='define'
d_oldpthreads=''
d_oldsock=''
d_open3='define'
d_pathconf='define'
d_pause='define'
d_phostname=''
d_pipe='define'
d_poll='define'
d_portable='define'
d_pthread_yield=''
d_pthreads_created_joinable=''
d_pwage=''
d_pwchange=''
d_pwclass=''
d_pwcomment='define'
d_pwexpire=''
d_pwgecos='define'
d_pwpasswd='define'
d_pwquota='define'
d_readdir='define'
d_readlink='define'
d_rename='define'
d_rewinddir='define'
d_rmdir='define'
d_safebcpy='define'
d_safemcpy='define'
d_sanemcmp='define'
d_sched_yield='define'
d_seekdir='define'
d_select='define'
d_sem='define'
d_semctl='define'
d_semctl_semid_ds='define'
d_semctl_semun='define'
d_semget='define'
d_semop='define'
d_setegid='define'
d_seteuid='define'
d_setgrent='define'
d_setgrps='define'
d_sethent='define'
d_setlinebuf='define'
d_setlocale='define'
d_setnent='define'
d_setpent='define'
d_setpgid='define'
d_setpgrp='define'
d_setpgrp2=''
d_setprior='define'
d_setpwent='define'
d_setregid='define'
d_setresgid=''
d_setresuid=''
d_setreuid='define'
d_setrgid='define'
d_setruid='define'
d_setsent='define'
d_setsid='define'
d_setvbuf='define'
d_sfio=''
d_shm='define'
d_shmat='define'
d_shmatprototype='define'
d_shmctl='define'
d_shmdt='define'
d_shmget='define'
d_sigaction='define'
d_sigsetjmp='define'
d_socket='define'
d_sockpair='define'
d_statblks='define'
d_statfsflags='define'
d_stdio_cnt_lval='define'
d_stdio_ptr_lval='define'
d_stdiobase='define'
d_stdstdio='define'
d_strchr='define'
d_strcoll='define'
d_strctcpy='define'
d_strerrm='strerror(e)'
d_strerror='define'
d_strtod='define'
d_strtol='define'
d_strtoul='define'
d_strxfrm='define'
d_suidsafe=''
d_symlink='define'
d_syscall='define'
d_sysconf='define'
d_sysernlst=''
d_syserrlst='define'
d_system='define'
d_tcgetpgrp='define'
d_tcsetpgrp='define'
d_telldir='define'
d_time='define'
d_times='define'
d_truncate='define'
d_tzname='define'
d_umask='define'
d_uname='define'
d_union_semun=''
d_vfork=''
d_void_closedir=''
d_voidsig='define'
d_voidtty=''
d_volatile='define'
d_vprintf='define'
d_wait4='define'
d_waitpid='define'
d_wcstombs='define'
d_wctomb='define'
d_xenix=''
date='date'
db_hashtype='u_int32_t'
db_prefixtype='size_t'
defvoidused='15'
direntrytype='struct dirent'
dlext='so'
dlsrc='dl_dlopen.xs'
doublesize='8'
dynamic_ext='B DB_File Data/Dumper Fcntl IO IPC/SysV NDBM_File ODBM_File Opcode POSIX SDBM_File Socket attrs re'
eagain='EAGAIN'
ebcdic=''
echo='echo'
egrep='egrep'
emacs=''
eunicefix='​:'
exe_ext=''
expr='expr'
extensions='B DB_File Data/Dumper Fcntl IO IPC/SysV NDBM_File ODBM_File Opcode POSIX SDBM_File Socket attrs re Errno'
find='find'
firstmakefile='makefile'
flex=''
fpostype='fpos_t'
freetype='void'
full_ar='/usr/bin/ar'
full_csh='/usr/bin/csh'
full_sed='/usr/bin/sed'
gccversion=''
gidtype='gid_t'
glibpth='/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib'
grep='grep'
groupcat='cat /etc/group'
groupstype='gid_t'
gzip='gzip'
h_fcntl='false'
h_sysfile='true'
hint='recommended'
hostcat='ypcat hosts'
huge=''
i_arpainet='define'
i_bsdioctl=''
i_db='define'
i_dbm='define'
i_dirent='define'
i_dld=''
i_dlfcn='define'
i_fcntl=''
i_float='define'
i_gdbm=''
i_grp='define'
i_limits='define'
i_locale='define'
i_machcthreads=''
i_malloc='define'
i_math='define'
i_memory=''
i_mntent=''
i_ndbm='define'
i_netdb='define'
i_neterrno=''
i_niin='define'
i_pthread='define'
i_pwd='define'
i_rpcsvcdbm=''
i_sfio=''
i_sgtty=''
i_stdarg='define'
i_stddef='define'
i_stdlib='define'
i_string='define'
i_sysdir='define'
i_sysfile='define'
i_sysfilio=''
i_sysin=''
i_sysioctl='define'
i_sysmount='define'
i_sysndir=''
i_sysparam='define'
i_sysresrc='define'
i_sysselct='define'
i_syssockio=''
i_sysstat='define'
i_sysstatvfs='define'
i_systime='define'
i_systimek=''
i_systimes='define'
i_systypes='define'
i_sysun='define'
i_syswait='define'
i_termio=''
i_termios='define'
i_time=''
i_unistd='define'
i_utime='define'
i_values='define'
i_varargs=''
i_varhdr='stdarg.h'
i_vfork=''
ignore_versioned_solibs=''
incpath=''
inews=''
installarchlib='/opt/dtv/perl/5.005_03/lib/5.00503/alpha-dec_osf'
installbin='/opt/dtv/perl/5.005_03/bin'
installman1dir='/opt/dtv/perl/5.005_03/man/man1'
installman3dir='/opt/dtv/perl/5.005_03/man/man3'
installprivlib='/opt/dtv/perl/5.005_03/lib/5.00503'
installscript='/opt/dtv/perl/5.005_03/bin'
installsitearch='/opt/dtv/perl/5.005_03/lib/site_perl/5.005/alpha-dec_osf'
installsitelib='/opt/dtv/perl/5.005_03/lib/site_perl/5.005'
installusrbinperl='define'
intsize='4'
known_extensions='B DB_File Data/Dumper Fcntl GDBM_File IO IPC/SysV NDBM_File ODBM_File Opcode POSIX SDBM_File Socket Thread attrs re'
ksh=''
large=''
ld='ld'
lddlflags='-shared -expect_unresolved "*" -O4 -msym -s -L/usr/local/lib -L/opt/local/lib'
ldflags=' -L/usr/local/lib -L/opt/local/lib'
less='less'
lib_ext='.a'
libc='/usr/shlib/libc.so'
libperl='libperl.so'
libpth='/usr/local/lib /opt/local/lib /usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /var/shlib'
libs='-ldbm -ldb -lm'
libswanted='sfio socket inet nsl nm gdbm dbm db malloc dld ld sun m cposix posix ndir dir crypt ucb BSD x'
line='line'
lint=''
lkflags=''
ln='ln'
lns='/usr/bin/ln -s'
locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include'
loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib'
longdblsize='8'
longlongsize='8'
longsize='8'
lp=''
lpr=''
ls='ls'
lseektype='off_t'
mail=''
mailx=''
make='make'
make_set_make='#'
mallocobj='malloc.o'
mallocsrc='malloc.c'
malloctype='void *'
man1dir='/opt/dtv/perl/5.005_03/man/man1'
man1direxp='/opt/dtv/perl/5.005_03/man/man1'
man1ext='1'
man3dir='/opt/dtv/perl/5.005_03/man/man3'
man3direxp='/opt/dtv/perl/5.005_03/man/man3'
man3ext='3'
medium=''
mips=''
mips_type=''
mkdir='mkdir'
models='none'
modetype='mode_t'
more='more'
mv=''
myarchname='alpha-dec_osf'
mydomain='.directv.com'
myhostname='bambam'
myuname='osf1 bambam v4.0 1091 alpha '
n=''
netdb_hlen_type='int'
netdb_host_type='const char *'
netdb_name_type='const char *'
netdb_net_type='int'
nm='nm'
nm_opt='-p'
nm_so_opt=''
nonxs_ext='Errno'
nroff='nroff'
o_nonblock='O_NONBLOCK'
obj_ext='.o'
optimize='-O4'
orderlib='false'
osname='dec_osf'
osvers='4.0'
package='perl5'
pager='/usr/bin/more'
passcat='cat /etc/passwd'
patchlevel='5'
path_sep='​:'
perl='perl'
perladmin='lobbesp@​bambam.directv.com'
perlpath='/opt/dtv/perl/5.005_03/bin/perl'
pg='pg'
phostname='hostname'
pidtype='pid_t'
plibpth=''
pmake=''
pr=''
prefix='/opt/dtv/perl/5.005_03'
prefixexp='/opt/dtv/perl/5.005_03'
privlib='/opt/dtv/perl/5.005_03/lib/5.00503'
privlibexp='/opt/dtv/perl/5.005_03/lib/5.00503'
prototype='define'
ptrsize='8'
randbits='15'
ranlib='​:'
rd_nodata='-1'
rm='rm'
rmail=''
runnm='true'
scriptdir='/opt/dtv/perl/5.005_03/bin'
scriptdirexp='/opt/dtv/perl/5.005_03/bin'
sed='sed'
selectminbits='32'
selecttype='fd_set *'
sendmail='sendmail'
sh='/bin/sh'
shar=''
sharpbang='#!'
shmattype='void *'
shortsize='2'
shrpenv=''
shsharp='true'
sig_name='ZERO HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM IOINT STOP TSTP CONT CHLD TTIN TTOU AIO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2 RESV RTMIN NUM34 NUM35 NUM36 NUM37 NUM38 NUM39 NUM40 NUM41 NUM42 NUM43 NUM44 NUM45 NUM46 NUM47 MAX IOT LOST URG CLD IO POLL PTY PWR RTMAX '
sig_name_init='"ZERO", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", "PIPE", "ALRM", "TERM", "IOINT", "STOP", "TSTP", "CONT", "CHLD", "TTIN", "TTOU", "AIO", "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "INFO", "USR1", "USR2", "RESV", "RTMIN", "NUM34", "NUM35", "NUM36", "NUM37", "NUM38", "NUM39", "NUM40", "NUM41", "NUM42", "NUM43", "NUM44", "NUM45", "NUM46", "NUM47", "MAX", "IOT", "LOST", "URG", "CLD", "IO", "POLL", "PTY", "PWR", "RTMAX", 0'
sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 6 6 16 20 23 23 23 29 48 '
sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 6, 6, 16, 20, 23, 23, 23, 29, 48, 0'
signal_t='void'
sitearch='/opt/dtv/perl/5.005_03/lib/site_perl/5.005/alpha-dec_osf'
sitearchexp='/opt/dtv/perl/5.005_03/lib/site_perl/5.005/alpha-dec_osf'
sitelib='/opt/dtv/perl/5.005_03/lib/site_perl/5.005'
sitelibexp='/opt/dtv/perl/5.005_03/lib/site_perl/5.005'
sizetype='size_t'
sleep=''
smail=''
small=''
so='so'
sockethdr=''
socketlib=''
sort='sort'
spackage='Perl5'
spitshell='cat'
split=''
src='.'
ssizetype='ssize_t'
startperl='#!/opt/dtv/perl/5.005_03/bin/perl'
startsh='#!/bin/sh'
static_ext=' '
stdchar='unsigned char'
stdio_base='((fp)->_base)'
stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)'
stdio_cnt='((fp)->_cnt)'
stdio_filbuf=''
stdio_ptr='((fp)->_ptr)'
strings='/usr/include/string.h'
submit=''
subversion='3'
sysman='/usr/man/man1'
tail=''
tar=''
tbl=''
tee='tee'
test='test'
timeincl='/usr/include/sys/time.h '
timetype='time_t'
touch='touch'
tr='tr'
trnl='\n'
troff=''
uidtype='uid_t'
uname='uname'
uniq='uniq'
usedl='define'
usemymalloc='y'
usenm='true'
useopcode='true'
useperlio=''
useposix='true'
usesfio='false'
useshrplib='true'
usethreads=''
usevfork='false'
usrinc='/usr/include'
uuname=''
version='5.00503'
vi=''
voidflags='15'
xlibpth='/usr/lib/386 /lib/386'
zcat=''
zip='zip'

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 1999

From [Unknown Contact. See original ticket]

On Sun, 19 Sep 1999 15​:30​:31 -0700, Gurusamy Sarathy wrote (in part)​:

Sarathy> The mktime() call was added (change#1914) to fix the
Sarathy> behavior of strftime() on linux, and apparently,
Sarathy> alpha-dec_osf (!).

Sarathy> I'd say this needs to be controlled via the hints only
Sarathy> for the platforms that need it.

I know of no vendor strftime() which doesn't need help to avoid
SEGVs. I consider reverting to SEGVs to avoid a cosmetic bug to
be very wrong. On the other hand, mktime()'s docs (on the vendor
releases I checked) are misleading, and using it turns out to be
very wrong as well. (The UNIX98 spec makes it rather explicit
that mktime() was wrong, but I didn't have that available when I
submitted the patch which added the mktime() call.)

Sometime today I'll submit a patch which substitutes a
'minimktime' which only rationalizes the input values, but which
doesn't assume that you want something equivalent to a
localtime() result. Since we already call init_tm(), that should
be OK for whatever timezone values you might really have wanted,
as well.

/spider

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 1999

From @timbunce

On Thu, Sep 23, 1999 at 09​:55​:26AM -0400, spider-perl@​Orb.Nashua.NH.US wrote​:

On Sun, 19 Sep 1999 15​:30​:31 -0700, Gurusamy Sarathy wrote (in part)​:

Sarathy> The mktime() call was added (change#1914) to fix the
Sarathy> behavior of strftime() on linux, and apparently,
Sarathy> alpha-dec_osf (!).

Sarathy> I'd say this needs to be controlled via the hints only
Sarathy> for the platforms that need it.

I know of no vendor strftime() which doesn't need help to avoid
SEGVs. I consider reverting to SEGVs to avoid a cosmetic bug to
be very wrong. On the other hand, mktime()'s docs (on the vendor
releases I checked) are misleading, and using it turns out to be
very wrong as well. (The UNIX98 spec makes it rather explicit
that mktime() was wrong, but I didn't have that available when I
submitted the patch which added the mktime() call.)

Sometime today I'll submit a patch which substitutes a
'minimktime' which only rationalizes the input values, but which
doesn't assume that you want something equivalent to a
localtime() result. Since we already call init_tm(), that should
be OK for whatever timezone values you might really have wanted,
as well.

/spider

Random observation​: I've found that mktime() can be _very slow, so
ways of avoiding it would be handy.

Tim.

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 1999

From [Unknown Contact. See original ticket]

On Thu, 23 Sep 1999 16​:14​:30 +0100, Tim Bunce wrote (in part)​:

Tim> Random observation​: I've found that mktime() can be _very
Tim> slow, so ways of avoiding it would be handy.

The mini-mktime won't be doing anything with tzset() or its
equivalent, so there should be no problem there. In fact, it'll
make neither library calls nor syscalls. All it does is straight
in-line integer arithmetic. The algorithm it uses is rather
obscure, but it works, and needs (depending on how you look at
it) 0 or 1 table lookups. I'd already have sent the patch, but I
have my day job's work to get done today, too. ;=}

/spider

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 1999

From [Unknown Contact. See original ticket]

Hi,

Just to clarify things a bit, I believe taking out mktime in this case
is the apropriate move replacing that with this "minimktime" is
probably the best move *as long* as it doesn't change data or return
bogus data (as it does with mktime on OSF1 and most likely Solaris if
my test c program emulates perl bahavior properly).

I'd personally have my program SEGV if I pass improper data to
strftime than give me bogus data. Even better would be to have Perl do
boundary checking as I believe you're proposing with "minimktime" to
trap improper data and return a null string instead of a time that is
incorrect. I just want to be sure that this fix doesn't cause Perl to
generate dates that are skewed by an hour. I can't afford to have
bogus dates in my database and trying to fix a 250GB database that has
*some* of it's times shifted by 1 hour is *painful*.

Maybe we should add a test to POSIX (not sure how portable this is but
according to Sun man pages should be X/Open Portability Guide, Issue
4 compatible)​:

  use POSIX;
  @​t=qw(37 57 0 3 8 99 5 245 0); # a time which mktime could skew
  $tstr="1999 09 03 00​:57​:37"; # what strftime should give us
  $pstr=&POSIX​::strftime("%Y %m %d %H​:%M​:%S", @​t);
  print (($tstr eq $pstr) ? "ok" : "not ok", " 99\n");

Phil

On Thu, 23 Sep 1999 09​:55​:26 -0400, spider-perl@​Orb.Nashua.NH.US said​:

spider> On Sun, 19 Sep 1999 15​:30​:31 -0700, Gurusamy Sarathy wrote (in
spider> part)​:
Sarathy> The mktime() call was added (change#1914) to fix the behavior
Sarathy> of strftime() on linux, and apparently, alpha-dec_osf (!).

Sarathy> I'd say this needs to be controlled via the hints only for
Sarathy> the platforms that need it.

spider> I know of no vendor strftime() which doesn't need help to
spider> avoid SEGVs. I consider reverting to SEGVs to avoid a
spider> cosmetic bug to be very wrong. On the other hand, mktime()'s
spider> docs (on the vendor releases I checked) are misleading, and
spider> using it turns out to be very wrong as well. (The UNIX98 spec
spider> makes it rather explicit that mktime() was wrong, but I didn't
spider> have that available when I submitted the patch which added the
spider> mktime() call.)

spider> Sometime today I'll submit a patch which substitutes a
spider> 'minimktime' which only rationalizes the input values, but
spider> which doesn't assume that you want something equivalent to a
spider> localtime() result. Since we already call init_tm(), that
spider> should be OK for whatever timezone values you might really
spider> have wanted, as well.

spider> /spider

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 1999

From [Unknown Contact. See original ticket]

On Thu, 23 Sep 1999 09​:55​:26 -0400, I wrote (in part)​:

sb> Sometime today I'll submit a patch which substitutes a
sb> 'minimktime' which only rationalizes the input values, but
sb> which doesn't assume that you want something equivalent to a
sb> localtime() result.

Here it is.

/spider

Inline Patch
--- ext/POSIX/POSIX.pod.DIST	Tue Jul 20 13:17:56 1999
+++ ext/POSIX/POSIX.pod	Thu Sep 23 17:47:51 1999
@@ -1024,7 +1024,8 @@ If you want your code to be portable, yo
 should use only the conversion specifiers defined by the ANSI C
 standard.  These are C<aAbBcdHIjmMpSUwWxXyYZ%>.
 The given arguments are made consistent
-by calling C<mktime()> before calling your system's C<strftime()> function.
+as though by calling C<mktime()> before calling your system's
+C<strftime()> function, except that the C<isdst> value is not affected.
 
 The string for Tuesday, December 12, 1995.
 
--- ext/POSIX/POSIX.xs.DIST	Fri Aug 20 11:51:30 1999
+++ ext/POSIX/POSIX.xs	Thu Sep 23 15:39:30 1999
@@ -332,6 +332,196 @@ init_tm(struct tm *ptm)		/* see mktime, 
 # define init_tm(ptm)
 #endif
 
+/*
+ * mini_mktime - normalise struct tm values without the localtime()
+ * semantics (and overhead) of mktime().
+ */
+static void
+mini_mktime(struct tm *ptm)
+{
+    int yearday;
+    int secs;
+    int month, mday, year, jday;
+    int odd_cent, odd_year;
+
+#define	DAYS_PER_YEAR	365
+#define	DAYS_PER_QYEAR	(4*DAYS_PER_YEAR+1)
+#define	DAYS_PER_CENT	(25*DAYS_PER_QYEAR-1)
+#define	DAYS_PER_QCENT	(4*DAYS_PER_CENT+1)
+#define	SECS_PER_HOUR	(60*60)
+#define	SECS_PER_DAY	(24*SECS_PER_HOUR)
+/* parentheses deliberately absent on these two, otherwise they don't work */
+#define	MONTH_TO_DAYS	153/5
+#define	DAYS_TO_MONTH	5/153
+/* offset to bias by March (month 4) 1st between month/mday & year finding */
+#define	YEAR_ADJUST	(4*MONTH_TO_DAYS+1)
+/* as used here, the algorithm leaves Sunday as day 1 unless we adjust it */
+#define	WEEKDAY_BIAS	6	/* (1+6)%7 makes Sunday 0 again */
+
+/*
+ * Year/day algorithm notes:
+ *
+ * With a suitable offset for numeric value of the month, one can find
+ * an offset into the year by considering months to have 30.6 (153/5) days,
+ * using integer arithmetic (i.e., with truncation).  To avoid too much
+ * messing about with leap days, we consider January and February to be
+ * the 13th and 14th month of the previous year.  After that transformation,
+ * we need the month index we use to be high by 1 from 'normal human' usage,
+ * so the month index values we use run from 4 through 15.
+ *
+ * Given that, and the rules for the Gregorian calendar (leap years are those
+ * divisible by 4 unless also divisible by 100, when they must be divisible
+ * by 400 instead), we can simply calculate the number of days since some
+ * arbitrary 'beginning of time' by futzing with the (adjusted) year number,
+ * the days we derive from our month index, and adding in the day of the
+ * month.  The value used here is not adjusted for the actual origin which
+ * it normally would use (1 January A.D. 1), since we're not exposing it.
+ * We're only building the value so we can turn around and get the
+ * normalised values for the year, month, day-of-month, and day-of-year.
+ *
+ * For going backward, we need to bias the value we're using so that we find
+ * the right year value.  (Basically, we don't want the contribution of
+ * March 1st to the number to apply while deriving the year).  Having done
+ * that, we 'count up' the contribution to the year number by accounting for
+ * full quadracenturies (400-year periods) with their extra leap days, plus
+ * the contribution from full centuries (to avoid counting in the lost leap
+ * days), plus the contribution from full quad-years (to count in the normal
+ * leap days), plus the leftover contribution from any non-leap years.
+ * At this point, if we were working with an actual leap day, we'll have 0
+ * days left over.  This is also true for March 1st, however.  So, we have
+ * to special-case that result, and (earlier) keep track of the 'odd'
+ * century and year contributions.  If we got 4 extra centuries in a qcent,
+ * or 4 extra years in a qyear, then it's a leap day and we call it 29 Feb.
+ * Otherwise, we add back in the earlier bias we removed (the 123 from
+ * figuring in March 1st), find the month index (integer division by 30.6),
+ * and the remainder is the day-of-month.  We then have to convert back to
+ * 'real' months (including fixing January and February from being 14/15 in
+ * the previous year to being in the proper year).  After that, to get
+ * tm_yday, we work with the normalised year and get a new yearday value for
+ * January 1st, which we subtract from the yearday value we had earlier,
+ * representing the date we've re-built.  This is done from January 1
+ * because tm_yday is 0-origin.
+ *
+ * Since POSIX time routines are only guaranteed to work for times since the
+ * UNIX epoch (00:00:00 1 Jan 1970 UTC), the fact that this algorithm
+ * applies Gregorian calendar rules even to dates before the 16th century
+ * doesn't bother me.  Besides, you'd need cultural context for a given
+ * date to know whether it was Julian or Gregorian calendar, and that's
+ * outside the scope for this routine.  Since we convert back based on the
+ * same rules we used to build the yearday, you'll only get strange results
+ * for input which needed normalising, or for the 'odd' century years which
+ * were leap years in the Julian calander but not in the Gregorian one.
+ * I can live with that.
+ *
+ * This algorithm also fails to handle years before A.D. 1 gracefully, but
+ * that's still outside the scope for POSIX time manipulation, so I don't
+ * care.
+ */
+
+    year = 1900 + ptm->tm_year;
+    month = ptm->tm_mon;
+    mday = ptm->tm_mday;
+    /* allow given yday with no month & mday to dominate the result */
+    if (ptm->tm_yday >= 0 && mday <= 0 && month <= 0) {
+	month = 0;
+	mday = 0;
+	jday = 1 + ptm->tm_yday;
+    }
+    else {
+	jday = 0;
+    }
+    if (month >= 2)
+	month+=2;
+    else
+	month+=14, year--;
+    yearday = DAYS_PER_YEAR * year + year/4 - year/100 + year/400;
+    yearday += month*MONTH_TO_DAYS + mday + jday;
+    /*
+     * Note that we don't know when leap-seconds were or will be,
+     * so we have to trust the user if we get something which looks
+     * like a sensible leap-second.  Wild values for seconds will
+     * be rationalised, however.
+     */
+    if ((unsigned) ptm->tm_sec <= 60) {
+	secs = 0;
+    }
+    else {
+	secs = ptm->tm_sec;
+	ptm->tm_sec = 0;
+    }
+    secs += 60 * ptm->tm_min;
+    secs += SECS_PER_HOUR * ptm->tm_hour;
+    if (secs < 0) {
+	if (secs-(secs/SECS_PER_DAY*SECS_PER_DAY) < 0) {
+	    /* got negative remainder, but need positive time */
+	    /* back off an extra day to compensate */
+	    yearday += (secs/SECS_PER_DAY)-1;
+	    secs -= SECS_PER_DAY * (secs/SECS_PER_DAY - 1);
+	}
+	else {
+	    yearday += (secs/SECS_PER_DAY);
+	    secs -= SECS_PER_DAY * (secs/SECS_PER_DAY);
+	}
+    }
+    else if (secs >= SECS_PER_DAY) {
+	yearday += (secs/SECS_PER_DAY);
+	secs %= SECS_PER_DAY;
+    }
+    ptm->tm_hour = secs/SECS_PER_HOUR;
+    secs %= SECS_PER_HOUR;
+    ptm->tm_min = secs/60;
+    secs %= 60;
+    ptm->tm_sec += secs;
+    /* done with time of day effects */
+    /*
+     * The algorithm for yearday has (so far) left it high by 428.
+     * To avoid mistaking a legitimate Feb 29 as Mar 1, we need to
+     * bias it by 123 while trying to figure out what year it
+     * really represents.  Even with this tweak, the reverse
+     * translation fails for years before A.D. 0001.
+     * It would still fail for Feb 29, but we catch that one below.
+     */
+    jday = yearday;	/* save for later fixup vis-a-vis Jan 1 */
+    yearday -= YEAR_ADJUST;
+    year = (yearday / DAYS_PER_QCENT) * 400;
+    yearday %= DAYS_PER_QCENT;
+    odd_cent = yearday / DAYS_PER_CENT;
+    year += odd_cent * 100;
+    yearday %= DAYS_PER_CENT;
+    year += (yearday / DAYS_PER_QYEAR) * 4;
+    yearday %= DAYS_PER_QYEAR;
+    odd_year = yearday / DAYS_PER_YEAR;
+    year += odd_year;
+    yearday %= DAYS_PER_YEAR;
+    if (!yearday && (odd_cent==4 || odd_year==4)) { /* catch Feb 29 */
+	month = 1;
+	yearday = 29;
+    }
+    else {
+	yearday += YEAR_ADJUST;	/* recover March 1st crock */
+	month = yearday*DAYS_TO_MONTH;
+	yearday -= month*MONTH_TO_DAYS;
+	/* recover other leap-year adjustment */
+	if (month > 13) {
+	    month-=14;
+	    year++;
+	}
+	else {
+	    month-=2;
+	}
+    }
+    ptm->tm_year = year - 1900;
+    ptm->tm_mon = month;
+    ptm->tm_mday = yearday;
+    /* re-build yearday based on Jan 1 to get tm_yday */
+    year--;
+    yearday = year*DAYS_PER_YEAR + year/4 - year/100 + year/400;
+    yearday += 14*MONTH_TO_DAYS + 1;
+    ptm->tm_yday = jday - yearday;
+    /* fix tm_wday if not overridden by caller */
+    if ((unsigned)ptm->tm_wday > 6)
+	ptm->tm_wday = (jday + WEEKDAY_BIAS) % 7;
+}
 
 #ifdef HAS_LONG_DOUBLE
 #  if LONG_DOUBLESIZE > DOUBLESIZE
@@ -3650,7 +3840,7 @@ strftime(fmt, sec, min, hour, mday, mon,
 	    mytm.tm_wday = wday;
 	    mytm.tm_yday = yday;
 	    mytm.tm_isdst = isdst;
-	    (void) mktime(&mytm);
+	    mini_mktime(&mytm);
 	    len = strftime(tmpbuf, sizeof tmpbuf, fmt, &mytm);
 	    /*
 	    ** The following is needed to handle to the situation where 
--- t/lib/posix.t.DIST	Tue Jul 20 13:18:13 1999
+++ t/lib/posix.t	Thu Sep 23 17:00:43 1999
@@ -14,7 +14,7 @@
 use strict subs;
 
 $| = 1;
-print "1..18\n";
+print "1..26\n";
 
 $Is_W32 = $^O eq 'MSWin32';
 
@@ -94,6 +94,31 @@
 # -DSTRUCT_TM_HASZONE to your cflags when compiling ext/POSIX/POSIX.c.
 # See ext/POSIX/hints/sunos_4.pl and ext/POSIX/hints/linux.pl 
 print POSIX::strftime("ok 18 # %H:%M, on %D\n", localtime());
+
+# If that worked, validate the mini_mktime() routine's normalisation of
+# input fields to strftime().
+sub try_strftime {
+    my $num = shift;
+    my $expect = shift;
+    my $got = POSIX::strftime("%a %b %d %H:%M:%S %Y %j", @_);
+    if ($got eq $expect) {
+	print "ok $num\n";
+    }
+    else {
+	print "# expected: $expect\n# got: $got\nnot ok $num\n";
+    }
+}
+
+$lc = &POSIX::setlocale(&POSIX::LC_TIME, 'C') if $Config{d_setlocale};
+try_strftime(19, "Wed Feb 28 00:00:00 1996 059", 0,0,0, 28,1,96);
+try_strftime(20, "Thu Feb 29 00:00:60 1996 060", 60,0,-24, 30,1,96);
+try_strftime(21, "Fri Mar 01 00:00:00 1996 061", 0,0,-24, 31,1,96);
+try_strftime(22, "Sun Feb 28 00:00:00 1999 059", 0,0,0, 28,1,99);
+try_strftime(23, "Mon Mar 01 00:00:00 1999 060", 0,0,24, 28,1,99);
+try_strftime(24, "Mon Feb 28 00:00:00 2000 059", 0,0,0, 28,1,100);
+try_strftime(25, "Tue Feb 29 00:00:00 2000 060", 0,0,0, 0,2,100);
+try_strftime(26, "Wed Mar 01 00:00:00 2000 061", 0,0,0, 1,2,100);
+&POSIX::setlocale(&POSIX::LC_TIME, $lc) if $Config{d_setlocale};
 
 $| = 0;
 # The following line assumes buffered output, which may be not true with EMX:

@p5pRT
Copy link
Author

p5pRT commented Dec 9, 2000

From @gsar

On Mon, 13 Sep 1999 14​:51​:17 PDT, Phil Lobbes wrote​:

I believe I have found a bug in Perl > 5.004_04 (possibly only Perl
5.005+) using POSIX​::strftime. I've been using POSIX​::strftime to
print out formatted times obtained through Perl's gmtime call.
Everything is fine when not going through strftime
(i.e. scalar(gmtime)) or using Perl 5.004_01-5.004_04, but when format
the times through strftime 5.005_03 it seems to get confused about
daylight savings times even though I'm passing it a full array from
gmtime.

The problem seems to be that strftime C module calls mktime() which
sets (or actually improperly re-sets) "isdst" in the data structure I
passed to it causing time to be 1 hour off with data structures that
would land within my DST period. I think stftime shouldn't be calling
mktime but I'm not 100% sure. This didn't used to happen (perl
5.004_01-03 anyway) and with 5.005 it breaks my database application.

Should I not use strftime? Is strftime supposed to call mktime? It
seems a bit dangerous to assume the programmer actually wants this
behavior but maybe I'm missing something here.

The *real* world where I've run into problems, gmtime sets tm_isdst to
0 appropriately, but using POSIX​::strftime make things look like
daylight savings time apparently!

% /opt/dtv/bin/perl -e '@​tmp=gmtime;use POSIX; print scalar(gmtime),
" or (@​tmp)\n",POSIX​::strftime("%Y %m %d %H​:%M​:%S", @​tmp), "\n"' ;
Fri Sep 3 00​:46​:11 1999 or (11 46 0 3 8 99 5 245 0)
1999 09 03 01​:46​:11

The mktime() call was added (change#1914) to fix the behavior of
strftime() on linux, and apparently, alpha-dec_osf (!). See​:

http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-09/msg01660.html
http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-11/msg00291.html
http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-11/msg00864.html

I'd say this needs to be controlled via the hints only for the
platforms that need it.

I've checked in the attached change. Someone will need to add a hints
file for dec_osf after ascertaining whether calling mktime() there
causes more problems than it solves.

Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration​:
Platform​:
osname=dec_osf, osvers=4.0, archname=alpha-dec_osf
uname='osf1 bambam v4.0 1091 alpha '
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef useperlio=undef d_sfio=undef
Compiler​:
cc='cc', optimize='-O4', gccversion=
cppflags='-std -ieee -D_INTRINSICS -I/usr/local/include -I/opt/local/include -DLANGUAGE_C'
ccflags ='-std -fprm d -ieee -D_INTRINSICS -I/usr/local/include -I/opt/local/include -DLANGUAGE_C'
stdchar='unsigned char', d_stdstdio=define, usevfork=false
intsize=4, longsize=8, ptrsize=8, doublesize=8
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
alignbytes=8, usemymalloc=y, prototype=define
Linker and Libraries​:
ld='ld', ldflags =' -L/usr/local/lib -L/opt/local/lib'
libpth=/usr/local/lib /opt/local/lib /usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /var/shlib
libs=-ldbm -ldb -lm
libc=/usr/shlib/libc.so, so=so, useshrplib=true, libperl=libperl.so
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' -Wl,-rpath,/opt/dtv/perl/5.005_03/lib/5.00503/alpha-dec_osf/CORE'
cccdlflags=' ', lddlflags='-shared -expect_unresolved "*" -O4 -msym -s -L/usr/local/lib -L/opt/local/lib'

Sarathy
gsar@​activestate.com

Inline Patch
-----------------------------------8<-----------------------------------
Change 4196 by gsar@auger on 1999/09/19 22:14:29

	control change#1914 via hints (causes problems on some platforms)

Affected files ...

... //depot/perl/ext/POSIX/POSIX.pod#12 edit
... //depot/perl/ext/POSIX/POSIX.xs#49 edit
... //depot/perl/ext/POSIX/hints/linux.pl#3 edit

Differences ...

==== //depot/perl/ext/POSIX/POSIX.pod#12 (text) ====
Index: perl/ext/POSIX/POSIX.pod
--- perl/ext/POSIX/POSIX.pod.~1~	Sun Sep 19 15:14:34 1999
+++ perl/ext/POSIX/POSIX.pod	Sun Sep 19 15:14:34 1999
@@ -1023,7 +1023,7 @@
 If you want your code to be portable, your format (C<fmt>) argument
 should use only the conversion specifiers defined by the ANSI C
 standard.  These are C<aAbBcdHIjmMpSUwWxXyYZ%>.
-The given arguments are made consistent
+On platforms that need it, the given arguments are made consistent
 by calling C<mktime()> before calling your system's C<strftime()> function.
 
 The string for Tuesday, December 12, 1995.

==== //depot/perl/ext/POSIX/POSIX.xs#49 (text) ====
Index: perl/ext/POSIX/POSIX.xs
--- perl/ext/POSIX/POSIX.xs.~1~	Sun Sep 19 15:14:34 1999
+++ perl/ext/POSIX/POSIX.xs	Sun Sep 19 15:14:34 1999
@@ -3652,7 +3652,9 @@
 	    mytm.tm_wday = wday;
 	    mytm.tm_yday = yday;
 	    mytm.tm_isdst = isdst;
+#if defined(HINT_STRFTIME_NEEDS_MKTIME)
 	    (void) mktime(&mytm);
+#endif
 	    len = strftime(tmpbuf, sizeof tmpbuf, fmt, &mytm);
 	    /*
 	    ** The following is needed to handle to the situation where 

==== //depot/perl/ext/POSIX/hints/linux.pl#3 (text) ====
Index: perl/ext/POSIX/hints/linux.pl
--- perl/ext/POSIX/hints/linux.pl.~1~	Sun Sep 19 15:14:34 1999
+++ perl/ext/POSIX/hints/linux.pl	Sun Sep 19 15:14:34 1999
@@ -2,4 +2,6 @@
 # Thanks to Bart Schuller <schuller@Lunatech.com>
 # See Message-ID: <19971009002636.50729@tanglefoot>
 #  XXX A Configure test is needed.
-$self->{CCFLAGS} = $Config{ccflags} . ' -DSTRUCT_TM_HASZONE -DHINT_SC_EXIST' ;
+$self->{CCFLAGS} = $Config{ccflags}
+		 . ' -DHINT_STRFTIME_NEEDS_MKTIME'
+		 . ' -DSTRUCT_TM_HASZONE -DHINT_SC_EXIST' ;
End of Patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant