I want to call a Linux syscall (or at least the libc wrapper) directly from a scripting language. I don't care what scripting language - it's just important that it not be compiled (the reason basically has to do with not wanting a compiler in the dependency path, but that's neither here nor there). Are there any scripting languages (shell, Python, Ruby, etc) that allow this?

In particular, it's the getrandom syscall.

share|improve this question
2  
getrandom merely pulls in random bytes from /dev/urandom. You can certainly do that from a shell script. – steve yesterday
    
@steve indeed, unless of course /dev isn't yet available. But then hard to imagine Perl would be! – derobert yesterday
    
Critically, I want this to block until the entropy pool is initialized, which reading from /dev/urandom as a file doesn't do. – joshlf 23 hours ago
5  
Read from /dev/random until it unblocks, then read from /dev/urandom? – bishop 22 hours ago
    
So I wasn't previously aware that /dev/random blocked in this way; somebody just told me. So that works, thanks! – joshlf 21 hours ago
up vote 14 down vote accepted

Perl allows this with its syscall function:

$ perldoc -f syscall
    syscall NUMBER, LIST
            Calls the system call specified as the first element of the list,
            passing the remaining elements as arguments to the system call. If
⋮

The documentation also gives an example of calling write(2):

require 'syscall.ph';        # may need to run h2ph
my $s = "hi there\n";
syscall(SYS_write(), fileno(STDOUT), $s, length $s);

Can't say I've ever used this feature, though. Well, before just now to confirm the example does indeed work.

This appears to work with getrandom:

$ perl -E 'require "syscall.ph"; $v = " "x8; syscall(SYS_getrandom(), $v, length $v, 0); print $v' | xxd
00000000: 5790 8a6d 714f 8dbe                      W..mqO..

And if you don't have getrandom in your syscall.ph, then you could use the number instead. It's 318 on my Debian testing (amd64) box. Beware that Linux syscall numbers are architecture-specific.

share|improve this answer
1  
Perl - the plan B hammer! – Thorbjørn Ravn Andersen 7 hours ago

In Python you can use the ctypes module to access arbitrary functions in dynamic libraries, including syscall() from libc:

import ctypes

SYS_getrandom = 318 # You need to check the syscall number for your target architecture

libc = ctypes.CDLL(None)
_getrandom_syscall = libc.syscall
_getrandom_syscall.restypes = ctypes.c_int
_getrandom_syscall.argtypes = ctypes.c_int, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, ctypes.c_uint

def getrandom(size, flags=0):
    buf = (ctypes.c_char * size)()
    result = _getrandom_syscall(SYS_getrandom, buf, size, flags)
    if result < 0:
        raise OSError(ctypes.get_errno(), 'getrandom() failed')
    return bytes(buf)
share|improve this answer

Ruby has a syscall(num [, args...]) → integer function.

For example:

irb(main):010:0> syscall 1, 1, "hello\n", 6
hello
=> 6

With getrandom():

irb(main):001:0> a = "aaaaaaaa"
=> "aaaaaaaa"
irb(main):002:0> syscall 318,a,8,0
=> 8
irb(main):003:0> a
=> "\x9Cq\xBE\xD6|\x87\u0016\xC6"
irb(main):004:0> 
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.