Closed p5pRT closed 20 years ago
Hi\,
I've figured out a very strange behaviour perl 5.7.0 (APC 7483 installed) shows on socket read operations. I first found that\, when I tried to run mirror 2.9 using perl 5.7.0 and did some investigation in the problem. I've isolated the thing in a small client/server application\, with a server which just displays a small text upon being connected and a variety of client procedures connecting the server.
The server establishes its service on port 4242. You'll receive the correct text file if you're doing a 'telnet localhost 4242'. The following small perl program also results in a correct output:
#!/usr/local/bin/perl -w
use FileHandle; use Client;
my $sh = new FileHandle; $sh = Client::tcp_connect( 'localhost'\, 4242);
while( \<$sh>) { print; }
The module Client.pm provides the appropriate socket and connect system call.
The next small perl program results in a corrupted output:
#!/usr/local/bin/perl -w
use FileHandle; use Client;
my $sh = new FileHandle; $sh = Client::tcp_connect( 'localhost'\, 4242);
while( !eof( $sh ) ){ my( $res) = &line( $sh ); last if $res eq 'eof'; }
sub line { my( $fh ) = @_;
while( \<$fh> ){ print "$_"; return( "ok" ); } return( "eof" ); }
Instead of the orginal lines of text a - at a first glance - random character is displayed at the beginning of each line. Having a closer look at the things displayed\, it turns out\, that each of these 'random' characters form some content of the orginal text file in my case beginning at character 7317 ... for my point of view this is very\, very mysterious!
Furthermore it turns out\, that the first client example does a connect system call followed by a few read calls as the following truss output shows:
.... close(4) = 0 connect(3\, 0x10022D8E0\, 16\, 1) = 0 fstat(3\, 0xFFFFFFFF7FFFCDA0) = 0 ioctl(3\, TCGETA\, 0xFFFFFFFF7FFFCCDC) Err#22 EINVAL read(3\, " / * L I N T L I B R A"..\, 8192) = 8192 ioctl(1\, TCGETA\, 0xFFFFFFFF7FFFEEAC) Err#25 ENOTTY fstat(1\, 0xFFFFFFFF7FFFEF70) = 0 read(3\, " n \, i n t y \, i n"..\, 8192) = 8192 read(3\, " t ( * i n i t ) ( W I"..\, 8192) = 8192 read(3\, " n t v i d p u t s ( c"..\, 8192) = 235 write(1\, " t ( * i n i t ) ( W I"..\, 8192) = 8192 read(3\, 0x100086C64\, 8192) = 0 ....
In opposite to this correct behaviour\, the second example does lots of recv calls in addition to the 3 read calls.
.... close(4) = 0 connect(3\, 0x10022D8E0\, 16\, 1) = 0 getsockopt(3\, 65535\, 4104\, 0xFFFFFFFF7FFFF24C\, 0xFFFFFFFF7FFFF248\, 1) = 0 getsockname(3\, 0xFFFFFFFF7FFFEF88\, 0xFFFFFFFF7FFFF090\, 1) = 0 getsockopt(3\, 65535\, 4104\, 0xFFFFFFFF7FFFF098\, 0xFFFFFFFF7FFFF094\, 1) = 0 recv(3\, " /"\, 1\, 0) = 1 fstat(3\, 0xFFFFFFFF7FFFF080) = 0 ioctl(3\, TCGETA\, 0xFFFFFFFF7FFFEFBC) Err#22 EINVAL read(3\, " * L I N T L I B R A R"..\, 8192) = 8192 ioctl(1\, TCGETA\, 0xFFFFFFFF7FFFEE9C) Err#25 ENOTTY fstat(1\, 0xFFFFFFFF7FFFEF60) = 0 getsockopt(3\, 65535\, 4104\, 0xFFFFFFFF7FFFF24C\, 0xFFFFFFFF7FFFF248\, 1) = 0 getsockname(3\, 0xFFFFFFFF7FFFEF88\, 0xFFFFFFFF7FFFF090\, 1) = 0 getsockopt(3\, 65535\, 4104\, 0xFFFFFFFF7FFFF098\, 0xFFFFFFFF7FFFF094\, 1) = 0 recv(3\, " \,"\, 1\, 0) = 1 getsockopt(3\, 65535\, 4104\, 0xFFFFFFFF7FFFF24C\, 0xFFFFFFFF7FFFF248\, 1) = 0 getsockname(3\, 0xFFFFFFFF7FFFEF88\, 0xFFFFFFFF7FFFF090\, 1) = 0 getsockopt(3\, 65535\, 4104\, 0xFFFFFFFF7FFFF098\, 0xFFFFFFFF7FFFF094\, 1) = 0 recv(3\, " "\, 1\, 0) = 1 getsockopt(3\, 65535\, 4104\, 0xFFFFFFFF7FFFF24C\, 0xFFFFFFFF7FFFF248\, 1) = 0 getsockname(3\, 0xFFFFFFFF7FFFEF88\, 0xFFFFFFFF7FFFF090\, 1) = 0 getsockopt(3\, 65535\, 4104\, 0xFFFFFFFF7FFFF098\, 0xFFFFFFFF7FFFF094\, 1) = 0 recv(3\, " i"\, 1\, 0) = 1 getsockopt(3\, 65535\, 4104\, 0xFFFFFFFF7FFFF24C\, 0xFFFFFFFF7FFFF248\, 1) = 0 ....
Assuming\, that the additional eof() call in the second example causes this behaviour\, I did another two tests:
#!/usr/local/bin/perl -w
use FileHandle; use Client;
my $sh = new FileHandle; $sh = Client::tcp_connect( 'localhost'\, 4242);
while( !eof( $sh ) ){ print \<$sh>; }
and
#!/usr/local/bin/perl -w
use FileHandle; use Client;
my $sh = new FileHandle; $sh = Client::tcp_connect( 'localhost'\, 4242);
while( !eof( $sh ) ){ while( \<$sh>) { print; break; } }
The first one worked out fine\, while the second one showed the buggy behaviour! Nevertheless the last test doens't show the problem\, if the 'last' statement is removed!
So my conclusion (without analyzing the underlaying perl code) is\, that caused by the second block of code the 'recv' system calls are forced and that these 'recv' cause side effects with the 'read' calls.
My perl 5.7.0 environment is:
Summary of my perl5 (revision 5.0 version 7 subversion 0) configuration: Platform: osname=solaris\, osvers=2.8\, archname=sun4-solaris-thread-multi-ld uname='sunos voi 5.8 generic sun4u sparc sunw\,ultra-5_10 ' config_args='-d' hint=previous\, useposix=true\, d_sigaction=define usethreads=define use5005threads=undef useithreads=define usemultiplicity=define useperlio=undef d_sfio=undef uselargefiles=define usesocks=define use64bitint=define use64bitall=define uselongdouble=define Compiler: cc='cc'\, ccflags ='-D_REENTRANT -DSOCKS -I/usr/local/include -I/opt/socks5/include -I/usr/local/BerkeleyDB.3.1/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -xarch=v9'\, optimize='-g -xarch=v9'\, cppflags='-D_REENTRANT -DSOCKS -I/usr/local/include -I/opt/socks5/include -I/usr/local/BerkeleyDB.3.1/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -xarch=v9' ccversion='Sun WorkShop 6 2000/04/07 C 5.1'\, gccversion=''\, gccosandvers='' intsize=4\, longsize=8\, ptrsize=8\, doublesize=8\, byteorder=87654321 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=16 ivtype='long'\, ivsize=8\, nvtype='long double'\, nvsize=16\, Off_t='off_t'\, lseeksize=8 alignbytes=16\, usemymalloc=y\, prototype=define Linker and Libraries: ld='cc'\, ldflags ='-g -xarch=v9 -L/usr/local/lib -R/usr/local/lib -L/opt/SUNWspro/WS6/lib/v9 -L/opt/socks5/lib -L/usr/local/BerkeleyDB.3.1/lib -R/usr/local/BerkeleyDB.3.1/lib -L/usr/krb5/lib -R/usr/krb5/lib' libpth=/usr/local/lib /opt/SUNWspro/WS6/lib/v9 /lib /usr/lib /usr/ccs/lib /opt/socks5/lib /usr/local/BerkeleyDB.3.1/lib /usr/krb5/lib libs=-lsocket -lnsl -ldb -ldl -lm -lsunmath -lposix4 -lpthread -lc -lsec -lsocks5 -lgssapi_krb5 perllibs=-lsocket -lnsl -ldl -lm -lsunmath -lposix4 -lpthread -lc -lsec -lsocks5 -lgssapi_krb5 libc=/usr/lib/sparcv9/libc.so\, so=so\, useshrplib=true\, libperl=libperl.so.7.0 Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags=' -R /opt/perl_5.7.0/lib/5.7.0/sun4-solaris-thread-multi-ld/CORE' cccdlflags='-KPIC'\, lddlflags=' -G -xarch=v9 -L/usr/local/lib -R/usr/local/lib -L/opt/SUNWspro/WS6/lib/v9 -L/opt/socks5/lib -L/usr/local/BerkeleyDB.3.1/lib -R/usr/local/BerkeleyDB.3.1/lib -L/usr/krb5/lib -R/usr/krb5/lib'
Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY USE_ITHREADS USE_64_BIT_INT USE_64_BIT_ALL USE_LONG_DOUBLE USE_LARGE_FILES USE_SOCKS PERL_IMPLICIT_CONTEXT Locally applied patches: DEVEL7481 Built under solaris Compiled at Oct 30 2000 13:06:46 @INC: /opt/perl_5.7.0/lib/5.7.0/sun4-solaris-thread-multi-ld /opt/perl_5.7.0/lib/5.7.0 /opt/perl_5.7.0/lib/site_perl/5.7.0/sun4-solaris-thread-multi-ld /opt/perl_5.7.0/lib/site_perl/5.7.0 /opt/perl_5.7.0/lib/site_perl /opt/perl_5.7.0/lib/vendor_perl/5.7.0/sun4-solaris-thread-multi-ld /opt/perl_5.7.0/lib/vendor_perl/5.7.0 /opt/perl_5.7.0/lib/vendor_perl .
I've attached my little 'test-suite' as gzipped tar file to this mail.
Any help of hints would be welcome ...
Regards -- Jens
/ +##+|##+ STRAWBERRY Jens Hamisch +v#+v v##+ EDV-Systeme GmbH Managing director / v v\v | . . . | Brauneckweg 2 Car (Voice): (+49 172) 81 04 162 | . | D-82549 Koenigsdorf Voice: (+49 8179) 9305-50 | . | Fax: (+49 8179) 9305-38 \ . / Tel./Fax: (+49 8179) 9305-50 Email: jens@Strawberry.COM \____/ Strawberry@Strawberry.COM
Hi\,
as suggested by Nick\, I've checked if the SOCKS- and close-patch is required even if PerlIO is used. It turns out\, that:
perl@7847 as is with SOCKS enabled Compiles on * Solaris 8 v9 * Solaris 8 i86pc * Solaris 2.6 sparc has not been tested
but t/lib/io_sock.t (close-bug) fails on * Solaris 8 v9 * Solaris 8 i86pc * Solaris 2.6 sparc has not been tested
perl@7847 with SOCKS and PerlIO enabled with the following small
modification:
perl.h:
* Don't define SOCKS_64BIT_BUG if USE_PERLIO is set
Compiles on
* none
* Solaris 2.6 sparc has not been tested
Fails to compile on
* Solaris 8 v9
* Solaris 8 i86pc
because the function PerlIO_fdupopen is not defined
perl@7847 with SOCKS and PerlIO enabled with the following small modification: perl.h: * Don't define SOCKS_64BIT_BUG if USE_PERLIO is set perlio.h: * #define PerlIO_fdupopen(f) (f) as perlsdio.h does
Compiles on * Solaris 8 v9 * Solaris 8 i86pc * Solaris 2.6 sparc has not been tested
and completes the testsuite on success on * Solaris 8 v9
but t/lib/io_sock.t (close-bug) fails on * Solaris 8 i86pc * Solaris 2.6 sparc has not been tested
perl@7847 with SOCKS and PerlIO enabled with the following big modification: perlio.h: * #define PerlIO_fdupopen(f) (f) as perlsdio.h does doio.c pp_sys.c perl.h perlsdio.h: * remove all SOCKS_64BIT_BUG code Configure: * force PerlIO if SOCKS is configured
Compiles on * Solaris 8 v9 * Solaris 8 i86pc * Solaris 2.6 sparc has not been tested
and completes the testsuite on success on * Solaris 8 v9
but t/lib/io_sock.t (close-bug) fails on * Solaris 8 i86pc * Solaris 2.6 sparc has not been tested
perl@7847 with SOCKS and PerlIO enabled with the following bigger modification: perlio.h: * #define PerlIO_fdupopen(f) (f) as perlsdio.h does doio.c pp_sys.c perl.h perlsdio.h: * remove all SOCKS_64BIT_BUG code Configure: * force PerlIO if SOCKS is configured perlio.c: * Apply the close-patch to PerlIOStdio_close
Compiles on * Solaris 8 v9 * Solaris 8 i86pc * Solaris 2.6 sparc is currently under test
and completes the testsuite on success * Solaris 8 v9 * Solaris 8 i86pc * Solaris 2.6 sparc is currently under test
The attached patch: * adds a workaround to the PerlIO_fdupopen problem. This should be doublechecked by Nick! * removes all SOCKS_64BIT_BUG code * forces PerlIO if SOCKS is configured * applies the close-patch to PerlIOStdio_close * adds the SOCKS c/s tests to t/lib/io_sock.t
and should be the final solution to the SOCKS problem. Removing all the Socks/64 bit workarounds requires\, that PerlIO is forced!
Hey\, it took me a couple of hours to figure all this out today ... ... maybe it's possible to add an acknowlegdement somewhere in the release notes for the DeTeSystem GmbH who paid me as consultant during this time\, and the weeks before! I couldn't have done all these tests and patches without them. That's my idea\, not theirs ...
I'm looking forward to your reactions to the attached patch.
-- Jens
/ +##+|##+ STRAWBERRY Jens Hamisch +v#+v v##+ EDV-Systeme GmbH Managing director / v v\v | . . . | Brauneckweg 2 Car (Voice): (+49 172) 81 04 162 | . | D-82549 Koenigsdorf Voice: (+49 8179) 9305-50 | . | Fax: (+49 8179) 9305-38 \ . / Tel./Fax: (+49 8179) 9305-50 Email: jens@Strawberry.COM \____/ Strawberry@Strawberry.COM
*** ./perl.h.FCS Fri Nov 24 16:05:41 2000
--- ./perl.h Fri Nov 24 16:14:21 2000
***************
*** 737\,745 ****
# undef INCLUDE_PROTOTYPES
# undef PERL_SOCKS_NEED_PROTOTYPES
# endif
- # ifdef USE_64_BIT_ALL
- # define SOCKS_64BIT_BUG /* until proven otherwise */
- # endif
# endif
# ifdef I_NETDB
# include \<netdb.h>
--- 737\,742 ----
***************
*** 2819\,2834 ****
#define PERL_CKDEF(s) OP *s (pTHX_ OP *o);
#define PERL_PPDEF(s) OP *s (pTHX);
- #ifdef SOCKS_64BIT_BUG
- typedef struct __s64_iobuffer {
- struct __s64_iobuffer *next\, *last; /* Queue pointer */
- PerlIO *fp; /* Assigned file pointer */
- int cnt; /* Buffer counter */
- int size; /* Buffer size */
- int *buffer; /* The buffer */
- } S64_IOB;
- #endif
-
#include "proto.h"
#ifdef PERL_OBJECT
--- 2816\,2821 ----
*** ./perlio.h.FCS Fri Nov 24 15:25:04 2000
--- ./perlio.h Fri Nov 24 15:25:13 2000
***************
*** 303\,309 ****
extern int PerlIO_setpos (PerlIO *\,const Fpos_t *);
#endif
#ifndef PerlIO_fdupopen
! extern PerlIO * PerlIO_fdupopen (PerlIO *);
#endif
#ifndef PerlIO_isutf8
extern int PerlIO_isutf8 (PerlIO *);
--- 303\,310 ----
extern int PerlIO_setpos (PerlIO *\,const Fpos_t *);
#endif
#ifndef PerlIO_fdupopen
! #define PerlIO_fdupopen(f) (f)
! /* extern PerlIO * PerlIO_fdupopen (PerlIO *); */
#endif
#ifndef PerlIO_isutf8
extern int PerlIO_isutf8 (PerlIO *);
*** ./Configure.FCS Fri Nov 24 16:04:31 2000
--- ./Configure Fri Nov 24 16:30:48 2000
***************
*** 3673\,3679 ****
cat \<\<EOM
Perl can be built to use the SOCKS proxy protocol library. To do so\,
! Configure must be run with -Dusesocks.
If this doesn't make any sense to you\, just accept the default '$dflt'.
EOM
--- 3673\,3680 ----
cat \<\<EOM
Perl can be built to use the SOCKS proxy protocol library. To do so\,
! Configure must be run with -Dusesocks. Configuring Perl for SOCKS
! will implicitely configure PerlIO.
If this doesn't make any sense to you\, just accept the default '$dflt'.
EOM
***************
*** 3686\,3691 ****
--- 3687\,3696 ----
set usesocks
eval $setvar
+ case "$usesocks" in
+ $define|true|[yY]*) useperlio="$define" ;;
+ esac
+
: Looking for optional libraries
echo " "
echo "Checking for optional libraries..." >&4
***************
*** 7436\,7456 ****
problems with some extension modules. Using PerlIO with stdio is safe\,
but it is slower than plain stdio and therefore is not the default.
If this doesn't make any sense to you\, just accept the default '$dflt'.
EOM
! rp='Use the experimental PerlIO abstraction layer?'
! . ./myread
! case "$ans" in
! y|Y)
val="$define"
;;
! *)
echo "Ok\, doing things the stdio way"
val="$undef"
;;
esac
- set useperlio
- eval $setvar
case "$vendorprefix" in
'') d_vendorbin="$undef"
--- 7441\,7476 ----
problems with some extension modules. Using PerlIO with stdio is safe\,
but it is slower than plain stdio and therefore is not the default.
+ EOM
+
+ case "$usesocks" in
+ $define|true|[yY]*)
+ cat \<\<EOM
+ The PerlIO abstraction layer is forced by the SOCKS configuration.
+
+ EOM
+ useperlio="$define"
+ ;;
+ *)
+ cat \<\<EOM
If this doesn't make any sense to you\, just accept the default '$dflt'.
+
EOM
! rp='Use the experimental PerlIO abstraction layer?'
! . ./myread
! case "$ans" in
! y|Y)
val="$define"
;;
! *)
echo "Ok\, doing things the stdio way"
val="$undef"
;;
+ esac
+ set useperlio
+ eval $setvar
+ ;;
esac
case "$vendorprefix" in
'') d_vendorbin="$undef"
*** ./embed.pl.FCS Fri Nov 24 16:05:41 2000
--- ./embed.pl Fri Nov 24 16:15:54 2000
***************
*** 1505\,1522 ****
p |UV |do_vecget |SV* sv|I32 offset|I32 size
p |void |do_vecset |SV* sv
p |void |do_vop |I32 optype|SV* sv|SV* left|SV* right
- #if defined(SOCKS_64BIT_BUG)
- p |Off_t |do_s64_tell |PerlIO* fp
- p |SSize_t|do_s64_fread |void *buf|SSize_t count|PerlIO* fp
- p |int |do_s64_getc |PerlIO* fp
- p |int |do_s64_seek |PerlIO* fp|Off_t pos|int whence
- p |int |do_s64_ungetc |int ch|PerlIO* fp
- p |void |do_s64_delete_buffer|PerlIO* fp
- Ajnop |void |do_s64_init_buffer
- s |S64_IOB * |s64_get_buffer |PerlIO *f
- s |S64_IOB * |s64_create_buffer |PerlIO *f
- s |int |s64_malloc |S64_IOB *ptr
- #endif
p |OP* |dofile |OP* term
Ap |I32 |dowantarray
Ap |void |dump_all
--- 1505\,1510 ----
*** ./perlsdio.h.FCS Fri Nov 24 16:05:41 2000
--- ./perlsdio.h Fri Nov 24 16:15:26 2000
***************
*** 18\,28 ****
#define PerlIO_open fopen
#define PerlIO_fdopen fdopen
#define PerlIO_reopen freopen
! #ifdef SOCKS_64BIT_BUG
! # define PerlIO_close(f) (Perl_do_s64_delete_buffer(aTHX_ f)\, fclose(f))
! #else
! # define PerlIO_close(f) fclose(f)
! #endif
#define PerlIO_puts(f\,s) fputs(s\,f)
#define PerlIO_putc(f\,c) fputc(c\,f)
#if defined(VMS)
--- 18\,24 ----
#define PerlIO_open fopen
#define PerlIO_fdopen fdopen
#define PerlIO_reopen freopen
! #define PerlIO_close(f) fclose(f)
#define PerlIO_puts(f\,s) fputs(s\,f)
#define PerlIO_putc(f\,c) fputc(c\,f)
#if defined(VMS)
***************
*** 47\,63 ****
(feof(f) ? 0 : (SSize_t)fread(buf\,1\,count\,f))
# define PerlIO_tell(f) ftell(f)
#else
! # ifdef SOCKS_64BIT_BUG
! # define PerlIO_getc(f) Perl_do_s64_getc(aTHX_ f)
! # define PerlIO_ungetc(f\,c) Perl_do_s64_ungetc(aTHX_ c\,f)
! # define PerlIO_read(f\,buf\,count) Perl_do_s64_fread(aTHX_ buf\,count\,f)
! # define PerlIO_tell(f) Perl_do_s64_tell(aTHX_ f)
! # else
! # define PerlIO_getc(f) getc(f)
! # define PerlIO_ungetc(f\,c) ungetc(c\,f)
! # define PerlIO_read(f\,buf\,count) (SSize_t)fread(buf\,1\,count\,f)
! # define PerlIO_tell(f) ftell(f)
! # endif /* SOCKS_64BIT_BUG */
#endif
#define PerlIO_eof(f) feof(f)
#define PerlIO_getname(f\,b) fgetname(f\,b)
--- 43\,52 ----
(feof(f) ? 0 : (SSize_t)fread(buf\,1\,count\,f))
# define PerlIO_tell(f) ftell(f)
#else
! # define PerlIO_getc(f) getc(f)
! # define PerlIO_ungetc(f\,c) ungetc(c\,f)
! # define PerlIO_read(f\,buf\,count) (SSize_t)fread(buf\,1\,count\,f)
! # define PerlIO_tell(f) ftell(f)
#endif
#define PerlIO_eof(f) feof(f)
#define PerlIO_getname(f\,b) fgetname(f\,b)
***************
*** 65\,79 ****
#define PerlIO_fileno(f) fileno(f)
#define PerlIO_clearerr(f) clearerr(f)
#define PerlIO_flush(f) Fflush(f)
! #ifdef SOCKS_64BIT_BUG
! # define PerlIO_seek(f\,o\,w) Perl_do_s64_seek(aTHX_ f\,o\,w)
#else
! # if defined(VMS) && !defined(__DECC)
! /* Old VAXC RTL doesn't reset EOF on seek; Perl folk seem to expect this */
! # define PerlIO_seek(f\,o\,w) (((f) && (*f) && ((*f)->_flag &= ~_IOEOF))\,fseek(f\,o\,w))
! # else
! # define PerlIO_seek(f\,o\,w) fseek(f\,o\,w)
! # endif
#endif
#ifdef HAS_FGETPOS
#define PerlIO_getpos(f\,p) fgetpos(f\,p)
--- 54\,64 ----
#define PerlIO_fileno(f) fileno(f)
#define PerlIO_clearerr(f) clearerr(f)
#define PerlIO_flush(f) Fflush(f)
! #if defined(VMS) && !defined(__DECC)
! /* Old VAXC RTL doesn't reset EOF on seek; Perl folk seem to expect this */
! #define PerlIO_seek(f\,o\,w) (((f) && (*f) && ((*f)->_flag &= ~_IOEOF))\,fseek(f\,o\,w))
#else
! # define PerlIO_seek(f\,o\,w) fseek(f\,o\,w)
#endif
#ifdef HAS_FGETPOS
#define PerlIO_getpos(f\,p) fgetpos(f\,p)
*** ./doio.c.FCS Fri Nov 24 16:05:41 2000
--- ./doio.c Fri Nov 24 16:14:02 2000
***************
*** 2039\,2215 ****
#endif /* SYSV IPC */
- #ifdef SOCKS_64BIT_BUG
-
- /**
- ** getc and ungetc wrappers for the 64 bit problems with SOCKS 5 support
- ** Workaround to the problem\, that SOCKS maps a socket 'getc' to revc
- ** without checking the ungetc buffer.
- **/
-
- /* Not threadsafe? */
- static S64_IOB *s64_buffer = (S64_IOB *) NULL;
-
- /* initialize the buffer area */
- /* required after a fork(2) call in order to remove side effects */
- void
- Perl_do_s64_init_buffer(void)
- {
- s64_buffer = (S64_IOB *) NULL;
- }
-
- /* get a buffered stream pointer */
- STATIC S64_IOB*
- S_s64_get_buffer(pTHX_ PerlIO *fp)
- {
- S64_IOB *ptr = s64_buffer;
- while( ptr && ptr->fp != fp)
- ptr = ptr->next;
- return( ptr);
- }
-
- /* create a buffered stream pointer */
- STATIC S64_IOB*
- S_s64_create_buffer(pTHX_ PerlIO *f)
- {
- S64_IOB *ptr = malloc( sizeof( S64_IOB));
- if( ptr) {
- ptr->fp = f;
- ptr->cnt = ptr->size = 0;
- ptr->buffer = (int *) NULL;
- ptr->next = s64_buffer;
- ptr->last = (S64_IOB *) NULL;
- if( s64_buffer) s64_buffer->last = ptr;
- s64_buffer = ptr;
- }
- return( ptr);
- }
-
- /* delete a buffered stream pointer */
- void
- Perl_do_s64_delete_buffer(pTHX_ PerlIO *f)
- {
- S64_IOB *ptr = S_s64_get_buffer(aTHX_ f);
- if( ptr) {
- /* fix the stream pointer according to the bytes buffered */
- /* required\, if this is called in a seek-context */
- if( ptr->cnt) fseek(f\,-ptr->cnt\,SEEK_CUR);
- if( ptr->buffer) free( ptr->buffer);
- if( ptr->last)
- ptr->last->next = ptr->next;
- else
- s64_buffer = ptr->next;
- free( ptr);
- }
- }
-
- /* internal buffer management */
-
- #define S64_BUFFER_SIZE 32
-
- STATIC int
- S_s64_malloc(pTHX_ S64_IOB *ptr)
- {
- if( ptr) {
- if( !ptr->buffer) {
- ptr->buffer = (int *) calloc( S64_BUFFER_SIZE\, sizeof( int));
- ptr->size = ptr->cnt = 0;
- } else {
- ptr->buffer = (int *) realloc( ptr->buffer\,
- ptr->size + S64_BUFFER_SIZE);
- }
-
- if( !ptr->buffer)
- return( 0);
-
- ptr->size += S64_BUFFER_SIZE;
-
- return( 1);
- }
-
- return( 0);
- }
-
- /* SOCKS 64 bit getc replacement */
- int
- Perl_do_s64_getc(pTHX_ PerlIO *f)
- {
- S64_IOB *ptr = S_s64_get_buffer(aTHX_ f);
- if( ptr) {
- if( ptr->cnt)
- return( ptr->buffer[--ptr->cnt]);
- }
- return( getc(f));
- }
-
- /* SOCKS 64 bit ungetc replacement */
- int
- Perl_do_s64_ungetc(pTHX_ int ch\, PerlIO *f)
- {
- S64_IOB *ptr = S_s64_get_buffer(aTHX_ f);
-
- if( !ptr) ptr = S_s64_create_buffer(aTHX_ f);
- if( !ptr) return( EOF);
- if( !ptr->buffer || (ptr->buffer && ptr->cnt >= ptr->size))
- if( !S_s64_malloc(aTHX_ ptr)) return( EOF);
- ptr->buffer[ptr->cnt++] = ch;
-
- return( ch);
- }
-
- /* SOCKS 64 bit fread replacement */
- SSize_t
- Perl_do_s64_fread(pTHX_ void *buf\, SSize_t count\, PerlIO* f)
- {
- SSize_t len = 0;
- char *bufptr = (char *) buf;
- S64_IOB *ptr = S_s64_get_buffer(aTHX_ f);
- if( ptr) {
- while( ptr->cnt && count) {
- *bufptr++ = ptr->buffer[--ptr->cnt];
- count--\, len++;
- }
- }
- if( count)
- len += (SSize_t)fread(bufptr\,1\,count\,f);
-
- return( len);
- }
-
- /* SOCKS 64 bit fseek replacement */
- int
- Perl_do_s64_seek(pTHX_ PerlIO* f\, Off_t offset\, int whence)
- {
- S64_IOB *ptr = S_s64_get_buffer(aTHX_ f);
-
- /* Simply clear the buffer and seek if the position is absolute */
- if( SEEK_SET == whence || SEEK_END == whence) {
- if( ptr) ptr->cnt = 0;
-
- /* In case of relative positioning clear the buffer and calculate */
- /* a fixed offset */
- } else if( SEEK_CUR == whence) {
- if( ptr) {
- offset -= (Off_t)ptr->cnt;
- ptr->cnt = 0;
- }
- }
-
- /* leave out buffer untouched otherwise\, because fseek will fail */
- /* seek now */
- return( fseeko( f\, offset\, whence));
- }
-
- /* SOCKS 64 bit ftell replacement */
- Off_t
- Perl_do_s64_tell(pTHX_ PerlIO* f)
- {
- Off_t offset = 0;
- S64_IOB *ptr = S_s64_get_buffer(aTHX_ f);
- if( ptr)
- offset = ptr->cnt;
- return( ftello(f) - offset);
- }
-
- #endif /* SOCKS_64BIT_BUG */
-
--- 2039\,2041 ----
*** ./pp_sys.c.FCS Fri Nov 24 16:05:42 2000
--- ./pp_sys.c Fri Nov 24 16:15:39 2000
***************
*** 3732\,3740 ****
if (childpid \< 0)
RETSETUNDEF;
if (!childpid) {
- #ifdef SOCKS_64BIT_BUG
- Perl_do_s64_init_buffer();
- #endif
/*SUPPRESS 560*/
if ((tmpgv = gv_fetchpv("$"\, TRUE\, SVt_PV)))
sv_setiv(GvSV(tmpgv)\, (IV)PerlProc_getpid());
--- 3732\,3737 ----
*** perlio.c.FCS Fri Nov 24 17:55:38 2000
--- perlio.c Fri Nov 24 18:01:13 2000
***************
*** 1368\,1375 ****
IV
PerlIOStdio_close(PerlIO *f)
{
FILE *stdio = PerlIOSelf(f\,PerlIOStdio)->stdio;
! return fclose(stdio);
}
IV
--- 1368\,1379 ----
IV
PerlIOStdio_close(PerlIO *f)
{
+ int optval\, optlen = sizeof(int);
FILE *stdio = PerlIOSelf(f\,PerlIOStdio)->stdio;
! return(
! (getsockopt(PerlIO_fileno(f)\, SOL_SOCKET\, SO_TYPE\, (char *)&optval\, &optlen) \< 0) ?
! fclose(stdio) :
! close(PerlIO_fileno(f)));
}
IV
*** t/lib/io_sock.t.FCS Fri Nov 24 18:08:28 2000
--- t/lib/io_sock.t Fri Nov 24 18:08:48 2000
***************
*** 30\,36 ****
}
$| = 1;
! print "1..14\n";
use IO::Socket;
--- 30\,36 ----
}
$| = 1;
! print "1..20\n";
use IO::Socket;
***************
*** 203\,205 ****
--- 203\,333 ----
$server->blocking(0);
print "not " if $server->blocking;
print "ok 14\n";
+
+ ### TEST 15
+ ### Set up some data to be transfered between the server and
+ ### the client. We'll use own source code ...
+ #
+ local @data;
+ if( !open( SRC\, "\< ../$0")) {
+ print "not ok 15 - $!";
+ } else {
+ @data = \
+ ### Child
+ #
+ SERVER_LOOP: while (1) {
+ last SERVER_LOOP unless $sock = $listen->accept;
+ while (\<$sock>) {
+ last SERVER_LOOP if /^quit/;
+ last if /^done/;
+ if( /^send/) {
+ print $sock @data;
+ last;
+ }
+ print;
+ }
+ $sock = undef;
+ }
+ $listen->close;
+
+ } else {
+
+ ### Fork failed
+ #
+ print "not ok 17\n";
+ die;
+ }
+
Hi\,
there is a little typo in the patch I've mailed. Apply this after the patch:
*** t/lib/io_sock.t.FCS Fri Nov 24 18:59:14 2000
--- t/lib/io_sock.t Fri Nov 24 18:58:19 2000
***************
*** 209\,215 ****
### the client. We'll use own source code ...
#
local @data;
! if( !open( SRC\, "\< ../$0")) {
print "not ok 15 - $!";
} else {
@data = \
BTW: The test on Solaris 2.6 sparc were successfull!
-- Jens
/ +##+|##+ STRAWBERRY Jens Hamisch +v#+v v##+ EDV-Systeme GmbH Managing director / v v\v | . . . | Brauneckweg 2 Car (Voice): (+49 172) 81 04 162 | . | D-82549 Koenigsdorf Voice: (+49 8179) 9305-50 | . | Fax: (+49 8179) 9305-38 \ . / Tel./Fax: (+49 8179) 9305-50 Email: jens@Strawberry.COM \____/ Strawberry@Strawberry.COM
Migrated from rt.perl.org#4549 (status was 'resolved')
Searchable as RT4549$