in reply to Re^4: Error: Not enough space
in thread Error: Not enough space

Ok in that case, which ones are considered to be system calls? is it only the system(..) calls or it is any call to underlying c routines also? Like can a call to print FH "foo"; cause ENOMEM? or can an array allocation cause an ENOMEM? so which all statements in the code should be checked for $! ? Here's an example:
@arr = ('x', 'y', 'z'); # error occurs so $! is set. But thinking that this small piece of cod +e wont cause any error I dont check for $! here. #some more code her print join(',', @arr); open(FILE, "<file.txt") || die (".....error"); # check for $! here if ($!) { # whcih is the culprit line causing this error? is it array allocation +, or is it print or is it open? }

Replies are listed 'Best First'.
Re^6: Error: Not enough space
by Joost (Canon) on Jan 05, 2005 at 12:06 UTC
    Ok in that case, which ones are considered to be system calls?

    Good question, I thought there was a full list in the perldocs, but I can't find it - most of it is documented in perlfunc, but print() also sets $! on error (and returns false), which isn't documented there, so there might be omissions.

    In general, errors from child processes in system() and `` are set in $? (though they set $! if the exec() fails), eval() errors are set in $@ and system errors that are not handled otherwise in the interpreter (not promoted to exceptions or worked around) set their errors in $! - these include file and pipe errors from print(), open(), read(), close() etc. All these functions return some value to indicate success/failure, and you should only read $! on failure.

    If you want to be sure, "Programming Perl 3rd edition" (the Camel book) has a list of all built-in functions and and also notes which ones set $!.

    Also, you might want to take a look at the standard (since perl 5.6) Fatal module. With it you can force an exception on functions that return false on error if you don't explicitly test for them (sadly, it doesn't work with system() and other functions that return true on error):

    from the docs:

    use Fatal qw/:void open close/; # properly checked, so no exception raised on error if(open(FH, "< /bogotic") { warn "bogo file, dude: $!"; } # not checked, so error raises an exception close FH;

    update: just to answer your other question: running out of memory in the interpreter will throw an exception which is untrappable by default (so your code should die on the line causing the exception). In theory, it's possible to catch this exception, but your code probably isn't trying to. See the $^M entry in perlvar.

Re^6: Error: Not enough space
by Anonymous Monk on Jan 05, 2005 at 11:51 UTC
    No, system calls are NOT calls to system. Calls to system don't set $!, they set $?. System calls are function calls that interact with the system, and typically have an obvious 1-1 mapping to your systems library calls that set errno. That's C/Unix speak, but to fully understand Perl, you must understand C and Unix, as large parts of Perl are designed to work with Unix.

    Functions that set $! will always return a false value on failure, and a true value on success. Never, ever use $! to determine whether something succeeded or not - the specification of your system libraries allows a function to set errno to whatever it wants in case of success (all that $! does is give you the value of errno - whose value usually isn't under Perls control). Always use the return value of the function used to determine success, and only use $! immediately after determining failure. Typically this is done by interpolating $! in the message you give with die. In your example, both print and open can set $!. But if your code reaches the test for if ($!), the open has succeeded (because you'll die if it fails). Which means that at that moment, the value of $! is utterly meaningless. No information can be derived from it.

    The manual page will tell you whether a function sets $!. Functions that set $! include (but aren't limited to): open, close, print, umask, chmod, unlink, rename, mkdir, rmdir, sysopen, sysread, syswrite, and fork.