next up previous contents index
Next: References Up: No Title Previous: Running Unix Processes

Interfacing to Unix

  This section is devoted to the description of the procedures of the module Unix.oz. It is loaded when the DFKI Oz system starts, and available by the variable Unix. For information on the modules Oz provides for see [1]. Most procedures can be seen as straightforward lifting of Unix functionality to the Oz level. Hence, our description will consist of a reference to the relevant Unix manual page and specification of differences between the Unix system call and the DFKI Oz implementation. As a major convention you can see that most int arguments in C are integers in Oz. Moreover char* arguments will be virtual strings, if they are used as input in C. If they are used as output in C they will be ordinary strings. An n-ary C-function returning a value is implemented as a n-ary Oz function. If an error occurs, the last argument (this argument, if present, will be denoted as StatusTI) is constrained to a ternary tuple with label error. The tuple's first argument is constrained to the number of the error (as specified by the respective Unix version your computer runs with), its second to a virtual string giving an error message. Its last argument is constrained to a virtual string describing which kind of error occurred, for instance an ordinary Unix error (constrained to unix), a host-lookup error (constrained to host), and so on. In cases where no information about the errors is available, the boolean value False is obtained as output. If arguments of the application are not used accordingly, failure is raised and a warning is printed. Whenever one needs predefined constants from C, one can use their names as atoms in Oz. Wherever bitwise disjunction of predefined constants is used in C, a list of atoms with the constant names are allowed, which are interpreted as bitwise disjunction of their respective values. The functionality of the module Unix can be classified as procedures which are useful in applications, or procedures needed for building high level functionality. In the latter case, we will point to the places where we have used these procedures.

Application Procedures

Random Integers

{rand ?I}
   Constrains I to randomly generated integer. See rand(3)  .
{srand +I}
   Sets the seed for the random number generator used by Unix.rand. If I is 0, the seed will be generated from the current time. See srand(3)  .
{randLimits ?MinI ?MaxI}
   Constrains MinI and MaxI to the smallest and greatest possible random number obtainable by Unix.rand. See rand(3)  .

Sockets

{getServByName +NameV +ProtoV ?PortIB}
   Gives the port number PortIB of a service NameV reachable in the Internet domain with the specified protocol ProtoV. If the service is unknown, PortIB will be constrained to False. As an example, the application
{getServByName "finger" "tcp" Port}
will constrain Port to the number, where you can connect to your local finger server. See getservbyname(3)  .
{getHostByName +NameV ?OfficialS ?AliasSs ?AddressSs}
   For the host NameV the official host-name OfficialS, a list of alias names AliasSs, and a list of strings giving numerical Internet addresses AddressSs is computed. See gethostbyname(3)  .

Time Inquiry

{gmTime ?GmTimeR}
{localTime ?LocalTimeR}
      Constrains GmTimeR to a description of the Coordinated Universal Time (UTC), respectively LocalTimeR to a description of the local time. The description is given by a record like:
time(sec:  % seconds (0..61) 
     min:  % minutes (0..59)
     hour: % hours (0..23)
     mDay: % day of month (1..31)
     mon:  % month of year (0..11)
     year: % years since 1900
     wDay: % days since Sunday (0..6)
     yDay: % day of year: 0..365
     isDst:% 1 if daylight savings time in effect (DST)
)
See gmtime(3)  , localtime(3)  , and time(3)  .

Miscellaneous

 

{getEnv +NameV ?ValueSB}
   Constrains ValueSB to the value of the environment variable NameV. If a variable with the given name does not exist, the procedure will constrain ValueSB to False. As an example, consider:
{Browse {Unix.getEnv "OZHOME"}}

will show you where your Oz system has been installed. This information is also available via System.ozHome   (see [4]). See getenv(3)  .

{putEnv +NameV +ValueV}
   Sets the value of the environment variable NameV to ValueV. See putenv(3)  .
{system +CmdV ?StatusTI}
   Executes the Unix command given by CmdV. The status of the command is reported by constraining StatusTI to it. For example, the following function checks, whether a file exists and is readable.
fun {IsReadableFile FileName}
   {Unix.system "test -r "#FileName}==0
end
  See system(3)  .
{tempName +DirV +PrefixV ?FileNameS}
   Implements the tempnam(3)  call of the stdio library. This is useful for generating a new file name. Suppose you want to have a new temporary file name starting with foo, located in the directory /tmp. Then
{Browse {Unix.tempName "/tmp" "foo"}}
will constrain FileName to a string like "/tmp/fooBAAa02378".
{unlink +PathV ?StatusTI}
   Removes the file with the name PathV. If an error has occurred, StatusTI is constrained as described above. See link(2)  .
{getDir +PathV ?FileNameSs}
    FileNameSs is constrained to a list of strings giving the files in the directory PathV. If an error occurs it is reported as described above. See opendir(3)  and readdir(3)  .
{stat +PathV ?StatusRT}
    StatusRT is bound to a record with features size and dir. The subtree at the feature size is bound to an integer giving the size of the file PathV. The subtree at the feature dir is one of the following atoms: reg (regular file), dir (directory), chr (character special file), blk (block special file), fifo (pipe or FIFO special file), unknown (something else). An error is reported as described above. See stat(2)  .

Low Level Procedures

Basic Input and Output

The procedures herein are used for implementing Open.file , Open.internetSocket , Open.unixSocket , and Open.pipe .

{open +FileNameV +FlagsAs +ModeAs ?StatusTI}
   Opens a file or a socket for reading and writing. FlagsAs must be a list with some of the following atoms as elements: 'O_RDONLY', 'O_WRONLY', 'O_RDWR', 'O_APPEND', 'O_CREAT', 'O_EXCL', 'O_TRUNC', 'O_NOCCTY', 'O_NONBLOCK', and 'O_SYNC'. Their meanings coincide with their usual Unix meanings. In the same manner ModeAs must be a list with elements drawn from: 'S_IRUSR', 'S_IWUSR', 'S_IXUSR', 'S_IRGRP', 'S_IWGRP', 'S_IXGRP', 'S_IROTH', 'S_IWOTH', and 'S_IXOTH'. An error is reported as described above. See open(2)  and chmod(2)  .

{fileDesc +FileDescA ?FileDescIB}
   Maps the atoms 'STDIN_FILENO', 'STDOUT_FILENO', and 'STDERR_FILENO' to integers, giving their respective file descriptor. Note that these descriptors will be duplicated. Otherwise it will fail. See open(2)  and dup(2)  .
{read +DescI +MaxI ?ListS TailX ?StatusTI}
   Reads data from a file or socket. Implements the read(2) 

system call. Unix.read yields a list of characters in ListS, where the tail of the list is constrained to TailX. If an error occurs, StatusTI will be constrained accordingly. An attempt to read from a file descriptor where no data is available constrains StatusTI to the atom unable. This problem is discussed below. Otherwise StatusTI is constrained to the number of characters read.

{write +DescI +V ?StatusTI}
   Writes the virtual string V to a file or a socket by using the system call write(2)  . If an error occurs, StatusTI is constrained as described above. Illegal parts of the virtual string +V are simply ignored, and the legal parts are written. If it is not possible to write at the moment, StatusTI is constrained to the unary tuple with label unable, where its argument is constrained to the part of V not written yet. If V contains an unconstrained variable, StatusTI is constrained to a ternary tuple with label suspend. The first argument is constrained to an integer describing the portion already written, the second to the unconstrained variable, and the last to the not yet written part of V. Otherwise StatusTI is constrained to the number of characters written.
{lSeek +DescI +WhenceA +OffsetI ?StatusTI}
   Positions the seek pointer of a file. This procedure is implemented by the lseek(2)  call. WhenceA must be one of the atoms 'SEEK_SET', 'SEEK_CUR', and 'SEEK_END'.
{close +DescI ?StatusTI}
   Closes a file or socket by using the close(2)  system call.

!!! Attention !!!

From Blocking to Suspension

  If someone wants to read from a file, or a socket via a Unix system call, it is possible that no information is available for reading. In this case the Unix system call will block, i.e. the whole Oz process will stop doing any work. To overcome this problem, we provide for three procedures. These procedures will turn in fact blocking to suspension. We have used this feature for implementing the Open classes.

{select +DescI ?StatusTI}
   Checks whether any data is present for reading at the file or socket with descriptor DescI, and constrains its output argument when data is available. For example the following case statement (we assume that Desc is constrained to a descriptor of a socket):
case {DetB {Unix.select Desc}} then
   S in case {Unix.read Desc 1024 ?S nil}
        of ... then
        \vdots
        end
end
will suspend until data for reading is available. If an error occurs StatusTI is constrained to a ternary tuple containing some information. Otherwise, StatusTI is constrained to 0. This functionality is implemented by the select(2)  system call. It is specialized for testing whether reading access is possible.
Before the previous technique is applicable one has to inform DFKI Oz in which file or socket one is interested.

{openIO +DescI ?StatusTI}
   Enables DFKI Oz to detect incoming data at the file or socket with descriptor DescI.
{closeIO +DescI ?StatusTI}
   Disables DFKI Oz to detect incoming data at the file or socket with descriptor DescI.

Sockets

The whole functionality presented here is used for implementing the Open.internetSocket  and Open.unixSocket  classes.

{socket +DomainA +TypeA +ProtoV ?StatusTI}
   Creates a socket. Implements exactly the system call socket(2)  . DomainA must be either the atom 'PF_INET' or 'PF_UNIX', whereas TypeA must be either 'SOCK_STREAM', or 'SOCK_DGRAM'. ProtoV must be a virtual string. If it denotes the empty string, an appropriate protocol is chosen automatically, otherwise it must denote a valid protocol name like "tcp" or "udp".
According to the domain of the socket, the address of a socket will be referred to by a virtual string giving the path for the Unix domain. In case of the Internet domain an integer describes the port and a virtual string describes the host name.

{bindInet +SockI +PortI ?StatusTI}
{bindUnix +SockI +PathV ?StatusTI}
      Binds a socket to its global name. See bind(2)  .
{listen +SockI +BackLogI ?StatusTI}
   Indicates that a socket is willing to receive connections. See listen(2)  .
{acceptInet +SockI ?HostS ?PortI ?StatusTI}
{acceptUnix +SockI ?PathS ?StatusTI}
      Accepts a connect request on a socket. For the Internet domain, HostS will be constrained to a string describing the host name. It is possible to use Unix.select for suspending a computation until a connect attempt on this socket is made. See accept(2)  and gethostbyaddr(3)  .
{connectInet +SockI +HostV +PortI ?StatusTI}
{connectUnix +SockI +PathV ?StatusTI}
      Used to connect to a socket. See connect(2)  and gethostbyaddr(3)  .
{shutDown +SockI +HowI ?StatusTI}
   Signals that a socket is not longer interested in sending or receiving data. See shutdown(2)  .
{getSockName +SockI ?PortI}
   Gets the name of a socket. Works only for the Internet domain, since this functionality is not available in Unix for the Unix domain. See getsockname(3)  .
{send +SockI +MsgV +FlagsAs ?StatusTI}
{sendToInet +SockI +MsgV +FlagsAs +HostV +PortI ?StatusTI}
{sendToUnix +SockI +MsgV +FlagsAs +PathV ?StatusTI}
         Sends data from a socket. FlagsAs has to be a list of atoms, its elements must be either 'MSG_OOB' or 'MSG_DONTROUTE'. See send(2)  and gethostbyname(3)  .
{receiveFromUnix +SockI +MaxI +FlagsAs ?MsgS TailX ?PathS ?StatusTI}
{receiveFromInet +SockI +MaxI +FlagsAs ?MsgS TailX ?HostS ?PortI
                 ?StatusTI}
      Receives data at a socket. FlagsAs has to be a list of atoms, its elements must be either 'MSG_OOB' or 'MSG_PEEK'. See recvfrom(2)  and gethostbyaddr(3)  .

Process Control

{pipe +CmdV +ArgsVs ?PidI ?StatusTI}
   Forks a Unix process which executes the command CmdV with arguments ArgsVs. PidI is constrained to the process identifier, and StatusTI to a Unix domain, stream typed socket descriptor where the standard input, the standard output and the standard error is redirected to. See socketpair(2)  , fork(2)  , execvp(2)  , and execve(2)  .
{wait ?PidI ?StatI}
   Implements the wait(2)  call.



next up previous contents index
Next: References Up: No Title Previous: Running Unix Processes



Sven Schmeier
Tue Sep 5 10:43:51 MET DST 1995