in reply to syscall() closes file descriptor

The problem is that syscall.ph doesn't understand what you are trying to do with $f. Perl is passing a GLOB to syscall but it is not getting converted to an address. That is why your output prints "GLOB(0x814".

Note that h2ph ( and thus, syscall.ph )does not claim to handle all structures correctly.

From man h2ph:
" It (h2ph) doesn't handle all C constructs, but it does attempt to isolate definitions inside evals so that you can get at the definitions that it can translate. It's only intended as a rough tool. You may need to dicker with the files produced."

If your read your data into a buffer and pass the buffer then SYS_write works correctly.

#!/usr/bin/perl use strict; use warnings; require 'sys/syscall.ph'; my $file = 'foobar'; my $buffer; open my $f, '<', \$file or die "open: $!"; defined read($f, $buffer, 10) or die "read: $!"; syscall(&SYS_write, fileno(STDERR), $buffer, 10) != -1 or warn "write: + $!"; print STDERR "\n"; defined read($f, $buffer, 1) or die "read: $!";

Update: Removed extraneous DATA block.

s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}

Replies are listed 'Best First'.
Re^2: syscall() closes file descriptor
by starbolin (Hermit) on Aug 22, 2006 at 21:47 UTC

    Actually, I think I was being too easy on your code and too harsh towards syscall. I can't think of anytime that SYS_write( id, filehandle, len) would work. Write() can not be expected to fill a buffer. Which is what you are asking it to do when you call it with a filehandle as the buffer. If you want to call write() then give it buffer. If you want something in that buffer then call read().

    Sorry this post sounds harsh. It's not meant that way.:)


    s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}

      I am not complaining about the output "GLOB(0x814". This is what one should expect when treating a file handle reference as a string. I don't expect perl to read from the file handle.

      I'm only wondering why the file handle gets closed. Nobody told perl to do that.

        But, if your passing parameters to syscall and syscall doesn't know what to do with them then the behavior is undefined. Undefined means anything could happen, data corruption, crash and etc. The problem is that Perl has to make assumptions about what you are going to do inside the syscall without actually parsing the syscall.

        From perldoc -f syscall:

        "You can't use a string literal(or other read-only string) as an argument to "syscall" because Perl has to assume that any string pointer might be written through."

        We can't expect the same kind of DWIM inside the syscall as we ususally expect elsewhere from Perl. Instead Perl 'expects' our parameter to match syscall.ph. Any thing else is going to give undefined behaviors.

        I don't know if Perl is trying to prep the string for writing as above or if the closing is accidental.


        s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}

        Note: It doesn't matter which routine you call only that the filehandle as a scalar in the argument list. So it seems to be an artifact of Perl trying to munge the argument list into a C structure.

        #!/usr/bin/perl use strict; use warnings; require 'sys/syscall.ph'; my $buffer = " "; open my $f, '</dev/null' or die "open: $!"; # This works syscall(&SYS_read, fileno($f), $buffer, 1) != -1 or warn "write: $!"; defined read($f, $buffer, 1) or die "First pass, read: $!"; # This closes $f syscall(&SYS_read, fileno($f), $buffer, 1, $f) != -1 or warn "write: $ +!"; defined read($f, $buffer, 1) or die "Second pass, read: $!";

        Since there would be no C function that took a Perl filehandle as an argument, the appearance of a Perl filehandle in a syscall argument list I take to be an error.


        s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}