Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Portable way of finding libc, unbuffered reads

13 views
Skip to first unread message

Clinton A. Pierce

unread,
Jun 16, 2003, 4:42:02 PM6/16/03
to perl6-i...@perl.org
The following code works just fine:

loadlib P1, "/lib/libc.so.6"
dlfunc P0, P1, "system", "it"
set I0, 1
set S5, "ls"
invoke
end

(Which in itself tickles and scares the bejesus out of me.) Is there a
good way of finding the standard C library on a Unix system other than
hard-wiring it in like this?

Also, is there any way yet of getting an unbuffered read (in parrot) so I
can getc() from the keyboard? I should ask, is there an *approved* way of
doing that now? I'm fairly familiar with C's I/O model so I could pull it
off with ioctl(), fcntl(), etc... and all of their friends, but alas
they're not around yet.

These questions are not necessarily related. Or unrelated. :)


Andy Dougherty

unread,
Jun 20, 2003, 3:43:01 PM6/20/03
to Clinton A. Pierce, perl6-i...@perl.org
On Mon, 16 Jun 2003, Clinton A. Pierce wrote:

> loadlib P1, "/lib/libc.so.6"
> dlfunc P0, P1, "system", "it"
> set I0, 1
> set S5, "ls"
> invoke
> end
>
> (Which in itself tickles and scares the bejesus out of me.) Is there a
> good way of finding the standard C library on a Unix system other than
> hard-wiring it in like this?

Not that I know of. You can get perl5's guess by looking at
$Config{libc}, but that value could be empty or wrong. If you want to be
either amused or amazed, you can look at the complex gyrations perl5's
Configure tries to go through to find the C library, but even that isn't
always right. Further, perl5's Configure only looks for the libc name if
it is necessary. Often, it is sufficient (for Configure's purpose) to let
the compiler find the C library. As one example, it's conceivable that
the compiler might use the C library in either /lib32/ for /lib64/,
depending on compiler flags and environment variables.

--
Andy Dougherty doug...@lafayette.edu

Jens Rieks

unread,
Jun 20, 2003, 5:55:16 PM6/20/03
to perl6-i...@perl.org, Clinton A. Pierce
> (Which in itself tickles and scares the bejesus out of me.) Is there a
> good way of finding the standard C library on a Unix system other than
> hard-wiring it in like this?
Yes. Parrot is linked with the standard C library. You can get a handle for
the own executable by passing a NULL pointer to dlopen. You can also use this
handle to call libc functions.
You can not pass a NULL pointer to loadlib at the moment, this small hacks
"converts" an empty string to a NULL pointer to pass it to Parror_dlopen:

const char * s = 0;

if( $2->strlen != 0 ) {
s = string_to_cstring(interpreter, ($2));
}
p = Parrot_dlopen(s);

With this hack, the following code will work:

loadlib P1, ""


dlfunc P0, P1, "system", "it"
set I0, 1
set S5, "ls"
invoke
end

cya,
Jens Rieks

Jens Rieks

unread,
Jun 20, 2003, 6:00:32 PM6/20/03
to Clinton A. Pierce, perl6-i...@perl.org
> You can not pass a NULL pointer to loadlib at the moment, this small hacks
> "converts" an empty string to a NULL pointer to pass it to Parror_dlopen:
It's for core.ops, of course. Here is the cvs diff output:

Index: core.ops
===================================================================
RCS file: /cvs/public/parrot/core.ops,v
retrieving revision 1.287
diff -r1.287 core.ops
4862c4862,4866
< const char * s = string_to_cstring(interpreter, ($2));
---


> const char * s = 0;
>
> if( $2->strlen != 0 ) {
> s = string_to_cstring(interpreter, ($2));
> }

cya,
Jens Rieks

Clinton A. Pierce

unread,
Jun 20, 2003, 6:58:11 PM6/20/03
to Jens Rieks, perl6-i...@perl.org

A very cool hack, indeed. :)

It's gonna need a little work though. On Win32 Parrot_dlopen is a
passthrough to LoadLibrary() which, as far as I can tell, doesn't have the
same behavior for this case. *But* it seems as though if you can find
parrot's name (imcc.exe, parrot.exe, etc...) and pass *that* to loadlib it
should work fine. Maybe. More testing required.

On my linux box (which was the issue...) it seems fine though. Whee.

Thanks!


Jens Rieks

unread,
Jun 20, 2003, 10:19:11 PM6/20/03
to perl6-i...@perl.org, Clinton A. Pierce
Clinton A. Pierce wrote:
> A very cool hack, indeed. :)
>
> It's gonna need a little work though. On Win32 Parrot_dlopen is a
> passthrough to LoadLibrary() which, as far as I can tell, doesn't have the
> same behavior for this case. *But* it seems as though if you can find
> parrot's name (imcc.exe, parrot.exe, etc...) and pass *that* to loadlib it
> should work fine. Maybe. More testing required.
No, just use GetModuleHandle(0) instead of LoadLibraray if NULL is passed.

> Thanks!
No problem, thank you for your work!

cya,
Jens Rieks

Leopold Toetsch

unread,
Jun 21, 2003, 8:02:46 AM6/21/03
to Jens Rieks, perl6-i...@perl.org, Clinton A. Pierce
Jens Rieks wrote:

> You can not pass a NULL pointer to loadlib at the moment, this small hacks
> "converts" an empty string to a NULL pointer to pass it to Parror_dlopen:


We could as well change string_to_cstring to return a NULL pointer for a
NULL String argument.

And for obtaining a NULL String you could use e.g. C<clears> or better a
new opcode:

B<null>(out STR) # set register to NULL

For consistency we could have this op for all register type.

null I0 # a little faster shortcut of "set I0, 0"


> Jens Rieks


leo


Dan Sugalski

unread,
Jun 21, 2003, 12:41:12 PM6/21/03
to Leopold Toetsch, Jens Rieks, perl6-i...@perl.org, Clinton A. Pierce
At 2:02 PM +0200 6/21/03, Leopold Toetsch wrote:
>And for obtaining a NULL String you could use e.g. C<clears> or
>better a new opcode:
>
> B<null>(out STR) # set register to NULL
>
>For consistency we could have this op for all register type.
>
> null I0 # a little faster shortcut of "set I0, 0"

Works, and done! :)
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Dan Sugalski

unread,
Jun 21, 2003, 12:55:57 PM6/21/03
to Jens Rieks, perl6-i...@perl.org, Clinton A. Pierce
At 11:55 PM +0200 6/20/03, Jens Rieks wrote:
> > (Which in itself tickles and scares the bejesus out of me.) Is there a
>> good way of finding the standard C library on a Unix system other than
>> hard-wiring it in like this?
>Yes. Parrot is linked with the standard C library. You can get a handle for
>the own executable by passing a NULL pointer to dlopen. You can also use this
>handle to call libc functions.

That's an interesting trick, albeit a very platform-dependent one. I
can see adding in support for getting a handle on the current
executable (though this is one of the cases where things may behave
differently under the interpreter and as a compiled standalope app)

Given all this, I think that an alternate version of loadlib to open
the current application is in order. (I'd say it should be a library
routine, but since loadlib is already an op it seems in order)
Perhaps loadlib with only one argument should give a handle on the
current app, with callouts to a platform-specific loading routine.
(The dlopen trick won't work on OS X right now, as well as Win32,
since we fake out dlopen)

>You can not pass a NULL pointer to loadlib at the moment, this small hacks
>"converts" an empty string to a NULL pointer to pass it to Parror_dlopen:

I've put in an alternate hack, one that returns NULL from
string_to_cstring if passed in a NULL string pointer.

Andy Dougherty

unread,
Jun 23, 2003, 11:48:33 AM6/23/03
to Jens Rieks, perl6-i...@perl.org, Clinton A. Pierce
On Fri, 20 Jun 2003, Jens Rieks wrote:

> > (Which in itself tickles and scares the bejesus out of me.) Is there a
> > good way of finding the standard C library on a Unix system other than
> > hard-wiring it in like this?
> Yes. Parrot is linked with the standard C library. You can get a handle for
> the own executable by passing a NULL pointer to dlopen. You can also use this
> handle to call libc functions.

Ahh, clever. That's likely to work for systems which use the dlopen()
dynamic loading interface. I don't know if it will also work on HP-UX,
AIX, and Mac, though there's likely some equivalent trick. (Similarly,
non-Unix systems such as Win32, VMS, and OS/2 will need some
platform-specific trick, though I realize the original query was limited
to Unix systems.)

--
Andy Dougherty doug...@lafayette.edu

Matt Seddon

unread,
Jun 23, 2003, 1:00:05 PM6/23/03
to doug...@lafayette.edu, perl6-i...@perl.org

>Ahh, clever. That's likely to work for systems which use the dlopen()
>dynamic loading interface. I don't know if it will also work on HP-UX,
>AIX, and Mac, though there's likely some equivalent trick. (Similarly,
>non-Unix systems such as Win32, VMS, and OS/2 will need some
>platform-specific trick, though I realize the original query was limited
>to Unix systems.)
>
>--
> Andy Dougherty doug...@lafayette.edu

As a brief aside, under win32 the dlopen trick could be emulated by
GetProcAddress, LoadLibrary and GetModuleHandle.

Hope this helps.
Matt Seddon.

_________________________________________________________________
Find a cheaper internet access deal - choose one to suit you.
http://www.msn.co.uk/internetaccess

0 new messages