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

recv dies using 'die' in FBSD #692

Closed
p5pRT opened this issue Oct 8, 1999 · 5 comments
Closed

recv dies using 'die' in FBSD #692

p5pRT opened this issue Oct 8, 1999 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 8, 1999

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

Searchable as RT1590$

@p5pRT
Copy link
Author

p5pRT commented Oct 8, 1999

From rns@bsd2.lsa.net

Using recipe 17.2 from the PCB, I tried sending data to a port I had opened
using $handle->recv($data,$maxlen) or die "Can't receive​: $!\n"; When I sent
data to the port however, the script died immediately at that line and
without returning any error message through $!. However, if I remove the
'or die..' part of the statment, the script works marvelously.

I've tried this on several FBSD 3.2 RELEASE boxes and as well as one
3.3 RELEASE box as well with the same results.

mjk

Perl Info


Site configuration information for perl 5.00503:

Configured by markm at $Date: 1999/05/05 19:42:40 $.

Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration:
  Platform:
    osname=freebsd, osvers=4.0-current, archname=i386-freebsd
    uname='freebsd freefall.freebsd.org 4.0-current freebsd 4.0-current #0: $Date: 1999/05/05 19:42:40 $'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef useperlio=undef d_sfio=undef
  Compiler:
    cc='cc', optimize='undef', gccversion=egcs-2.91.66 19990314 (egcs-1.1.2 release)
    cppflags=''
    ccflags =''
    stdchar='char', d_stdstdio=undef, usevfork=true
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags ='-Wl,-E'
    libpth=/usr/lib
    libs=-lm -lc -lcrypt
    libc=/usr/lib/libc.so, so=so, useshrplib=true, libperl=libperl.so.3
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-DPIC -fpic', lddlflags='-shared'

Locally applied patches:
    


@INC for perl 5.00503:
    /usr/libdata/perl/5.00503/mach
    /usr/libdata/perl/5.00503
    /usr/local/lib/perl5/site_perl/5.005/i386-freebsd
    /usr/local/lib/perl5/site_perl/5.005
    .


Environment for perl 5.00503:
    HOME=/home/lsa/rns
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/bin:/usr/X11R6/bin:/home/lsa/rns/bin
    PERL_BADLANG (unset)
    SHELL=/usr/local/bin/tcsh

@p5pRT
Copy link
Author

p5pRT commented Oct 8, 1999

From @tobez

On Thu, Oct 07, 1999 at 10​:36​:15PM -0500, Blah wrote​:

Using recipe 17.2 from the PCB, I tried sending data to a port I had
opened using $handle->recv($data,$maxlen) or die "Can't receive​:

I don't really actually see any mention of recv() in recipe 17.2.

Anyway, the actual piece of code in question might be useful.

$!\n"; When I sent data to the port however, the script died
immediately at that line and without returning any error message
through $!. However, if I remove the 'or die..' part of the statment,
the script works marvelously.

Cheers,
--
Anton Berezin <tobez@​plab.ku.dk>
The Protein Laboratory, University of Copenhagen

@p5pRT
Copy link
Author

p5pRT commented Oct 8, 1999

From [Unknown Contact. See original ticket]

my bad, its actually in 17.3.

using the code in 17.2 to open the socket and adding the recv function
found in 17.3 i end up with the following code​:

-*-----------------*-
#!/usr/bin/perl
use IO​::Socket;

$server_port = "5000"; # use any port >1024 you like, this doesnt seem to matter
$server = IO​::Socket​::INET->new(LocalPort => $server_port,
  Type => SOCK_STREAM,
  Reuse => 1,
  Listen => 10 )
  or die "Couldn't be a tcp server on prot $server_port : $@​\n";

while ($client = $server->accept()) {
  $maxlen = "30";

  # code from 17.3
  $client->recv($data_read, $maxlen) # slightly modified as specified by Net​::Gen
  or die "Can't recv​: $!\n";
}
-*-----------------*-

this code successfully opens a socket on the port and I can establish a
connection to it. as soon as i send any data to the port however i get the
following​:

bash# perl testsvr.pl
Can't recv​:
bash#

what i found is that if i remark out the 'die' portion as such​:

  $client->recv($data_read, $maxlen); # slightly modified as specified by Net​::Gen
  # or die "Can't recv​: $!\n";

the script works just fine and can receive data w/o hiccup. i've tested
the same script with the 'die' on a linux, hpux, and ppc box and all work
successfully. it only seems to fail on FBSD (tested 3.2 RELEASE & 3.3
RELEASE) and possibly on Sun (though i'm not sure what version).

hope this clears it up a little.

mjk

On Fri, 8 Oct 1999, Anton Berezin wrote​:

On Thu, Oct 07, 1999 at 10​:36​:15PM -0500, Blah wrote​:

Using recipe 17.2 from the PCB, I tried sending data to a port I had
opened using $handle->recv($data,$maxlen) or die "Can't receive​:

I don't really actually see any mention of recv() in recipe 17.2.

Anyway, the actual piece of code in question might be useful.

$!\n"; When I sent data to the port however, the script died
immediately at that line and without returning any error message
through $!. However, if I remove the 'or die..' part of the statment,
the script works marvelously.

Cheers,
--
Anton Berezin <tobez@​plab.ku.dk>
The Protein Laboratory, University of Copenhagen

@p5pRT
Copy link
Author

p5pRT commented Oct 9, 1999

From [Unknown Contact. See original ticket]

On Fri, 08 Oct 1999 at 13​:06​:20 +0200, Anton Berezin wrote​:

On Thu, Oct 07, 1999 at 10​:36​:15PM -0500, Blah wrote​:

Using recipe 17.2 from the PCB, I tried sending data to a port I had
opened using $handle->recv($data,$maxlen) or die "Can't receive​:

I don't really actually see any mention of recv() in recipe 17.2.
Anyway, the actual piece of code in question might be useful.

There is also the point that 'recv' doesn't send data - it receives it.
Clarification of what you really meant would be useful.

Ian
--
To check if the playing field is level, one must first get off one's high horse
  - Tony Kavanagh <kavteam@​terrigal.net.au>

@p5pRT
Copy link
Author

p5pRT commented Oct 9, 1999

From @tobez

On Fri, Oct 08, 1999 at 09​:35​:08PM -0700, Mike Keenan wrote​:

using the code in 17.2 to open the socket and adding the recv function
found in 17.3 i end up with the following code​:

#!/usr/bin/perl
use IO​::Socket;

$server_port = "5000"; # use any port >1024 you like, this doesnt seem to matter
$server = IO​::Socket​::INET->new(LocalPort => $server_port,
Type => SOCK_STREAM,
Reuse => 1,
Listen => 10 )
or die "Couldn't be a tcp server on prot $server_port : $@​\n";

while ($client = $server->accept()) {
$maxlen = "30";

# code from 17.3
$client->recv($data_read, $maxlen) # slightly modified as specified by Net​::Gen
or die "Can't recv​: $!\n";
}

this code successfully opens a socket on the port and I can establish
a connection to it. as soon as i send any data to the port however i
get the following​:

bash# perl testsvr.pl
Can't recv​:

Okay, what would you expect? :-)

Perl's recv() returns the address of the sender. To be able to do so it
uses recvfrom(2) internally. From FreeBSD's recvfrom(2) manpage​:

  If from is non-nil, and the socket is not connection-oriented, the
  source address of the message is filled in. Fromlen is a
  value-result parameter, initialized to the size of the buffer
  associated with from, and modified on return to indicate the actual
  size of the address stored there.

It is implied, but, unfortunately, not stated clearly, that for
*connection-oriented* sockets the source address is *not* filled in.
This is indeed the case in FreeBSD​:

The recvfrom syscall calls in turn soreceive() internal function, which
only fills the ``from'' field if PR_ADDR flag is set in the protosw
structure for the protocol used. PR_ADDR is *not* set for SOCK_STREAM.

On the other hand, Perl documentation says that recv() returns undef on
error, and in your case it behaves accordingly, i.e. there was no error,
so it returns empty scalar, not an undef!

Basically, the Perl Cookbook is wrong suggesting to use `or die' instead
of `die unless defined', and IMHO Perl documentation for recv() needs
to be corrected so the user will not expect to get a sender address
using a connection-oriented protocol, and (another IMHO) FreeBSD manpage
for recvfrom(2) needs to be corrected to specify exactly what happens
with a `from' parameter in different situations.

I think I'll submit patches for the two ``needs to be corrected'' items
above. :-)

Cheers,
--
Anton Berezin <tobez@​plab.ku.dk>
The Protein Laboratory, University of Copenhagen

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