/* clib.q: Q's system module $Id: clib.q,v 1.6 2004/08/31 22:25:31 agraef Exp $ */ /* This file is part of the Q programming system. The Q programming system is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. The Q programming system is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* NOTE: Not all operations are implemented on all systems. The UNIX-specific operations are marked with `(U)'. Only a portable subset of the UNIX system interface is provided, which encompasses the most essential operations found on many recent UNIX (and other POSIX) systems, as described by the ANSI C and POSIX standards, as well as the Single UNIX Specification (SUS). These operations are also available on Linux and OSX systems. Please also note that at this time some of the low-level operations (most notably, ioctl) are not yet implemented. */ import stdlib, string; /****************************************************************************/ /* Manifest constants. These vary from system to system; only the most common values are provided as global variables here. Flag values can be combined using bitwise logical operations as usual. Flag values which are unavailable on the host system will be set to zero, other undefined values to -1. Thus undefined values will generally have no effect or cause the corresponding operations to fail. */ public var const // data sizes (useful with byte strings); if a type is undefined then its // size value is set to zero SIZEOF_CHAR, SIZEOF_SHORT, SIZEOF_INT, SIZEOF_LONG, SIZEOF_LONG_LONG, SIZEOF_FLOAT, SIZEOF_DOUBLE, // _spawn modes P_WAIT, P_NOWAIT, P_OVERLAY, P_DETACH, // file buffering modes (setvbuf) IONBF, IOLBF, IOFBF, // file positioning modes (fseek) SEEK_SET, SEEK_CUR, SEEK_END, // scheduling policies (setsched, getsched) SCHED_OTHER, SCHED_RR, SCHED_FIFO, // file access modes O_RDONLY, O_WRONLY, O_RDWR, // access mode bitmask O_ACCMODE, // file descriptor flags FD_CLOEXEC, // status flags O_CREAT, O_EXCL, O_TRUNC, O_APPEND, O_NONBLOCK, O_NDELAY, O_NOCTTY, O_BINARY, // file type bitmask S_IFMT, // file types S_IFBLK, S_IFCHR, S_IFIFO, S_IFREG, S_IFDIR, S_IFLNK, S_IFSOCK, // permission flags S_ISUID, S_ISGID, S_ISVTX, S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH, // fcntl command codes F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_SETFL, F_GETLK, F_SETLK, F_SETLKW, // lock types F_RDLCK, F_WRLCK, F_UNLCK, // modes for access operation F_OK, R_OK, W_OK, X_OK, // wait options WNOHANG, WUNTRACED, // time units used by the clock and times routines CLOCKS_PER_SEC, CLK_TCK, // trap action values SIG_IGN, SIG_DFL, SIG_TRP, // signal numbers SIGABRT, SIGALRM, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGKILL, SIGPIPE, SIGQUIT, SIGSEGV, SIGTERM, SIGUSR1, SIGUSR2, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ, /* termios constants ******************************************************/ // tcsetattr options TCSANOW, TCSADRAIN, TCSAFLUSH, // tcflush options TCIFLUSH, TCIOFLUSH, TCOFLUSH, // tcflow options TCIOFF, TCION, TCOOFF, TCOON, // input modes BRKINT, ICRNL, IGNBRK, IGNCR, IGNPAR, INLCR, INPCK, ISTRIP, IUCLC, IXANY, IXOFF, IXON, PARMRK, // output modes OPOST, OLCUC, ONLCR, OCRNL, ONOCR, ONLRET, OFILL, NLDLY, NL0, NL1, CRDLY, CR0, CR1, CR2, CR3, TABDLY, TAB0, TAB1, TAB2, TAB3, BSDLY, BS0, BS1, VTDLY, VT0, VT1, FFDLY, FF0, FF1, // control modes CSIZE, CS5, CS6, CS7, CS8, CSTOPB, CREAD, PARENB, PARODD, HUPCL, CLOCAL, // local modes ECHO, ECHOE, ECHOK, ECHONL, ICANON, IEXTEN, ISIG, NOFLSH, TOSTOP, XCASE, // baud rates B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, // symbolic control character indices VEOF, VEOL, VERASE, VINTR, VKILL, VMIN, VQUIT, VSTART, VSTOP, VSUSP, VTIME, /* socket-related constants ***********************************************/ // address families AF_LOCAL, AF_UNIX, AF_FILE, AF_INET, AF_INET6, // socket types SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, // shutdown options (HOW argument) SHUT_RD, SHUT_WR, SHUT_RDWR, // send/recv flag values MSG_EOR, MSG_OOB, MSG_PEEK, MSG_WAITALL, // socket option level (getsockopt/setsockopt) SOL_SOCKET, // socket level options SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG, SO_DONTROUTE, SO_ERROR, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_RCVBUF, SO_RCVLOWAT, SO_RCVTIMEO, SO_REUSEADDR, SO_SNDBUF, SO_SNDLOWAT, SO_SNDTIMEO, SO_TYPE, // important IP protocol numbers IPPROTO_IP, IPPROTO_ICMP, IPPROTO_TCP, IPPROTO_UDP; // retrieve system parameters private extern sys_vars; def (SIZEOF_CHAR, SIZEOF_SHORT, SIZEOF_INT, SIZEOF_LONG, SIZEOF_LONG_LONG, SIZEOF_FLOAT, SIZEOF_DOUBLE, P_WAIT, P_NOWAIT, P_OVERLAY, P_DETACH, IONBF, IOLBF, IOFBF, SEEK_SET, SEEK_CUR, SEEK_END, O_RDONLY, O_WRONLY, O_RDWR, O_ACCMODE, FD_CLOEXEC, O_CREAT, O_EXCL, O_TRUNC, O_APPEND, O_NONBLOCK, O_NDELAY, O_NOCTTY, O_BINARY, S_IFMT, S_IFBLK, S_IFCHR, S_IFIFO, S_IFREG, S_IFDIR, S_IFLNK, S_IFSOCK, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_SETFL, F_GETLK, F_SETLK, F_SETLKW, F_RDLCK, F_WRLCK, F_UNLCK, F_OK, R_OK, W_OK, X_OK, WNOHANG, WUNTRACED, CLOCKS_PER_SEC, CLK_TCK, SIGABRT, SIGALRM, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGKILL, SIGPIPE, SIGQUIT, SIGSEGV, SIGTERM, SIGUSR1, SIGUSR2, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ, TCSANOW, TCSADRAIN, TCSAFLUSH, TCIFLUSH, TCIOFLUSH, TCOFLUSH, TCIOFF, TCION, TCOOFF, TCOON, BRKINT, ICRNL, IGNBRK, IGNCR, IGNPAR, INLCR, INPCK, ISTRIP, IUCLC, IXANY, IXOFF, IXON, PARMRK, OPOST, OLCUC, ONLCR, OCRNL, ONOCR, ONLRET, OFILL, NLDLY, NL0, NL1, CRDLY, CR0, CR1, CR2, CR3, TABDLY, TAB0, TAB1, TAB2, TAB3, BSDLY, BS0, BS1, VTDLY, VT0, VT1, FFDLY, FF0, FF1, CSIZE, CS5, CS6, CS7, CS8, CSTOPB, CREAD, PARENB, PARODD, HUPCL, CLOCAL, ECHO, ECHOE, ECHOK, ECHONL, ICANON, IEXTEN, ISIG, NOFLSH, TOSTOP, XCASE, B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, VEOF, VEOL, VERASE, VINTR, VKILL, VMIN, VQUIT, VSTART, VSTOP, VSUSP, VTIME, AF_LOCAL, AF_INET, AF_INET6, SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SHUT_RD, SHUT_WR, SHUT_RDWR, MSG_EOR, MSG_OOB, MSG_PEEK, MSG_WAITALL, SOL_SOCKET, SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG, SO_DONTROUTE, SO_ERROR, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_RCVBUF, SO_RCVLOWAT, SO_RCVTIMEO, SO_REUSEADDR, SO_SNDBUF, SO_SNDLOWAT, SO_SNDTIMEO, SO_TYPE, IPPROTO_IP, IPPROTO_ICMP, IPPROTO_TCP, IPPROTO_UDP ) = sys_vars; def SIG_IGN = -1, SIG_DFL = 0, SIG_TRP = 1, SCHED_OTHER = 0, SCHED_RR = 1, SCHED_FIFO = 2, AF_UNIX = AF_LOCAL, AF_FILE = AF_LOCAL; // these values should be ubiquitous def S_ISUID = 04000, S_ISGID = 02000, S_ISVTX = 01000, S_IRWXU = 00700, S_IRUSR = 00400, S_IWUSR = 00200, S_IXUSR = 00100, S_IRWXG = 00070, S_IRGRP = 00040, S_IWGRP = 00020, S_IXGRP = 00010, S_IRWXO = 00007, S_IROTH = 00004, S_IWOTH = 00002, S_IXOTH = 00001; /****************************************************************************/ /* Additional string functions. Some trivial stuff from the C library you might have been missing in Q. */ /* character predicates */ public extern islower C, isupper C, isalpha C, isdigit C, isxdigit C, isalnum C, ispunct C, isspace C, isgraph C, isprint C, iscntrl C, isascii C; /* convert a string to lower- or uppercase */ public extern tolower S, toupper S; /****************************************************************************/ /* Byte strings. The following type represents unstructured binary data implemented as C byte vectors. This data structure is used by the low-level I/O functions and other clib functions which operate on binary data. */ public extern type ByteStr; public isbytestr B; // check for byte strings isbytestr _:ByteStr = true; isbytestr _ = false otherwise; /* Byte strings can be constructed from integers, floating point numbers, string values or lists of unsigned byte values. If X is not a list, an optional SIZE (as in bytestr (X,SIZE)) denotes the desired byte size of the object; otherwise a reasonable default size is chosen. If the specified size differs from the actual size of X, the result is zero-padded or truncated accordingly. Multiprecision integer values are encoded in the host byte order, with the least significant limb first. Negative integers are represented in 2's complement. Floating point values are encoded using double precision by default or if the byte count is sufficient (i.e., at least 8 on most systems), and using single precision otherwise. */ public extern bytestr X; // create a byte string /* Like ordinary character strings, byte strings can be concatenated, size- measured, indexed, sliced and compared lexicographically. Moreover, a byte string can be converted back to a (multiprecision) integer, floating point number, string value, or a list of byte values. */ public extern bcat Bs; // concatenate list of byte strings public extern bsize B; // byte size of B public extern byte I B; // Ith byte of B public extern bsub B I J; // slice of B (bytes I..J) public extern bcmp B1 B2; // compare B1 and B2 public extern bint B; // convert to unsigned integer public extern bfloat B; // convert to floating point number public extern bstr B; // convert to string public stdlib::null B; // check for empty byte string public bytes B; // convert to list public ::list B; // dito null B:ByteStr = (#B=0); bytes B:ByteStr = map (B!) [0..#B-1]; list B:ByteStr = bytes B; /* For convenience, the following common operators are overloaded. */ #B:ByteStr = bsize B; B:ByteStr!I:Int = byte I B; B1:ByteStr++B2:ByteStr = bcat [B1,B2]; sub B:ByteStr I J = bsub B I J; (B1:ByteStr=B2:ByteStr) = (bcmp B1 B2=0); (B1:ByteStrB2:ByteStr) = (bcmp B1 B2>0); (B1:ByteStr<>B2:ByteStr) = (bcmp B1 B2<>0); (B1:ByteStr<=B2:ByteStr) = (bcmp B1 B2<=0); (B1:ByteStr>=B2:ByteStr) = (bcmp B1 B2>=0); /****************************************************************************/ /* Extended file functions. Provide an extended version of fopen which handles the `+' mode for r/w files, and various other stdio-related stuff from the C library. */ public extern ::fopen NAME MODE, fdopen FD MODE, freopen NAME MODE F; public extern fileno F; /* Set the buffering mode for a file. */ public extern setvbuf F MODE; /* Get a temporary file name, or a temporary file opened in "w+b" mode which will be deleted automatically when it is closed. */ public extern tmpnam, tmpfile; /* File positioning functions. */ public extern ftell F, fseek F POS WHENCE; public rewind F; rewind F:File = fseek F 0 SEEK_SET; /* Alternative string input functions. */ public extern gets, fgets F; public extern fget F; /* ungetc. */ public extern ungetc C, fungetc F C; /* Some aliases for C afficionados. */ public ::readc as getc, ::freadc F as fgetc; public ::writes S as puts, ::fwrites F S as fputs; public ::writec C as putc, ::fwritec F C as fputc; /****************************************************************************/ /* C-style formatted I/O. These functions provide an interface to the C printf and scanf routines. Arguments to the printf routines and the results of the scanf routines are encoded as tuples or single non-tuple value (if only one item is read/written). */ public extern printf FORMAT ARGS, fprintf F FORMAT ARGS, sprintf FORMAT ARGS; public extern scanf FORMAT, fscanf F FORMAT, sscanf S FORMAT; /****************************************************************************/ /* File and directory functions. These functions provide the same functionality as their C counterparts. */ public extern rename OLD NEW; // rename a file public extern unlink NAME; // delete a file public extern truncate NAME LEN; // truncate a file (U) public extern getcwd, chdir NAME; // get/set the working directory public extern mkdir NAME MODE; // create a new directory public extern rmdir NAME; // remove a directory public extern readdir NAME; // list the files in a directory public extern link OLD NEW; // create a hard link (U) public extern symlink OLD NEW; // create a symbolic link (U) public extern readlink NAME; // read a symbolic link public extern mkfifo NAME MODE; // create a named pipe (U) public extern access NAME MODE; // test access mode public extern chmod NAME MODE; // set the file mode public extern chown NAME UID GID; // set file ownership (U) public extern lchown NAME UID GID; // set link ownership (U) public extern utime NAME TIMES; // set the file times public extern umask N; // set/get file creation mask public extern stat NAME, lstat NAME; // file and link information /* Access routines for the components of the tuples returned by the stat/lstat functions. */ public st_dev STAT, st_ino STAT, st_mode STAT, st_nlink STAT, st_uid STAT, st_gid STAT, st_rdev STAT, st_size STAT, st_atime STAT, st_mtime STAT, st_ctime STAT; st_dev STAT = STAT!0; st_ino STAT = STAT!1; st_mode STAT = STAT!2; st_nlink STAT = STAT!3; st_uid STAT = STAT!4; st_gid STAT = STAT!5; st_rdev STAT = STAT!6; st_size STAT = STAT!7; st_atime STAT = STAT!8; st_mtime STAT = STAT!9; st_ctime STAT = STAT!10; /****************************************************************************/ /* Process control. Most of these operations are UNIX-specific. */ public extern system CMD; // execute command using the shell public extern fork; // fork a child process (U) public extern exec PROG ARGS; // execute program public extern spawn PROG ARGS; // execute program in child process public extern _spawn MODE PROG ARGS; // execute child with options public extern nice INC; // change nice value (U) public extern exit N; // exit process with given exit code public extern pause; // pause until a signal occurs (U) public extern raise SIG; // raise signal in current process public extern kill SIG PID; // send signal to given process (U) public extern getpid; // current process id public extern getppid; // parent's process id (U) public extern wait; // wait for any child process (U) public extern waitpid PID OPTIONS; // wait for given child process (U) /* Routines to interpret the exit codes returned by the spawn/system/wait/ waitpid functions (U). */ public extern isactive STATUS; // process is active public extern isexited STATUS, exitstatus STATUS; // process has exited normally, get its exit code public extern issignaled STATUS, termsig STATUS; // process was terminated by signal, get the signal number public extern isstopped STATUS, stopsig STATUS; // process was stopped by signal, get the signal number // process environment public extern getenv NAME, setenv NAME VAL; /* User/group-related functions (U). */ public extern setuid UID, setgid GID; // set user/group id of process public extern seteuid UID, setegid GID; // set effective user/group id public extern setreuid RUID EUID, setregid RGID EGID; // set real and effective ids public extern getuid, geteuid; // get real/effective user id public extern getgid, getegid; // get real/effective group id public extern getlogin; // get real login name // get/set supplementary group ids of current process public extern getgroups, setgroups GIDS; /* Session-related routines (U). */ public extern getpgid PID, setpgid PID PGID; // get and set process group public extern getpgrp, setpgrp; // dito, for calling process public extern getsid PID; // get session id of process public extern setsid; // create a new session /****************************************************************************/ /* Low-level I/O. Operations for direct manipulation of files on the file descriptor level. These are simple wrappers for the low-level I/O operations of the C library. */ /* General operations. */ public extern open NAME FLAGS MODE; // create a new descriptor public extern close FD; // close a descriptor public extern dup FD, dup2 OLDFD NEWFD; // duplicate a descriptor public extern pipe; // create an unnamed pipe /* fstat returns the same kind of structure as stat and lstat, see above. */ public extern fstat FD; // stat descriptor public extern fchdir FD; // change directory (U) public extern fchmod FD MODE; // change file mode (U) public extern fchown FD UID GID; // set file ownership (U) public extern ftruncate FD LEN; // truncate a file (U) public extern fsync FD, fdatasync FD; // sync the given file (U) /* Read/write binary data represented as byte strings (see the ByteStr data structure above). NOTE: These operations work on standard file objects just as well as on descriptors. */ public extern bread FD SIZE; // read a byte string public extern bwrite FD DATA; // write a byte string /* Position the file pointer. In difference to fseek, this function works on file descriptors and returns the new offset. */ public extern lseek FD POS WHENCE; /* Fcntl operation (U). Note that the ARG parameter depends on the type of operation performed. See the manual for details. */ public extern fcntl FD CMD ARG; /* Select operation. This operation is available on Windows as part of the socket interface, but only applies to sockets there. */ /* The input is a tuple (IN,OUT,ERR,TIMEOUT) consisting of three lists of file descriptors or file objects to be watched, and an optional integer or floating point value specifying a timeout in seconds. The result is a triple indicating the lists of files/descriptors which are now ready to perform I/O (which might consist of three empty lists if the timeout was exceeded). If no timeout is specified then the function may block indefinitely. */ public extern select FILES; /* Some terminal-related stuff. */ public extern isatty FD; // is descriptor a terminal? /* Terminal associated with a file descriptor, and the name of the controlling terminal. (U) */ public extern ttyname FD; // terminal associated with descriptor public extern ctermid; // name of controlling terminal /* Pseudo terminal operations (U). The openpty function returns a pair (MASTER, SLAVE) of file descriptors, while forkpty returns a pair (PID, MASTER) where PID is 0 in the forked child and the child's process id in the parent. */ public extern openpty, forkpty; /****************************************************************************/ /* Termios interface (U). Terminal attributes are stored in a termios structure, represented as a 7-tuple (IFLAG,OFLAG,CFLAG,LFLAG,ISPEED, OSPEED,CC). The control character set CC is represented as a list of character numbers, indexed by the symbolic constants VEOF etc. See termios(3) for further details. */ public extern tcgetattr FD; // get terminal attributes public extern tcsetattr FD WHEN ATTR; // set terminal attributes public extern tcsendbreak FD DURATION; // send break public extern tcdrain FD; // wait until all output finished public extern tcflush FD QUEUE; // flush input or output queue public extern tcflow FD ACTION; // control input/output flow public extern tcgetpgrp FD; // get terminal process group public extern tcsetpgrp FD PGID; // set terminal process group /* Access components of the termios structure. */ public c_iflag ATTR, c_oflag ATTR, c_cflag ATTR, c_lflag ATTR, c_ispeed ATTR, c_ospeed ATTR, c_cc ATTR; c_iflag ATTR = ATTR!0; c_oflag ATTR = ATTR!1; c_cflag ATTR = ATTR!2; c_lflag ATTR = ATTR!3; c_ispeed ATTR = ATTR!4; c_ospeed ATTR = ATTR!5; c_cc ATTR = ATTR!6; /****************************************************************************/ /* System information. */ /* System error codes. */ public extern errno, seterrno N; // get/set last error code public extern perror S, strerror N; // print error message /* Operating system identification (U). */ public extern uname; // return OS identification /* Access components of uname result. */ public un_sysname UNAME, un_nodename UNAME, un_release UNAME, un_version UNAME, un_machine UNAME; un_sysname UNAME = UNAME!0; un_nodename UNAME = UNAME!1; un_release UNAME = UNAME!2; un_version UNAME = UNAME!3; un_machine UNAME = UNAME!4; /* Hostname. */ public extern gethostname; /* Various system databases. */ /* Password and group database (U). Password entries are encoded as 7-tuples (NAME,PASSWD,UID,GID,GECOS,DIR,SHELL), group entries as 4-tuples (NAME,PASSWD,GID,MEMBERS). */ public extern getpwuid UID, getpwnam NAME; // look up a password entry public extern getpwent; // list of all pw entries public extern getgrgid GID, getgrnam NAME; // look up group entry public extern getgrent; // list of all group entries /* Access components of password and group structures. */ public pw_name PW, pw_passwd PW, pw_uid PW, pw_gid PW, pw_gecos PW, pw_dir PW, pw_shell PW; pw_name PW = PW!0; pw_passwd PW = PW!1; pw_uid PW = PW!2; pw_gid PW = PW!3; pw_gecos PW = PW!4; pw_dir PW = PW!5; pw_shell PW = PW!6; public gr_name GR, gr_passwd GR, gr_gid GR, gr_members GR; gr_name GR = GR!0; gr_passwd GR = GR!1; gr_gid GR = GR!2; gr_members GR = GR!3; /* UNIX password encryption. */ public extern crypt KEY SALT; // (U) /* The following functions require BSD-style gethostbyname and friends. Only the gethostbyname, gethostbyaddr, getprotobyname, getprotobynumber, getservbyname and getservbyport operations are available on Windows. The meaning of the various items described here is explained under "BSD socket interface" below. */ /* Host database. Host entries are of the form (NAME,ALIASES,ADDR_TYPE, ADDR_LIST), where NAME denotes the official hostname, ALIASES its alternative names, ADDR_TYPE the address family and ADDR_LIST the list of addresses. Both hostnames and IP addresses are specified as strings. */ public extern gethostbyname HOST, gethostbyaddr ADDR; public extern gethostent; // (U) public h_name HENT, h_aliases HENT, h_addr_type HENT, h_addr_list HENT; h_name HENT = HENT!0; h_aliases HENT = HENT!1; h_addr_type HENT = HENT!2; h_addr_list HENT = HENT!3; /* Protocol database. Protocol entries are of the form (NAME,ALIASES,PROTO) denoting official name, aliases and number of the protocol. */ public extern getprotobyname NAME; public extern getprotobynumber PROTO; public extern getprotoent; // (U) public p_name PENT, p_aliases PENT, p_proto PENT; p_name PENT = PENT!0; p_aliases PENT = PENT!1; p_proto PENT = PENT!2; /* Service database. Service entries are of the form (NAME,ALIASES,PORT,PROTO) denoting official name, aliases, port number and protocol number of the port. The NAME argument of getservbyname can also be a pair (NAME,PROTO) to restrict the search to services for the given protocol (given by its name). Likewise, the PORT argument can also be replaced with (PORT,PROTO). */ public extern getservbyname NAME; public extern getservbyport PORT; public extern getservent; // (U) public s_name PENT, s_aliases PENT, s_port PENT, s_proto PENT; s_name PENT = PENT!0; s_aliases PENT = PENT!1; s_port PENT = PENT!2; s_proto PENT = PENT!3; /****************************************************************************/ /* BSD socket interface. These functions are available on systems providing a BSD-compatible socket layer (BSD, BeOS, Linux, OSX, Windows and most recent System V flavours). At creation time, a socket is described by the following attributes (see socket(2) for more details): - Address family (sometimes also referred to as namespace, protocol family or domain). The adress families supported by this implementation are AF_LOCAL (a.k.a. AF_UNIX a.k.a. AF_FILE), AF_INET and AF_INET6. - Communication style (also called the socket type). One distinguishes between "connection-based" sockets which are used to establish client/ server connections, and "connectionless" sockets which allow data to be received from and sent to arbitrary addresses. The socket types supported by this implementation are SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW and SOCK_RDM. Among these, SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM are connection-based. Please note that not all socket types are supported for all protocol families. - Protocol: For each address a.k.a. protocol family and socket type there may be a number of different protocols available. For the AF_LOCAL namespace, which refers to the local filesystem, the protocol is always 0, the default protocol. The available protocols for the internet namespaces can be retrieved from the protocol database. Before another process can connect to a socket it must also be bound to an address. The address format depends on the address family of the socket. For the local namespace, the address is simply a filename on the local filesystem. For the IPv4 namespace, it is a pair (HOST,PORT) where HOST denotes the host name or IP address, specified as a string, and PORT is a port number. For the IPv6 namespace, it is a quadrupel (HOST,PORT,FLOWINFO, SCOPEID). Host names and known port numbers can be retrieved from the host and service databases. */ /* Create a socket, or a pair of connected sockets, for the given address family, socket type and protocol. */ public extern socket FAMILY TYPE PROTO; public extern socketpair FAMILY TYPE PROTO; // (U) /* Shut down data transmission on a socket. You can stop reading, writing or both, depending on whether HOW is SHUT_RD, SHUT_WR or SHUT_RDWR. */ public extern shutdown SOCKET HOW; /* Close a socket. On most systems this is just identical to close (see Low-Level I/O above), but on some systems (in particular, BEOS and Windows) socket descriptors are special and you must use this function instead. */ public extern closesocket SOCKET; /* Bind a socket to an address. */ public extern bind SOCKET ADDR; /* Start listening for and accept connection requests. These operations are used on the server side of a connection-based socket. */ public extern listen SOCKET N; public extern accept SOCKET; /* Initiate a connection on a socket. This function can be used on both connection-based and connectionless sockets. */ public extern connect SOCKET ADDR; /* Retrieve information about a socket, and get/set socket options (encoded as byte strings). */ public extern getsockname SOCKET; public extern getpeername SOCKET; public extern getsockopt SOCKET LEVEL OPT; public extern setsockopt SOCKET LEVEL OPT DATA; /* Transmit datagrams on a socket. All data is encoded as byte strings. The receive operations return the received data, the send operations the number of bytes actually written. For recvfrom/sendto the data is encoded as a pair (ADDR,DATA) which includes the source/destination address. */ public extern recv SOCKET FLAGS SIZE, send SOCKET FLAGS DATA; public extern recvfrom SOCKET FLAGS SIZE, sendto SOCKET FLAGS DATA; /****************************************************************************/ /* Multithreading. These operations are in close correspondence with POSIX 1003.1b. However, some operations are named differently, and since there are no mutable data structures in Q, semaphores provide the extra functionality to send data from one thread to another. Mutexes are also supported, mostly for the purpose of handling critical sections involving operations with side-effects (I/O etc.). Mutexes are *not* required to make conditions work since these have their own internal mutex handling. For more information on POSIX threads, please refer to the corresponding section in the UNIX manual. */ /* These functions will only work as advertised if the interpreter has been built with POSIX thread support (--with-pthread). It must also be noted that in the current implementation the interpreter effectively serializes multithreaded scripts on the reduction level and thus user-level threads cannot really take advantage of multi-processor machines. */ /* Thread creation and management. */ public extern type Thread; // thread handle type public isthread THREAD; // check for thread objects isthread _:Thread = true; isthread _ = false otherwise; public extern thread_no THREAD; // thread number public extern this_thread; // handle of the current thread (T1:Thread = T2:Thread) = (thread_no T1 = thread_no T2); (T1:Thread < T2:Thread) = (thread_no T1 < thread_no T2); (T1:Thread > T2:Thread) = (thread_no T1 > thread_no T2); (T1:Thread <> T2:Thread) = (thread_no T1 <> thread_no T2); (T1:Thread <= T2:Thread) = (thread_no T1 <= thread_no T2); (T1:Thread >= T2:Thread) = (thread_no T1 >= thread_no T2); /* The main thread (private). Don't remove this definition, it is needed to prevent the main thread handle from being garbage collected! */ private var const MAIN_THREAD; def MAIN_THREAD = this_thread; public extern special thread X; // start a thread, return its handle public extern return X; // terminate thread, return X as result public extern cancel THREAD; // cancel THREAD public extern result THREAD; // wait for THREAD, return its result public extern yield; // allow context switch public extern active THREAD; // check if THREAD is active public extern canceled THREAD; // check if THREAD was canceled /* Realtime scheduling. USE WITH CARE. */ public extern setsched THREAD POL PRIO; // set scheduling parameters public extern getsched THREAD; // get scheduling parameters /* Mutexes. USE WITH CARE. */ public extern type Mutex; // mutex type public ismutex MUTEX; // check for mutex objects ismutex _:Mutex = true; ismutex _ = false otherwise; public extern mutex; // standard, i.e., fast mutex object public extern errorchecking_mutex; // error checking mutex object public extern recursive_mutex; // recursive mutex object public extern lock MUTEX; // lock MUTEX public extern unlock MUTEX; // unlock MUTEX public extern try MUTEX; // try MUTEX /* Conditions. */ public extern type Cond; // condition type public iscond COND; // check for condition objects iscond _:Cond = true; iscond _ = false otherwise; public extern cond; // new condition object public extern signal COND; // signal COND public extern broadcast COND; // broadcast COND public extern await COND; // wait for COND, or (COND,TIME) /* Semaphores (semaphore queues, actually). */ public extern type Sem; // semaphore type public issem SEM; // check for semaphore objects issem _:Sem = true; issem _ = false otherwise; public extern sem; // semaphore object public extern bounded_sem MAX; // bounded semaphore object public extern post SEM X; // enqueue a value public extern get SEM; // dequeue a value public extern try SEM; // dequeue a value, fail if none public extern get_size SEM; // get the current queue size public extern get_bound SEM; // get the max queue size (0 if none) #SEM:Sem = get_size SEM; /****************************************************************************/ /* Expression references. These can be seen as pointers to expression values. The referenced value can be changed at any time. References can be used to create mutable data structures which can also be shared by different threads in a multithreaded program. */ public extern type Ref; // reference type public isref REF; // check for reference objects isref _:Ref = true; isref _ = false otherwise; public extern ref X; // initialize a reference object public extern put REF X; // store a new value public extern get REF; // retrieve the current value /****************************************************************************/ /* Time functions. Return information about the active timezone and the current time, and convert time values to various formats. Also available are functions to measure cpu time. These functions are in close correspondence with the date and time functions of the C library, see the manual for details. */ /* Simple time (T) is represented as seconds since the "epoch", broken-down time (TM) as a 9-tuple (YEAR,MONTH,DAY,HOUR,MIN,SEC,WDAY,YDAY,ISDST). See the description of the tm struct in the ctime(3) manual page for more information. */ public extern tzname, timezone, daylight; public extern ctime T, gmtime T, localtime T; public extern mktime TM, asctime TM, strftime FORMAT TM; /* Access components of broken-down time. */ public tm_year TM, tm_month TM, tm_day TM, tm_hour TM, tm_min TM, tm_sec TM, tm_wday TM, tm_yday TM, tm_isdst TM; tm_year TM = TM!0; tm_month TM = TM!1; tm_day TM = TM!2; tm_hour TM = TM!3; tm_min TM = TM!4; tm_sec TM = TM!5; tm_wday TM = TM!6; tm_yday TM = TM!7; tm_isdst TM = TM!8; /* clock and times measure cpu time in different units, given by the constants CLOCKS_PER_SEC and CLK_TICK, respectively. The times function returns a 5-tuple (TOTAL,UTIME,STIME,CHILD_UTIME,CHILD_STIME). See times(2) for details. */ public extern clock, times; /****************************************************************************/ /* Filename globbing using the shell's wildcard syntax (*, ? etc.). */ public extern fnmatch PATTERN S; // check whether S matches PATTERN public extern glob PATTERN; // return the list of all filenames // matching PATTERN /****************************************************************************/ /* Regular expression matching using "extended" (egrep-like) syntax as defined by POSIX 1003.2/D11.2. */ /* 1. Low-level interface. The following functions are directly implemented in C using the GNU regex library. The regmatch function searches for the first match, regnext for the next, and regdone terminates a global search still in progress. The OPTS string allows you to specify various options for the search. In particular, "g" denotes a global, "i" a case-insensitive, and "n" a "multi-line" search; see the documentation for further details. */ public extern regmatch OPTS REGEX S, regnext, regdone; /* 2. High-level interface. The regex function evaluates, for each match of the given regular expression in the given string, the special EXPR argument, and returns the collection of all results as a list. The OPTS argument has the same meaning as with the low-level functions. In particular, if the "g" option is omitted, then only the first match will be reported, if any. */ public special regex ~OPTS ~REGEX ~S EXPR, regex_next EXPR; private special check ~P X Y; regex OPTS:String REGEX:String S:String EXPR = check (regmatch OPTS REGEX S) [EXPR|regex_next EXPR] []; regex_next EXPR = check regnext [EXPR|regex_next EXPR] []; check P:Bool X Y = X if P; = Y otherwise; check P X Y = P otherwise; /* 3. Match state information. These functions are typically invoked after regmatch, regnext, or in the EXPR argument of regex, to return information about the current match. The match state is maintained on a hidden stack manipulated with the regmatch/regnext/regdone functions, hence multiple nested searches are possible. */ public extern regstart, regskip, reg N, regpos N, regend N, regs; /* An expression of the form `regerr MSG', where MSG is the error message, is used to return abnormal error conditions such as bad regular expression syntax. You can redefine `regerr' as appropriate for your application. */ public regerr MSG; /****************************************************************************/ /* Additional integer functions from the GMP library. */ /* exact powers, integer parts of roots, powers/inverses mod K */ public extern pow M N, root M N, intsqrt M; public extern powmod K M N, invmod K M; /* number-theoretic functions: probabilistic prime test, gcd, lcm, factorization helpers, and Jacobi symbol */ public extern isprime N; public extern gcd M N, lcm M N, fact M N, rem M N; public extern jacobi M N; /****************************************************************************/ /* C implementations of common standard library functions. These are *much* faster than the originals in stdlib.q and string.q. */ public extern stdlib::append Xs Y, stdlib::cat Xs, stdlib::mklist X N, stdlib::nums N M, stdlib::numsby K N M, stdlib::reverse Xs, stdlib::tuplecat Xs; public extern string::chars S, string::join DELIM Xs, string::split DELIM Xs, string::strcat Xs; /* fast (albeit unstable) quicksort implementation using the qsort routine from the C library */ public extern sort P Xs;