in reply to Re^2: HPUX corruption of file handle after fork
in thread HPUX corruption of file handle after fork

I just played around with this some more (I somehow had the feeling that you know what you're doing... ;)  and I can now reproduce the problem. Initially, I had rather short content in my dummy SQL_REPORT_ID sections. So, to simulate longer read times, I added a sleep 1 like this

... while (<$fh>) { last if (/END SQL_REPORT_ID/) ; $Sql .= "$_"; } sleep 1; ...

and now I'm getting this (when doing print STDERR "Generated $ReportId: $Sql"; in the child):

Generated 1: foo 1 Generated 2: foo 2 Generated 3: foo 3 Generated 4: foo 4 Generated 2: foo 2 Generated 3: foo 3 Generated 4: foo 4 (2..4 repeated ad infinitum...)

This is on HP-UX (no difference between 11.00, 11.11 and 11.23) — on Linux, however, everything is fine. I'll try other platforms later and report back...

For the record, my test file contains:

SQL_REPORT_ID 1 foo 1 END SQL_REPORT_ID SQL_REPORT_ID 2 foo 2 END SQL_REPORT_ID SQL_REPORT_ID 3 foo 3 END SQL_REPORT_ID SQL_REPORT_ID 4 foo 4 END SQL_REPORT_ID

Update: in case anyone is interested, here are the results for a couple of other platforms I could find:

No problem on

but same problem as on HP-UX, on

(don't know what to make of it, yet...)

Replies are listed 'Best First'.
Re^4: HPUX corruption of file handle after fork
by Abe (Acolyte) on Dec 10, 2007 at 17:45 UTC
    Aha - so it's not the perl version but it's probably perl on HPUX.

    I'm not into this enough to look at perl source code, but I find it hard to imagine it's got something special about the way it calls close() for HPUX.

    H'm. To me it means I have to be careful with explicitly opened files when calling fork(). perl open() is probably safe.

    If you find out more do let me know, but I'm willing to use fork() now, just I know what to expect.

    Thanks - Abe

      There are lots of issues at hand.

      At the Un*x/POSIX level exit() does lots of cleaning. To be on the safe side it is usually better to _exit() in the child. IO buffering can get in the way as exit() will usually flush the streams before closing them.

      perl will usually show its un*x heritage (except in some places and/or platforms in recent years where it was considered better to "fix" that un*x behaviour). Recently while translating C code for a system(3) with time-out I needed low-level IO and POSIX::_exit() to be close to the old behaviour.

      Even at the perl level don't forget that exit() does call END blocks ...

      5.8.0 was very buggy, so it would be better to use another version. cheers hth --stephan

        Thanks sgt - sorry I didn't notice for a bit. I'd solved it and didn't check the thread again. I was a chicken and just stuck to STDIN, though I'd understood what had gone wrong. Regards, Abe