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

Script misses EOF on Solaris #807

Closed
p5pRT opened this issue Nov 3, 1999 · 14 comments
Closed

Script misses EOF on Solaris #807

p5pRT opened this issue Nov 3, 1999 · 14 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 3, 1999

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

Searchable as RT1734$

@p5pRT
Copy link
Author

p5pRT commented Nov 3, 1999

From dehc@dhassler.comp.pge.com

#!/usr/local/bin/perl -w
use strict;

# This script runs as expected on AIX, HP/UX, Linux, SunOS 4.1
# Never sees EOF on <IN> under Solaris, Unixware.
# dehc@​pge.com

my($MAX) = 64;

open( IN, "$0" ) || die "open $!\n";; # open self as input

$SIG{CHLD} = 'IGNORE';

my( $count ) = 0;
my( $chldpid ) = 0;

$| = 1;

while ( <IN> ) { chomp;

  ++$count; # break out counter

  $chldpid = fork(); # Fork one child per line of input.

  if ( $chldpid == 0 ) { # Child

  print "$count chldpid $$​: $_\n";
  exit(0);

  } else { print "==>$count $. forked $chldpid\n"; } # Parent

  if ( $count > $MAX ) { print "MAX count ($MAX) exceeded\n"; last; }
}

Perl Info


Site configuration information for perl 5.00503:

Configured by dehc at Mon Oct 25 14:23:34 PDT 1999.

Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration:
  Platform:
    osname=solaris, osvers=2.6, archname=sun4-solaris
    uname='sunos dhassler 5.6 generic_105181-15 sun4u sparc sunw,ultra-2 '
    hint=previous, useposix=true, d_sigaction=define
    usethreads=undef useperlio=undef d_sfio=undef
  Compiler:
    cc='/opt/SUNWspro/bin/cc', optimize='-g', gccversion=
    cppflags='-I/usr/local/include'
    ccflags ='-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=16
    alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /usr/ccs/lib
    libs=-lsocket -lnsl -ldl -lm -lc -lcrypt -lposix4
    libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-KPIC -g', lddlflags='-G -L/usr/local/lib -g'

Locally applied patches:
    


@INC for perl 5.00503:
    /usr/local/lib/perl5/5.00503/sun4-solaris
    /usr/local/lib/perl5/5.00503
    /usr/local/lib/perl5/site_perl/5.005/sun4-solaris
    /usr/local/lib/perl5/site_perl/5.005
    .


Environment for perl 5.00503:
    HOME=/export/home/dehc
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/bin:/opt/NSCPcom:/opt/SUNWspro/SC4.2/bin:/opt/SoftWindows/bin:/usr/ccs/bin:/usr/dt/bin:/usr/openwin/bin:/usr/sbin:/usr/ucb:/etc:/usr/local/bin:/usr/proc/bin:.:/opt/oracle/bin:/opt/oracle/dba:/opt/oracle/TOOLS
    PERL_BADLANG (unset)
    SHELL=/bin/csh

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2006

From @smpeters

[dehc@​dhassler.comp.pge.com - Wed Nov 03 00​:11​:41 1999]​:

-----------------------------------------------------------------
[Please enter your report here]

#!/usr/local/bin/perl -w
use strict;

# This script runs as expected on AIX, HP/UX, Linux, SunOS 4.1
# Never sees EOF on <IN> under Solaris, Unixware.
# dehc@​pge.com

my($MAX) = 64;

open( IN, "$0" ) || die "open $!\n";; # open self as input

$SIG{CHLD} = 'IGNORE';

my( $count ) = 0;
my( $chldpid ) = 0;

$| = 1;

while ( <IN> ) { chomp;

\+\+$count;            \# break out counter

$chldpid = fork\(\);        \# Fork one child per line of input\.

if \( $chldpid == 0 \) \{        \# Child

    print "$count chldpid $$&#8203;: $\_\\n";
    exit\(0\);

\} else \{ print "==>$count $\. forked $chldpid\\n"; \} \# Parent

if \( $count > $MAX \) \{ print "MAX count \($MAX\) exceeded\\n"; last; \}

}

This is an old one, but certainly confirmed. On Linux and OpenBSD, the
program functions normally and stops after printing the last line of the
program. On Solaris, it seems to restart over at the beginning of the file.

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2006

From @AlanBurlison

Steve Peters via RT wrote​:

This is an old one, but certainly confirmed. On Linux and OpenBSD, the
program functions normally and stops after printing the last line of the
program. On Solaris, it seems to restart over at the beginning of the file.

http​://www.gossamer-threads.com/lists/perl/porters/183790

--
Alan Burlison
--

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2006

From @smpeters

On Mon, Feb 06, 2006 at 06​:20​:50PM +0000, Alan Burlison wrote​:

Steve Peters via RT wrote​:

This is an old one, but certainly confirmed. On Linux and OpenBSD, the
program functions normally and stops after printing the last line of the
program. On Solaris, it seems to restart over at the beginning of the
file.

http​://www.gossamer-threads.com/lists/perl/porters/183790

Splendid! For posterity, the important note for Solaris users in that
thread was (from Alan Burlison, of course)

  As the fork() manpage says​:

  An application should call _exit() rather than exit(3C) if
  it cannot execve(), since exit() will flush and close stan-
  dard I/O channels and thereby corrupt the parent process's
  standard I/O data structures.

  Big rule​: Don't use exit() after fork(), use _exit().

@p5pRT p5pRT closed this as completed Feb 6, 2006
@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2006

@smpeters - Status changed from 'open' to 'resolved'

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2006

From @smpeters

[stmpeters - Mon Feb 06 11​:07​:43 2006]​:

On Mon, Feb 06, 2006 at 06​:20​:50PM +0000, Alan Burlison wrote​:

Steve Peters via RT wrote​:

This is an old one, but certainly confirmed. On Linux and OpenBSD, the
program functions normally and stops after printing the last line
of the
program. On Solaris, it seems to restart over at the beginning of the
file.

http​://www.gossamer-threads.com/lists/perl/porters/183790

Splendid! For posterity, the important note for Solaris users in that
thread was (from Alan Burlison, of course)

As the fork() manpage says​:

An application should call _exit() rather than exit(3C) if
it cannot execve(), since exit() will flush and close stan-
dard I/O channels and thereby corrupt the parent process's
standard I/O data structures.

Big rule​: Don't use exit() after fork(), use _exit().

I guess perldocs for this would be nice too :). I've added the
following to perlfork. Questions, comments, and concerns are appreciated.

Change 27108 by stevep@​stevep-mccoy on 2006/02/06 19​:43​:17

  Document the limitations of calling exit() (instead of _exit()) from
  a child process on Solaris.

Affected files ...

... //depot/perl/pod/perlfork.pod#11 edit

Differences ...

==== //depot/perl/pod/perlfork.pod#11 (text) ====

@​@​ -100,7 +100,7 @​@​
exit() always exits just the executing pseudo-process, after automatically
wait()-ing for any outstanding child pseudo-processes. Note that this
means
that the process as a whole will not exit unless all running
pseudo-processes
-have exited.
+have exited. See below for some limitations with open filehandles.

=item Open handles to files, directories and network sockets

@​@​ -177,6 +177,13 @​@​
One can avoid this by opening files that need distinct seek pointers
separately in the child.

+On some operating systems, notably Solaris and Unixware, calling C<exit()>
+from a child process will flush and close open filehandles in the parent,
+thereby corrupting the filehandles. On these systems, calling C<_exit()>
+is suggested instead. C<_exit()> is available in Perl through the
+C<POSIX> module. Please consult your systems manpages for more information
+on this.
+
=item Forking pipe open() not yet implemented

The C<open(FOO, "|-")> and C<open(BAR, "-|")> constructs are not yet

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2006

From @nwc10

On Mon, Feb 06, 2006 at 11​:44​:24AM -0800, Steve Peters via RT wrote​:

+On some operating systems, notably Solaris and Unixware, calling C<exit()>
+from a child process will flush and close open filehandles in the parent,
+thereby corrupting the filehandles. On these systems, calling C<_exit()>
+is suggested instead. C<_exit()> is available in Perl through the
+C<POSIX> module. Please consult your systems manpages for more information
+on this.
+

I think I'd prefer it if "On these systems..." were changed to "In the child
process following a C<fork> you should always call C<POSIX​::_exit()> instead
of C<exit()>"

I believe that it's never incorrect to call _exit(), so we're doing no-one
any favours by suggesting that they can get away with exit().

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2006

From @smpeters

On Mon, Feb 06, 2006 at 07​:52​:05PM +0000, Nicholas Clark wrote​:

On Mon, Feb 06, 2006 at 11​:44​:24AM -0800, Steve Peters via RT wrote​:

+On some operating systems, notably Solaris and Unixware, calling C<exit()>
+from a child process will flush and close open filehandles in the parent,
+thereby corrupting the filehandles. On these systems, calling C<_exit()>
+is suggested instead. C<_exit()> is available in Perl through the
+C<POSIX> module. Please consult your systems manpages for more information
+on this.
+

I think I'd prefer it if "On these systems..." were changed to "In the child
process following a C<fork> you should always call C<POSIX​::_exit()> instead
of C<exit()>"

I believe that it's never incorrect to call _exit(), so we're doing no-one
any favours by suggesting that they can get away with exit().

I'll take a look at Win32 and Cygwin to see how they do following the
suggestion. Of course if someone knows off the top of their heads,
I'd appreciate finding out :)

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2006

From nick@ing-simmons.net

Nicholas Clark <nick@​ccl4.org> writes​:

On Mon, Feb 06, 2006 at 11​:44​:24AM -0800, Steve Peters via RT wrote​:

+On some operating systems, notably Solaris and Unixware, calling C<exit()>
+from a child process will flush and close open filehandles in the parent,
+thereby corrupting the filehandles. On these systems, calling C<_exit()>
+is suggested instead. C<_exit()> is available in Perl through the
+C<POSIX> module. Please consult your systems manpages for more information
+on this.
+

I think I'd prefer it if "On these systems..." were changed to "In the child
process following a C<fork> you should always call C<POSIX​::_exit()> instead
of C<exit()>"

I believe that it's never incorrect to call _exit(), so we're doing no-one
any favours by suggesting that they can get away with exit().

I agree with that.
I have also thought for some time that there should be a "core" way to
call _exit().

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2006

From @ysth

On Mon, Feb 06, 2006 at 10​:40​:21PM +0000, Nick Ing-Simmons wrote​:

Nicholas Clark <nick@​ccl4.org> writes​:

On Mon, Feb 06, 2006 at 11​:44​:24AM -0800, Steve Peters via RT wrote​:

+On some operating systems, notably Solaris and Unixware, calling C<exit()>
+from a child process will flush and close open filehandles in the parent,
+thereby corrupting the filehandles. On these systems, calling C<_exit()>
+is suggested instead. C<_exit()> is available in Perl through the
+C<POSIX> module. Please consult your systems manpages for more information
+on this.
+

I think I'd prefer it if "On these systems..." were changed to "In the child
process following a C<fork> you should always call C<POSIX​::_exit()> instead
of C<exit()>"

I believe that it's never incorrect to call _exit(), so we're doing no-one
any favours by suggesting that they can get away with exit().

atexit handlers installed by XS modules?

I agree with that.
I have also thought for some time that there should be a "core" way to
call _exit().

use feature "_exit"; ?

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2006

From @smpeters

Nick Ing-Simmons wrote​:

Nicholas Clark <nick@​ccl4.org> writes​:

On Mon, Feb 06, 2006 at 11​:44​:24AM -0800, Steve Peters via RT wrote​:

+On some operating systems, notably Solaris and Unixware, calling C<exit()>
+from a child process will flush and close open filehandles in the parent,
+thereby corrupting the filehandles. On these systems, calling C<_exit()>
+is suggested instead. C<_exit()> is available in Perl through the
+C<POSIX> module. Please consult your systems manpages for more information
+on this.
+
I think I'd prefer it if "On these systems..." were changed to "In the child
process following a C<fork> you should always call C<POSIX​::_exit()> instead
of C<exit()>"

I believe that it's never incorrect to call _exit(), so we're doing no-one
any favours by suggesting that they can get away with exit().

I agree with that.
I have also thought for some time that there should be a "core" way to
call _exit().

Unfortunately, it appears that _exit() doesn't work on Win32, or it just
doesn't have the effect hoped for with the manufactured fork() on Win32.

Steve Peters
steve@​fisharerojo.org

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2006

From @smpeters

[stmpeters - Mon Feb 06 19​:43​:54 2006]​:

Nick Ing-Simmons wrote​:

Nicholas Clark <nick@​ccl4.org> writes​:

On Mon, Feb 06, 2006 at 11​:44​:24AM -0800, Steve Peters via RT
wrote​:

+On some operating systems, notably Solaris and Unixware, calling
C<exit()>
+from a child process will flush and close open filehandles in the
parent,
+thereby corrupting the filehandles. On these systems, calling
C<_exit()>
+is suggested instead. C<_exit()> is available in Perl through
the
+C<POSIX> module. Please consult your systems manpages for more
information
+on this.
+
I think I'd prefer it if "On these systems..." were changed to "In
the child
process following a C<fork> you should always call
C<POSIX​::_exit()> instead
of C<exit()>"

I believe that it's never incorrect to call _exit(), so we're doing
no-one
any favours by suggesting that they can get away with exit().

I agree with that.
I have also thought for some time that there should be a "core" way
to
call _exit().

Unfortunately, it appears that _exit() doesn't work on Win32, or it
just
doesn't have the effect hoped for with the manufactured fork() on
Win32.

I shouldn't try to analyze bugs when sleepy. Actually, the lack of
output from Win32 should have pointed me to the fact that _exit() forces
the parent to exit as well as the child on Win32. That's not what we
want. So, I guess I'll be navigating the twisty maze of MSDN for that one.

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2006

From @smpeters

On Tue, Feb 07, 2006 at 04​:41​:27AM -0800, Steve Peters via RT wrote​:

[stmpeters - Mon Feb 06 19​:43​:54 2006]​:

Nick Ing-Simmons wrote​:

Nicholas Clark <nick@​ccl4.org> writes​:

On Mon, Feb 06, 2006 at 11​:44​:24AM -0800, Steve Peters via RT
wrote​:

+On some operating systems, notably Solaris and Unixware, calling
C<exit()>
+from a child process will flush and close open filehandles in the
parent,
+thereby corrupting the filehandles. On these systems, calling
C<_exit()>
+is suggested instead. C<_exit()> is available in Perl through
the
+C<POSIX> module. Please consult your systems manpages for more
information
+on this.
+
I think I'd prefer it if "On these systems..." were changed to "In
the child
process following a C<fork> you should always call
C<POSIX​::_exit()> instead
of C<exit()>"

I believe that it's never incorrect to call _exit(), so we're doing
no-one
any favours by suggesting that they can get away with exit().

I agree with that.
I have also thought for some time that there should be a "core" way
to
call _exit().

Unfortunately, it appears that _exit() doesn't work on Win32, or it
just
doesn't have the effect hoped for with the manufactured fork() on
Win32.

I shouldn't try to analyze bugs when sleepy. Actually, the lack of
output from Win32 should have pointed me to the fact that _exit() forces
the parent to exit as well as the child on Win32. That's not what we
want. So, I guess I'll be navigating the twisty maze of MSDN for that one.

Google works wonderfully with MSDN. There is a function called
_c_exit() that functions similarly to _exit() on Win32. I'll experiment
with it to see if using that instead of _exit() on Win32 forks will
work.

Steve Peters
steve@​fisharerojo.org

@p5pRT
Copy link
Author

p5pRT commented Feb 10, 2006

From nick@ing-simmons.net

Steve Peters via RT <perlbug-followup@​perl.org> writes​:

Unfortunately, it appears that _exit() doesn't work on Win32, or it
just
doesn't have the effect hoped for with the manufactured fork() on
Win32.

I shouldn't try to analyze bugs when sleepy. Actually, the lack of
output from Win32 should have pointed me to the fact that _exit() forces
the parent to exit as well as the child on Win32. That's not what we
want. So, I guess I'll be navigating the twisty maze of MSDN for that one.

i.e. _exit() works too well and exits the process taking all the
pseudo-forked threads with it. All the more reason to make our own.

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