Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 523 forks source link

POSIX::tmpnam() broken for threaded 5.00503 #123

Closed p5pRT closed 20 years ago

p5pRT commented 24 years ago

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

Searchable as RT927$

p5pRT commented 24 years ago

From hirschs@btv.ibm.com

Hello\,

Perl 5.00503 has a problem in the POSIX library module when built for threading\, plus a small typo.

1) POSIX.xs looks for the definition of 'L_tmpname' in sys/types.h. On AIX 4.1.5\, Tru64 Unix 4.0D and Solaris (all I could check at the moment)\, this is spelled 'L_tmpnam' (drop the trailing "e"). The Perl function (mis)spelling should probably not change to preserve operation of legacy code.

2) On non-threaded systems\, tmpnam() can be called with an optional pointer to storage for the generated string. If not provided\, the library returns a pointer to internal static storage. On threaded systems\, the parameter is no longer optional.

The existing XS stub for tmpnam() looks like it wants to be coded for a single\, optional parm that is defaulted to NULL​:

char * tmpnam(s = 0)   char * s = 0;

Unfortunately\, the explicit assignment in the third line causes xsubpp to omit generation of the necessary conditional expression. When NULL is passed to tmpnam() under threaded Perl\, the call simply fails.

The patch below takes care of both problems​:

Inline Patch ```diff --- POSIX.xs.orig Thu Mar 4 19:34:14 1999 +++ POSIX.xs Mon Jun 28 13:42:46 1999 @@ -1520,8 +1520,8 @@ goto not_there; #endif if (strEQ(name, "L_tmpname")) -#ifdef L_tmpname - return L_tmpname; +#ifdef L_tmpnam + return L_tmpnam; #else goto not_there; #endif @@ -3367,9 +3367,17 @@ char * buffer size_t nbytes -char * -tmpnam(s = 0) - char * s = 0; +SV * +tmpnam() + PREINIT: + U32 i; + int len; + CODE: + RETVAL = newSVpv("", L_tmpnam); + len = strlen(tmpnam(SvPV(RETVAL, i))); + SvCUR_set(RETVAL, len); + OUTPUT: + RETVAL void abort() ```

My solution instantiates an SV with a blank string of requisite length preallocated\, then calls tmpnam() with a pointer to this string. The return value is checked for its new (potentially shorter) length\, and the SV adjusted to reflect this. Unless I'm misreading the perlguts doc\, Perl manages all storage. No memory leaks should result.

Since the motivation for passing a parameter to tempnam() under C relates to storage allocation\, I made no attempt to support this feature under Perl.

Here is the test program I used to verify the fix​:

#!/usr/local/bin/perl5.00503 -w

use strict;

use POSIX qw(​:stdio_h);

my $tmpfile = POSIX​::tmpnam(); $tmpfile or die "$!"; print "tempfile = $tmpfile\n";

my $len = L_tmpname; print "L_tmpname = $len\n";

Please contact me if any more information is required?

Regards\,

Steven N. Hirsch

Development Engineer IBM Microelectronics

Perl Info ``` Site configuration information for perl 5.00503: Configured by hirschs at Thu Apr 15 16:28:17 EDT 1999. Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration: Platform: osname=aix, osvers=4.1.5.0, archname=aix-thread uname='aix stargate 1 4 000092735700 ' hint=recommended, useposix=true, d_sigaction=define usethreads=define useperlio=undef d_sfio=undef Compiler: cc='cc_r', optimize='-O', gccversion= cppflags='' ccflags ='-D_ALL_SOURCE -D_ANSI_C_SOURCE -D_POSIX_SOURCE -qmaxmem=8192 -DNEED_PTHREAD_INIT -I/usr/local/include' stdchar='unsigned char', d_stdstdio=define, usevfork=false intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8 alignbytes=8, usemymalloc=n, prototype=define Linker and Libraries: ld='ld', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib /usr/ccs/lib libs=-ldbm -ldb -ldl -lld -lm -lc_r -lc -lbsd -lPW libc=, so=a, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_aix.xs, dlext=so, d_dlsymun=undef, ccdlflags='-bE:perl.exp' cccdlflags=' ', lddlflags='-bhalt:4 -bM:SRE -bI:$(PERL_INC)/perl.exp -bE:$(BASEEXT).exp -b noentry -lpthreads -lc_r -lc -L/usr/local/lib' Locally applied patches: @INC for perl 5.00503: /usr/local/lib/perl5/5.005/aix-thread /usr/local/lib/perl5/5.005 /usr/local/lib/perl5/site_perl/5.005/aix-thread /usr/local/lib/perl5/site_perl/5.005 . Environment for perl 5.00503: HOME=/afs/btv.ibm.com/u4/hirschs LANG=en_US LANGUAGE (unset) LC__FASTMSG=true LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/prod/local/bin:.:/usr/local/bin:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin:/usr/afsws/bin:/usr/afsws/etc:/usr/prod/local/bin:/usr/prod/contrib/bin:/usr/prod/tools/bin:/afs/btv.ibm.com/data/a29tools/cadence/bin:/afs/btv.ibm.com/data/a29tools/cadence/cds434/9502/tools/bin:/afs/btv.ibm.com/data/a29tools/cadence/cds434/9502/tools/dfII/bin:/afs/btv/data/a29v/work/bin:/afs/btv.ibm.com/data/a29tools/iss/prod/code: PERL_BADLANG (unset) SHELL=/bin/ksh ```