NAME
Sidef::Sys::Sys - System-level operations and utilities
DESCRIPTION
The Sys class provides an interface to various system-level operations, including process control, timing, I/O, object introspection, weak references, and the traditional Unix user/group/host/network/protocol/service databases. This class wraps many Perl built-in functions and provides a Sidef-friendly interface to system programming capabilities.
Sys is normally used through the pre-existing global Sys instance rather than by constructing your own (see "new").
SYNOPSIS
# Process control
var pid = Sys.fork
Sys.sleep(2)
Sys.exit(0)
# I/O operations
Sys.say("Hello, World!")
var input = Sys.readln("Enter your name: ")
Sys.printf("Welcome, %s!\n", input)
# System information
say Sys.os # Operating system name
say Sys.user # Current username
# File operations
Sys.open(\var fh, '<', 'file.txt')
Sys.opendir(\var dh, '/tmp')
# User/group information
var user_info = Sys.getpwnam('root')
var group_info = Sys.getgrnam('wheel')
INHERITS
Inherits methods from Sidef::Object::Object.
CONSTRUCTION
new
Sys.new
Creates a new, empty Sys object. Any arguments given are ignored — this constructor takes none. There is normally no need to call this yourself; Sidef provides a ready-made Sys instance for the whole program.
PROCESS CONTROL
fork
self.fork
Creates a child process. Returns the child's process ID (PID) to the parent process, 0 to the child process, or nil on failure.
var pid = Sys.fork
if (pid == 0) {
say "I am the child"
Sys.exit(0)
}
else {
say "I am the parent, child PID: #{pid}"
Sys.wait
}
wait
self.wait
Waits for any child process to terminate and returns its process ID, or -1 if there are no child processes to wait for.
var pid = Sys.fork
if (pid == 0) {
Sys.exit(0)
}
else {
var terminated_pid = Sys.wait
say "Child #{terminated_pid} terminated"
}
exit
self.exit(code)
Terminates the program immediately with the specified exit code. An exit code of 0 typically indicates success, while non-zero values indicate various error conditions. If omitted, code defaults to 0.
Sys.exit(0) # Success
Sys.exit(1) # Error
kill
self.kill(signal, *list)
Sends signal to each process ID in list. signal can be a signal name (e.g. 'TERM', 'KILL', 'HUP') or number. Returns the number of processes successfully signaled.
Sys.kill('TERM', 1234) # Terminate process 1234
Sys.kill(9, 1234, 5678) # Kill multiple processes
Sys.kill('HUP', Sys.getppid) # Send HUP to parent
system
self.system(*args)
Executes an external command and waits for it to complete, exactly like Perl's built-in system. Output goes directly to STDOUT/STDERR. Returns the raw child status value: 0 means the command exited successfully; any other value packs the exit code and signal information together (the actual exit code is the returned value shifted right by 8 bits).
Sys.system("ls", "-la")
var status = Sys.system("false")
if (status == 0) {
say "Command succeeded"
}
else {
say "Command failed with exit code #{status >> 8}"
}
Aliases: run
exec
self.exec(*args)
Replaces the current process image with the specified external command. This function does not return on success — the calling program is gone. Arguments can be a single command string or a command followed by its individual arguments.
Sys.exec("ls", "-la", "/tmp")
Sys.exec("echo 'Hello World'")
getppid
self.getppid
Returns the process ID (PID) of the parent process.
say "My parent PID is: #{Sys.getppid}"
getpgrp
self.getpgrp(pid)
Returns the process group ID for the specified process ID. If pid is omitted, returns the process group of the current process.
var pgrp = Sys.getpgrp() # Current process group
var pgrp2 = Sys.getpgrp(1234)
setpgrp
self.setpgrp(pid, pgrp)
Sets the process group for the specified process ID. Both parameters default to 0 if omitted, which sets the current process as its own process group leader.
Sys.setpgrp(0, 0) # Set current process as process group leader
getpriority
self.getpriority(which, who)
Returns the current priority (nice value) of a process, process group, or user. which specifies the target kind (0 = process, 1 = process group, 2 = user), and who specifies its ID.
var priority = Sys.getpriority(0, 0) # Current process priority
setpriority
self.setpriority(which, who, priority)
Sets the priority (nice value) of a process, process group, or user. which specifies the target kind (0 = process, 1 = process group, 2 = user), who specifies its ID, and priority is the new value (lower numbers mean higher scheduling priority).
Sys.setpriority(0, 0, 10) # Lower priority of current process
TIMING
alarm
self.alarm(sec)
Schedules a SIGALRM signal to be delivered to the process after sec seconds (fractional seconds are supported). Setting sec to 0 cancels any pending alarm. Returns a boolean: true if a previous alarm still had time remaining when this call replaced it, false otherwise (including when there was no previous alarm).
Sys.alarm(10) # Set alarm for 10 seconds
Sys.alarm(0) # Cancel alarm
ualarm
self.ualarm(usec)
Like "alarm", but usec is given in microseconds, allowing finer granularity. Returns a boolean: true if a previous alarm still had time remaining, false otherwise.
Sys.ualarm(500000) # Alarm in 500,000 microseconds (0.5 seconds)
Aliases: micro_alarm
sleep
self.sleep(sec)
Suspends execution for sec seconds (fractional seconds are supported). Returns a boolean indicating whether any (nonzero) amount of time was actually slept.
Sys.sleep(5) # Sleep for 5 seconds
Sys.sleep(0.5) # Sleep for half a second
nanosleep
self.nanosleep(nsec)
Suspends execution for nsec nanoseconds — despite the similarly-named "sleep", this method's argument is a nanosecond count, not a (possibly fractional) second count. Returns a boolean indicating whether any (nonzero) amount of time was actually slept.
Sys.nanosleep(500_000_000) # Sleep for 500,000,000 ns = 0.5 seconds
Sys.nanosleep(1_000_000) # Sleep for 1,000,000 ns = 1 millisecond
Aliases: nano_sleep
usleep
self.usleep(usec)
Suspends execution for usec microseconds. Returns a boolean indicating whether any (nonzero) amount of time was actually slept.
Sys.usleep(500000) # Sleep for 500,000 microseconds (0.5 seconds)
Sys.usleep(1000000) # Sleep for 1,000,000 microseconds (1 second)
Aliases: micro_sleep
INPUT/OUTPUT
self.print(*args)
Prints the arguments to the currently selected output filehandle (default STDOUT), without appending a newline. Returns a boolean indicating success.
Sys.print("Hello")
Sys.print("Value: ", value, " at ", timestamp)
printf
self.printf(format, *args)
Formats and prints output according to a sprintf-style format string to the currently selected output filehandle. Returns a boolean indicating success.
Sys.printf("Value: %d, Name: %s\n", 42, "Alice")
Sys.printf("%.2f%%\n", percentage)
printh
self.printh(fh, *args)
Prints the arguments to the specified filehandle without appending a newline. fh may be a raw filehandle (as returned by, e.g., "select") or a Sidef filehandle-like object supporting its own print method — in the latter case, this simply delegates to fh.print(*args). Returns a boolean indicating success.
Sys.open(\var fh, '>', 'output.txt')
Sys.printh(fh, "Line 1")
Sys.printh(fh, "Line 2")
fh.close
println
self.println(*args)
Prints the arguments to the currently selected output filehandle (default STDOUT) and appends a newline. Returns a boolean indicating success.
Sys.println("Hello, World!")
Sys.println("Value: ", value)
Sys.println() # Print empty line
Aliases: say
scanln
self.scanln(prompt)
Displays prompt (if given) and reads a single line of input from the terminal, returning it as a String with the trailing newline removed. Returns nil on end of input.
var name = Sys.scanln("Enter your name: ")
var age = Sys.scanln("Enter your age: ")
Aliases: readln, readline
read
self.read(type)
self.read(prompt, type)
Displays prompt (if given), reads a single line of input from the terminal, and constructs a new object of type from it (i.e. type.new(input)). type must be a class that accepts a raw string in its constructor, such as String or Number. Returns nil on end of input.
var name = Sys.read(String)
var count = Sys.read("How many? ", Number)
"scanln" is a thin wrapper around this that always uses String as the type.
select
self.select(fh)
Sets the specified filehandle as the default output filehandle for "print", "printf", "println", etc. Returns the previously selected filehandle, as a Sidef FileHandle object.
Sys.open(\var fh, '>', 'output.txt')
var old = Sys.select(fh)
say "This goes to the file"
Sys.select(old)
say "This goes to STDOUT"
stdin
self.stdin
Returns the standard input filehandle (STDIN).
var line = Sys.stdin.readline
stdout
self.stdout
Returns the standard output filehandle (STDOUT).
Sys.stdout.say("Hello")
stderr
self.stderr
Returns the standard error filehandle (STDERR).
Sys.stderr.say("Error message")
FILE AND DIRECTORY OPERATIONS
open
self.open(var, mode, filename)
Opens filename (converted via its to_file method) and assigns the resulting filehandle to var. mode follows the usual conventions ('<' for read, ''> for write, '>'> for append, etc.). The actual return value and supported modes are governed by the file object's own open method.
Sys.open(\var fh, '<', 'input.txt') && do {
say fh.readline
fh.close
}
opendir
self.opendir(var, dirname)
Opens the directory at dirname (converted via its to_dir method) and assigns the resulting directory handle to var.
Sys.opendir(\var dh, '/tmp') && do {
while (var entry = dh.read) {
say entry
}
dh.close
}
SYSTEM INFORMATION
osname
self.osname
Returns the operating system name as a string (e.g., 'linux', 'darwin', 'MSWin32', 'freebsd'), taken directly from Perl's $^O.
say Sys.osname
if (Sys.osname == 'linux') {
say "Running on Linux"
}
Aliases: os
user
self.user
Returns the login name of the current user as a string.
say "Current user: #{Sys.user}"
Aliases: getlogin
sidef
self.sidef
Returns the absolute filesystem path of the currently running script.
say "Running: #{Sys.sidef}"
umask
self.umask(mode)
Sets the file creation mask (umask) to mode and returns the previous mask. If mode is omitted, simply returns the current mask without changing it.
var old = Sys.umask(0o022) # Set umask to 022 (octal)
# Create files...
Sys.umask(old) # Restore old umask
OBJECT INTROSPECTION
ref
self.ref(obj)
Returns a string describing what kind of reference obj is: the blessed class name for an object, a bare type such as 'ARRAY', 'HASH', or 'CODE' for an unblessed reference, or an empty string if obj is not a reference at all. This mirrors Perl's built-in ref function.
say Sys.ref([1, 2, 3]) # "Sidef::Types::Array::Array"
say Sys.ref(Hash()) # "Sidef::Types::Hash::Hash"
say Sys.ref(42) # "Sidef::Types::Number::Number"
See also "reftype" (which ignores blessing) and "class_name" (which strips the package prefix).
reftype
self.reftype(obj)
Returns the underlying storage type of a reference as a string (e.g., 'ARRAY', 'HASH', 'SCALAR', 'CODE'), ignoring any blessing — unlike "ref", this always reports the raw storage kind even for blessed objects.
say Sys.reftype([1,2,3]) # "ARRAY"
say Sys.reftype(Hash()) # "HASH"
class_name
self.class_name(obj)
Returns the short class name of the given object — the part of its full package name after the last ::.
say Sys.class_name(42) # "Number"
say Sys.class_name("hello") # "String"
say Sys.class_name([1,2,3]) # "Array"
defined
self.defined(obj)
Returns true if obj is defined (not nil), false otherwise.
say Sys.defined(nil) # false
say Sys.defined(0) # true
say Sys.defined("") # true
refaddr
self.refaddr(obj)
Returns the memory address of the reference as a number. Useful for debugging and checking object identity.
var obj = [1, 2, 3]
say Sys.refaddr(obj) # e.g., 140234567890123
bless
self.bless(obj, class)
Blesses obj into class, changing its type, and returns the blessed object.
var obj = Hash()
Sys.bless(obj, :MyClass)
WEAK REFERENCES
weaken
self.weaken(obj)
Converts a reference to a weak reference in place. Weak references do not prevent the referenced object from being garbage collected. Returns a boolean indicating success.
var obj = [1, 2, 3]
var ref = \obj
Sys.weaken(ref)
# obj can now be garbage collected even though ref exists
isweak
self.isweak(obj)
Returns true if the reference is weak (won't prevent garbage collection), false otherwise.
var ref = \obj
say Sys.isweak(ref) # false
Sys.weaken(ref)
say Sys.isweak(ref) # true
unweaken
self.unweaken(obj)
Converts a weak reference back into a strong reference in place. Returns a boolean indicating success.
Sys.weaken(ref)
Sys.unweaken(ref) # Now strong again
ERROR HANDLING AND OUTPUT
die
self.die(*args)
Raises a fatal exception, concatenating the arguments to form the error message, and terminates the program unless caught. A trailing newline is added automatically, so Perl's usual "at FILE line N" suffix is suppressed.
Sys.die("Fatal error occurred!")
Sys.die("Error: ", error_msg, " at line ", line_num)
Aliases: raise
warn
self.warn(*args)
Prints a warning message to STDERR, concatenating the arguments to form the message. A trailing newline is added automatically. Unlike "die", this does not terminate the program.
Sys.warn("Warning: low disk space")
Sys.warn("Deprecated function used at line ", line_num)
USER AND GROUP DATABASES
These methods query the traditional Unix user and group databases (as one would with getpwnam(3)/getgrnam(3) and friends). A successful lookup returns an Array of positional fields (not a hash) — see each method below for its exact field order.
getpwnam
self.getpwnam(name)
Looks up a user by login name. On success, returns an array with fields, in order: [name, passwd, uid, gid, quota, comment, gcos], followed by the shell, i.e. [name, passwd, uid, gid, quota, comment, gcos, shell]. Note that the home directory is not included in the returned array. Returns nil if the user isn't found.
var user = Sys.getpwnam('root')
say user[0] # name
say user[2] # uid
getpwuid
self.getpwuid(uid)
Looks up a user by numeric user ID. Returns the same array shape as "getpwnam", or nil if not found.
var user = Sys.getpwuid(1000)
say user[0] # name
getpwent
self.getpwent
Returns the next entry from the user database as the same array shape as "getpwnam", or nil when there are no more entries. Use "setpwent" to rewind and iterate again.
Sys.setpwent
while (var user = Sys.getpwent) {
say user[0]
}
setpwent
self.setpwent
Resets the user database iterator to the beginning, so "getpwent" starts over from the first entry. Returns a boolean.
getgrnam
self.getgrnam(name)
Looks up a group by name. Note: due to how this lookup is currently implemented, a successful lookup returns just the group's name as a plain string (the passwd/gid/members fields are not accessible this way), while an unsuccessful lookup returns an array of mostly-undefined values rather than nil — the reverse of the not-found convention used elsewhere in this class.
var name = Sys.getgrnam('wheel')
say name # "wheel"
getgrgid
self.getgrgid(gid)
Looks up a group by numeric group ID. See the caveat under "getgrnam" — this currently behaves the same way.
var name = Sys.getgrgid(0)
getgrent
self.getgrent
Returns the next entry from the group database. See the caveat under "getgrnam" — this currently behaves the same way. Use "setgrent" to rewind and iterate again.
Sys.setgrent
while (var group = Sys.getgrent) {
say group
}
setgrent
self.setgrent
Resets the group database iterator to the beginning, so "getgrent" starts over from the first entry. Returns a boolean.
NETWORK DATABASES
These methods query the traditional Unix host, network, protocol, and service databases. Like the user/group lookups above, a successful result is returned as an Array of positional fields, and nil is returned when nothing is found.
gethostbyname
self.gethostbyname(name)
Looks up a host by name. Returns an array [name, aliases, addrtype, length, addrs], where aliases is a single (possibly space-separated) string of alternate names, and addrs is an array of address strings.
var host = Sys.gethostbyname('localhost')
say host[0] # name
say host[4] # array of addresses
gethostbyaddr
self.gethostbyaddr(addr, addrtype)
Looks up a host by network address. addrtype specifies the address family (typically 2 for AF_INET). Returns the same array shape as "gethostbyname".
var host = Sys.gethostbyaddr("127.0.0.1", 2)
gethostent
self.gethostent
Returns the next entry from the hosts database, in the same array shape as "gethostbyname", or nil when there are no more entries. Use "sethostent" to rewind.
sethostent
self.sethostent(stayopen)
Opens and rewinds the hosts database. If stayopen is true, the database connection is kept open for efficiency. Returns a boolean.
getnetbyname
self.getnetbyname(name)
Looks up a network by name. Returns an array [name, aliases, addrtype, net].
var net = Sys.getnetbyname('loopback')
getnetbyaddr
self.getnetbyaddr(addr, addrtype)
Looks up a network by address and address type. Returns the same array shape as "getnetbyname".
getnetent
self.getnetent
Returns the next entry from the networks database, in the same array shape as "getnetbyname", or nil when there are no more entries. Use "setnetent" to rewind.
setnetent
self.setnetent(stayopen)
Opens and rewinds the networks database. If stayopen is true, the database connection is kept open for efficiency. Returns a boolean.
getprotobyname
self.getprotobyname(name)
Looks up a protocol by name (e.g., 'tcp', 'udp', 'icmp'). Returns an array [name, aliases, proto].
var proto = Sys.getprotobyname('tcp')
say proto[2] # protocol number, as a string
getprotobynumber
self.getprotobynumber(num)
Looks up a protocol by its number. Returns the same array shape as "getprotobyname".
var proto = Sys.getprotobynumber(6) # TCP
getprotoent
self.getprotoent
Returns the next entry from the protocols database, in the same array shape as "getprotobyname", or nil when there are no more entries. Use "setprotoent" to rewind.
setprotoent
self.setprotoent(stayopen)
Opens and rewinds the protocols database. If stayopen is true, the database connection is kept open for efficiency. Returns a boolean.
getservbyname
self.getservbyname(name, proto)
Looks up a service by name and protocol. Returns an array [name, aliases, port, proto], where port is a number.
var service = Sys.getservbyname('http', 'tcp')
say service[2] # 80
getservbyport
self.getservbyport(port, proto)
Looks up a service by port number and protocol. Returns the same array shape as "getservbyname".
var service = Sys.getservbyport(80, 'tcp')
say service[0] # "http"
getservent
self.getservent
Returns the next entry from the services database, in the same array shape as "getservbyname", or nil when there are no more entries. Use "setservent" to rewind.
setservent
self.setservent(stayopen)
Opens and rewinds the services database. If stayopen is true, the database connection is kept open for efficiency. Returns a boolean.
EXAMPLES
Forking a Child Process
var pid = Sys.fork
if ((pid == 0)) {
say "Child process running"
Sys.exit(0)
}
else {
Sys.wait
say "Child has finished"
}
Reading Typed Input
var name = Sys.scanln("Name: ")
var count = Sys.read("How many apples? ", Number)
Sys.printf("%s has %d apples\n", name, count)
Redirecting Output Temporarily
Sys.open(var fh, '>', 'log.txt')
var old = Sys.select(fh)
say "This line goes to log.txt"
Sys.select(old)
say "This line goes back to the terminal"
fh.close
Running a Command and Checking the Result
var status = Sys.system("grep", "-q", "root", "/etc/passwd")
if ((status == 0)) {
say "Found it"
}
else {
say "grep exited with code #{status >> 8}"
}
Looking Up a User
var pw = Sys.getpwnam('root')
if (pw) {
say "UID: #{pw[2]}"
say "Shell: #{pw[7]}"
}