MUSIC/SP Socket Interface to TCP/IP =================================== File: $tcp:sockets_doc.txt Last updated: Mar 1, 2008 (c) Copyright by Dave Edwards, 2008. All rights reserved. See also: $tcp:sockets.s - Assembler source module $tcp:winsock_err.txt - Some MS Windows Sockets error codes $sys:iucv.s - MUSIC/SP nucleus module IUCV $wcc:clib.socket.h - C header file for Waterloo C sockets You can view the latest version of this documentation file at http://webpages.mcgill.ca/staff/group3/dedwar1/web/sockets_doc.txt Contents -------- 1. References 2. Introduction and Concepts 3. Implementation and Internals 4. Data Structures 5. Blocking and Nonblocking Mode 6. Notes on the Function Descriptions 7. Waterloo C Sockets 8. Socket Functions 9. MUSIC/SP-Specific Functions 10. Socket Error Codes - - - - - 1. References ------------- - For a good description of TCP/IP and the original Berkeley sockets, see the book "Unix Network Programming" by W. Richard Stevens (Prentice Hall, 1990, ISBN 0139498761) or its more recent editions. You are strongly encouraged to read Chapter 4 (A network Primer), Chaper 5 (Communications Protocols), and Chapter 6 (Berkeley Sockets), in order to understand how sockets work. - IBM manual: IBM TCP/IP for VM: Programmer's Reference, Ver 2 Rel 4 (SC31-6084-03 Dec/1996 or equivalent), Chapter 5 "IUCV Sockets". Chapter 2 "C Sockets API" is also useful as a description of the VM socket routines, which are quite close to the MUSIC/SP routines. A more recent, but similar, manual is VM/ESA TCP/IP Programmer's Reference Ver 2 Rel 4.0 (SC24-5849-01 Jul/1999). - IBM manual: VM/ESA CP Programming Services (SC24-5435-00 Jun/1990 or equivalent), Part 2: Inter-User Communications Vehicle (IUCV). This describes the general IUCV supported by VM, and the details of the various IUCV requests and external interrupts. A more recent, but similar, manual is VM/ESA CP Programming Services Ver 2 Rel 4.0 (SC24-5760-03 Jul/1999). - IBM manual: TCP/IP Tutorial and Technical Overview (GG24-3376-01 June/1990 or later equivalents). - A good, complete description of the C sockets API as it exists in the Windows 2000 environment, is available online (www.microsoft.com) and in the Help for Microsoft Visual Studio 6.0. See Platform SDK --> Networking and Distributed Services --> Windows Sockets Ver. 2. It is excellent for explaining the exact behaviour of the various socket functions. This is relevant for MUSIC/SP under the Sim390 mainframe emulator, since Sim390 uses Windows Sockets as the underlying TCP/IP. - Internet Requests For Comments (RFC's). These are numbered text documents that describe the various Internet protocols. They are available on-line from several web sites, for example www.ietf.org. 2. Introduction and Concepts ---------------------------- Using various library functions, it is possible to program TCP/IP socket applications in MUSIC/SP. The languages that can be used include Assembler, Fortran, Rexx, and Waterloo C. In order to actually run such an application, MUSIC/SP must be run under either VM (on a "real" mainframe or P/370 or P/390) or a mainframe emulator (such as Sim390) that supports the required IUCV Sockets protocol. On VM, the underlying TCP/IP is provided by the VM TCPIP virtual machine. On Sim390, the underlying TCP/IP is Windows WinSock. MUSIC/SP uses the IUCV (Inter-User Communications Vehicle) protocol to talk to the underlying TCP/IP. In Sim390, IUCV is emulated by Sim390 itself. The sockets API is a more-or-less standardized application programming interface that allows two applications, on the same or different computers, to exchange data using an underlying transport protocol. It was originally developed around 1982 for Unix, and is often referred to as "Berkely sockets". Now, most operating systems support some form of sockets. One of the most popular transport protocols is TCP/IP, which actually is comprised of several protocols: TCP (Transmission Control Protocol, which establishes a reliable, stream-oriented connection), UDP (User Datagram Protocol, which is a connectionless, unreliable protocol for sending small messages (packets) between processes), IP (Internet Protocol, which is the low-level packet delivery service used by higher-level protocols such as TCP and UDP), and others. The TCP/IP protocol suite is referred to as the Internet protocols. TCP is the basis for many application-level protocols such as FTP (File Transfer Protocol), HTTP (HyperText Transfer Protocol), Telnet remote login, and SMTP (Simple Mail Transfer Protocol). Sockets can be used with other transport protocols, such as Xerox's XNS, IBM's SNA, NetBIOS, etc., but here we are concerned only with TCP/IP, primarily TCP and UDP. In socket functions and data structures, the TCP/IP "family" of protocols is identified by the constant AF_INET = 2 (Address Family - Internet). The Address Family is also sometimes called the "domain" or the "Protocol Family". In the terminology of inter-process communications, an "association" is defined as a 5-tuple (a list of 5 things): ( protocol, local network address, local process, remote network address, remote process ). For TCP/IP, the protocol is usually TCP or UDP; a process (program) on a machine ("host") is identified by a 16-bit port number; and the network address is a 32-bit number called the IP address. A "half association" is one side of an association, and is a triple: ( protocol, network address, process ). You can loosely think of a "socket" as the half association that represents one side of a complete association. A local socket (on the local machine) and a remote socket (on a "remote" machine, which may or may not be a different machine), logically connected together, form a complete association, or communications path. An example of a completely specified association is: ( TCP protocol, local network address = 198.170.25.10, local port = 4321, remote network address = 132.206.120.4, remote port = 80 ). Often one side of an association is considered to be a server, and the other side is considered to be a client. A server listens for incoming connections on a "well-known" (i.e. predefined) port number, and client applications connect to the server. Each server and client is a separate application program (process) with its own socket. In Unix terminology, a server is often called a "daemon". A socket is identified by a "handle", which is implementation dependent, but is usually a 32-bit positive integer. The socket handle is also called a "socket number" or "socket descriptor". It is similar to the handle that identifies an open file (a file descriptor). The variable names used for a socket handle are often s, sd, socn, or fd. For example, an application creates a new socket by calling the socket() function, which returns a socket handle. Other socket functions refer to that socket via its handle. Note that when a socket is first created by the socket() function, only the protocol part of the 5-tuple association is filled in; the other 4 parts of the association are filled in later by calls to other functions such as bind() and connect(). For example, after socket(), a TCP server normally calls bind(), listen(), and accept(). After socket(), a TCP client normally calls just connect(). After the socket is completely specified, the application is free to call send() and similar functions to write data to the socket, and recv() and similar functions to read data from the socket. An application can have several sockets open at the same time. A port number does not have to be unique within the host machine. Only the complete 5-tuple association has to be unique. For example, an HTTP server process may have several simultaneous connections to different clients, all with the same local port number 80. However, only one server process at a time on a machine can be listening for incoming connections on a given port number. Two different processes on a machine cannot both be listening on port 80, for example. 3. Implementation and Internals ------------------------------- MUSIC/SP uses a protocol called "IUCV Sockets" (IUCV Socket Application Programming Interface) for TCP/IP socket operations. This protocol was originally designed for IBM's VM operating system, as a way for a virtual machine to perform TCP/IP socket operations, but it is also supported by the Sim390 mainframe emulator, independently of VM. The socket routines in MUSIC/SP are contained in the source file $tcp:sockets.s, and are similar to the standard Berkeley Sockets functions in Unix systems. The corresponding object modules are in the *MUS subroutine library. (For Waterloo C, the equivalent object file is $tcp:watc.sockets.obj .) Most of these socket routines can also be called from a program written in Rexx. In that case, use the short (6 char or less) version of the name. The Rexx functions are in the REXSOCK Load Library member. The calling sequence definitions assumed by Rexx are in $rex:rexx.functabl.s . The following routines are not provided by REXSOCK: READV, RECVMG, SELECTX, SENDMG, WRITEV. MUSIC/SP uses VM's IUCV (Inter-User Communications Vehicle) protocol to communicate with the TCPIP virtual machine, which performs the real TCP/IP socket operations. Therefore most socket routines (source file: $tcp:sockets.s) in MUSIC/SP issue an IUCV Send request, specifying the socket operation to be done and the data values to be used. The results of the socket operation (return codes, data, etc.) are returned to MUSIC/SP in an IUCV answer area, and the MUSIC/SP socket routine returns them to the caller. In the case of MUSIC/SP running under the Sim390 emulator, the emulator plays the role of both IUCV and the VM TCPIP virtual machine. Sim390 provides the IUCV services that are required. IUCV requests require the MUSIC/SP SYSCOM privilege. In order to do socket calls, the userid or program must have this privilege. In order for a MUSIC/SP application program to use TCP/IP, it must first establish an IUCV path to the TCPIP virtual machine (by an IUCV Connect request), then do an IUCV Send specifying parameters for the path. This path setup is done automatically by the code in $tcp:sockets.s the first time the application program calls a socket routine which requires a TCPIP socket operation. Within that path, the application program may open 1 or more sockets, each potentially representing a connection to a remote process. Each socket is given a socket number ("handle"), which is a small integer (0, 1, 2, ...) by which the application program refers to the socket. Each path has its own set of socket numbers; two different paths (i.e. 2 different tasks in MUSIC/SP) may each have a socket number 0, for example, but they refer to different actual sockets. Each IUCV path is identified by a 16-bit path id, which is assigned by IUCV as a result of the IUCV Connect request. Each IUCV Send request (representing a socket operation) specifies the path id as part of the request. The coding in $tcp:sockets.s automatically manages the application's path id. The MUSIC/SP virtual machine may have several tasks running simultaneously, therefore several IUCV paths established to the TCPIP virtual machine. As part of the parameters for the initial IUCV Send during path setup, MUSIC/SP must specify a unique (unique within the MUSIC/SP virtual machine) 8-character subtaskid. By default, the coding in $tcp:sockets.s uses "MUSnnnnn", where nnnnn is the TCB number, as the subtaskid. However, a different subtaskid can be specified by calling the XPATH routine before any socket calls. For example, a child task created by INETD (the "super server") uses "INExxxxx", where xxxxx is a printable hex global sequence number assigned by INETD, as its subtaskid, when receiving the incoming socket connection from INETD via TAKESK(); see $tcp:getsoc.s . It is possible for an application program to open more than 1 path to TCPIP, however $tcp:sockets.s only knows about the single path that it sets up. To open a second path, the application would have to do its own IUCV Connect request etc., separate from $tcp:sockets.s . The nucleus module IUCV ($sys:iucv.s) maintains a table of path ids and the TCB number which owns each path. A program can do IUCV requests only on its own path ids. However, since a single path can represent multiple sockets, there is really no need for more than 1 path per program. The socket routines ($tcp:sockets.s) are NOT serially reusable, They remember various settings and values between calls. Therefore they must be in the root segment, if the application program uses an overlay structure. 4. Data Structures ------------------ A number of structures and constants are used in the TCP/IP socket interface. A few of the common ones are explained below. Others are detailed in the applicable socket calls. Note that the information applies to the AF_INET (=2) domain (Internet). Unless indicated otherwise, binary integer values are in network byte order, i.e. Big-endian, i.e. high-order byte is first. Character strings are in EBCDIC, since MUSIC/SP runs in an IBM mainframe environment. Native binary values in MUSIC/SP are in Big-endian byte order, even when it runs under a mainframe emulator (Hercules or Sim390) on an Intel PC. By contrast, native binary values in an Intel PC are in Little-endian order. The native byte order is called "host byte order" or "local byte order". When there is any doubt, and to make porting of applications to other environments easier, the byte ordering conversion routines htonl(), htons(), ntohl(), and ntohs() should be used. Network socket address or name: This is used in the calls that establish connections or send data to specific places. (In Waterloo C sockets, the structure sockaddr_in or sockaddr is used.) 2 2 4 8 +------+------+----------+------------------+ | 0002 | pppp | aaaaaaaa | 0000000000000000 | +------+------+----------+------------------+ 0002 - indicates the AF_INET (internet) domain, in local byte order. pppp - 16-bit port number, in network byte order. a..a - 32-bit internet address of host, in network byte order. 0..0 - binary zeros. Clientid: This is used in exchanging sockets between applications. This data structure is specific to the VM IUCV TCP/IP environment, and should be considered opaque (a "black box") to the application. See the GIVESK() and TAKESK() routines. A program can call GCLNID() to get its own clientid. (In Waterloo C sockets, the structure clientid is used.) 4 8 8 20 +----------+------------------+-----------------+-----/-----+ | 00000002 | vvvvvvvvvvvvvvvv | ttttttttttttttt | 0.......0 | +----------+------------------+-----------------+-----/-----+ 0..2 - Indicates the AF_INET (internet) domain. v..v - Virtual machine name. This is the VM userid of the MUSIC virtual machine, e.g. "MUSIC ". For MUSIC/SP running under Sim390, it is always "MUSIC ". Note: If an application program needs to construct a clientid, it should call GCLNID() to get its own clientid to use as a model, rather than filling in the domain and virtual machine name from other sources. t..t - Task name specified when connecting to TCP/IP (subtaskid - see the Introduction section above). This name identifies the IUCV path (application) within the virtual machine, i.e. within the MUSIC/SP system. It is 8 characters long. Example: 'MUSnnnnn' where nnnnn is the 5-digit TCB (Task Control block) number of the MUSIC/SP application program. 0..0 - Binary zeros. 5. Blocking and Nonblocking Mode -------------------------------- Each socket is in either blocking or nonblocking mode. When a socket is created, it is in blocking mode, but it can be set to nonblocking mode by a call to FCNTL(). In blocking mode, a call to a socket routine does not return until the operation is complete (e.g. for a READ(), some data is available to be read; for a WRITE(), all the data has been written); the program may be blocked (delayed) until the operation is complete. In nonblocking mode, if the operation would require the program to wait, error value EWOULDBLOCK (-35) is returned instead, and the operation is not done; the program could then call SELECT() to wait until the operation can be retried. Note that the operation of the SELECT() routine is not affected by whether the socket is in blocking or nonblocking mode. Implementation note: In Windows Sockets and in the Sim390 and VM implementations of IUCV sockets, a write operation (WRITE(), SEND(), etc.) on a blocking-mode socket does not return until ALL the requested bytes have been written to the socket (or an error occurs). In other words, a write on a blocking-mode socket is not partial. However, this is not necessarily true for other socket implementations, such as Unix; therefore it is advisable to check that the return value (the number of bytes actually written) is not less than the number requested. In the case of a write to a nonblocking socket, the write may be partial (i.e. return value is positive but less than the number of bytes requested), in all implementations. A write operation should not specify a length of 0. In the case of a read operation on a socket (in any mode), the read may be partial, in all implementations. - - - - - 6. Notes on the Function Descriptions ------------------------------------- In the descriptions below, each subroutine is known by two names. The first one in lower case is the official C name. The second name is the six character name that can be used to call the routines from languages that don't support long subroutine names like FORTRAN, ASSEMBLER, and REXX. Arguments are described as "In" (input to the routine), "Out" (output from the routine), or "In/Out" (both). If not indicated for an argument, the type is "In". Unless indicated otherwise, values are 32-bit signed integers (Fortran INTEGER*4). In most cases, a return value rc < 0 indicates an error. For rc = -n, n is an error code which indicates the cause of the error. The error codes are listed at the end of this document. Some error codes are standard Unix codes. Others are specific to MUSIC/SP or the VM or Sim390 implementation of IUCV Sockets. (Functions in Waterloo C sockets use a slightly different return value convention - see the section below.) 7. Waterloo C Sockets --------------------- A sockets API (Application Programming Interface) is provided for Waterloo C on MUSIC/SP. It is designed to be as close as reasonably possible to the standard Unix, VM, and Windows (WinSock) C sockets API. Standard function names (the lower-case longer names shown in the function descriptions below), arguments, and return types are used. See the WatC header file $wcc:clib.socket.h for the exact definitions and function prototypes. Enter the command "/help watc" to get detailed general information about Waterloo C on MUSIC/SP. Requirements for coding a TCP/IP sockets program in WatC: - Use the /inc watc control statement to compile. - Use #include . It should precede other #include's. - Use #include , to give access to the WatC error code number variable errno. Most WatC socket functions return rc=-1 if an error occurred. In that case, you can refer to the errno variable to get the actual WatC error code, which is a positive integer. Note: WatC socket functions and other library functions never reset errno to 0; therefore you should examine errno only after a function call returns an error indication (rc<0). You should always use the standard names for error codes (EBADF, EINVAL, EWOULDBLOCK, ECONNREFUSED, etc.), not the actual numeric values, since (for compatibility with existing WatC non-socket errno values) the values used in WatC are different from the standard Unix values, and are different from the numeric values given in this documentation file. See file $wcc:clib.socket.h . Exception: In WatC, the following functions do NOT set errno when an error occurs (the function return value itself indicates the type of error): inet_addr, muresolve - Use the following /include statement at the end of your program (or in your Linkage Editor job), to include the required API function object modules: /include $tcp:watc.sockets.obj - If your WatC program uses the muresolve() function (for DNS lookup to convert a domain name to IP address), you also need the following /include statement: /include $tcp:watc.muresolv.obj - If your WatC program (a server application) uses the mugetsoc() function, you also need the following /include statement: /include $tcp:watc.mugetsoc.obj - The function calling convention used in WatC is different from that used for normal Fortran and assembler routines in MUSIC/SP and MVS. Therefore a WatC program cannot directly call a normal MUSIC/SP library function (i.e. a function from the *MUS or *OS libraries). A Program Interrupt (program crash) would occur. That is why WatC uses its own versions of the socket functions, in object file $tcp:watc.sockets.obj . For example, you must not try to call RESOLV directly from a WatC program; you must use the function muresolve instead. Enter the command "/help watc" for more information about calling conventions. - For a small sample program, see file $wcc:watc.sock.sample . The major differences between WatC sockets and Windows (WinSock): - In WinSock, use: #include or In Watc, use: #include - In WinSock, you must use functions WSAStartup and WSACleanup to initialize and deinitialize WinSock. No similar functions are needed in WatC. - In Winsock, a socket descriptor number (e.g. as returned by the socket() function) should be declared as type SOCKET, which is unsigned int, and you test for an error from socket() by testing for value INVALID_SOCKET. In WatC, a socket number is signed int, and any negative value indicates an error. Socket numbers in WatC are small integers; in WinSock they may be much larger integers. - In WinSock, use function name closesocket instead of close. - In WinSock, if you want to use errno as in WatC, define it as a macro by the following statement: #define errno (WSAGetLastError()) - In WinSock, error names are prefixed by WSA. For example, use WSAENOTCONN instead of ENOTCONN. - In Winsock, the internal implementation of the socket sets for the select() function is different. Winsock (but not MUSIC/SP, even under Sim390) uses a list of socket numbers instead of a bit mask. There are some different requirements for the arguments of select(). See the description of select(). - - - - - 8. Socket Functions ------------------- accept/ACCEPT Accept() is used by a server to complete a connection with a client. It assigns a new socket number (ns) to the connection and fills in the client's network address in the fields provided. If there are no pending connections accept() will block until one occurs unless nonblocking mode is in effect. The select() routine can be used to test for pending connections prior to issuing a blocking accept(). Once the accept() is complete the server can accept subsequent connections on the same socket (s). Before calling accept(), a server program normally calls bind() to specify a port number, and listen(). ns = accept(s, name, namelen) ns - New socket number assigned to the connection s - Original socket number created by the server name - (Out) The port number and network address of the connecting client (i.e. the remote process). This is in the form of a 16-byte socket address structure described above. namelen - (In/Out) The length of the name. Should be 16. Note: The namelen arg is In/Out, therefore a variable must be used. Before the call, the caller sets it to 16 (the length of name area). On return, the routine sets it to 16 (the length of the returned info in name). Theoretically, the caller may set namelen to a value other than 16 before the call, but this should be avoided. If an error occurs ns is set to a negative value. Common errors are: EBADF -9 : s is not a valid socket descriptor number EINVAL -22 : listen() was not called EMFILE -24 : system socket table is full EWOULDBLOCK -35 : nonblocking mode with no connections pending EOPNOTSUPP -45 : s is not a stream socket bind/BIND Bind() defines the local network address and port number that is to be associated with a specific socket. Normally the local IP address is specified as 0.0.0.0 (x'00000000') (INADDR_ANY), which means that any of the machine's local IP addresses can be used. For Sim390, the special address 127.0.0.1 (localhost) is treated the same as if 0.0.0.0 is specified. rc = bind(s, name, namelen) rc - Return code. 0 if successful bind. s - Original socket number created by the server name - The port number and network address to bind to namelen - The length of the name Common errors: EBADF -9 : s is not a valid socket descriptor number EADDRNOTAVAIL -49 : address is not available or invalid EAFNOSUPPORT -47 : address family is not supported EADDRINUSE -48 : address is currently in use EINVAL -22 : socket is already bound to an address close/CLOSE This shuts down the socket, frees all resources associated with it and closes the TCP connection. The socket number is released. Note: In Windows Sockets (WinSock), the function name is closesocket. rc = close(s) rc - Return code. 0 if successful close. s - Socket number Common errors: EBADF -9 : s is not a valid socket descriptor number connect/CONECT With stream sockets connect() is used by client applications to connect to servers. The server must have set up a passive open at the other end by issuing bind() and a listen() before the connect() is issued. The server should respond with an accept() to complete the connection. In blocking mode the connect() blocks until the connection is established or an error occurs. In nonblocking mode, EINPROGRESS (-36) is returned, but the connect operation continues; select() must be used to determine when the connection is actually complete; if the connection is successful, the socket shows up in the write list of select(); if an error occurs, the socket shows up in the exception list. Connect() can also be used with UDP sockets to establish peer. This basically allows the caller to send datagrams using calls like read() and write() that have no room to specify a remote address. In other words connect() simply defines a default remote address. rc = connect(s, name, namelen) rc - Return code. 0 if successful connection. s - Socket number name - The port number and network address of the server to connect to. namelen - The length of the name. Normally 16. Common errors: EBADF -9 : s is not a valid socket descriptor EINVAL -22 : namelen argument is invalid EINPROGRESS -36 : connection is in progress (nonblocking mode). This is not considered to be an error. This occurs on a nonblocking-mode socket when the connection is not immediate; the connect operation continues in the background. EALREADY -37 : previous connection has not completed EAFNOSUPPORT -47 : address family is not supported EADDRNOTAVAIL -49 : cannot reach the remote host ENETUNREACH -51 : remote network cannot be reached EISCONN -56 : socket is already connected ETIMEDOUT -60 : connection timed out ECONNREFUSED -61 : remote host rejected the connection EHOSTUNREACH -65 : remote host cannot be reached fcntl/FCNTL Fcntl() is used to control whether a socket operates in blocking or nonblocking mode. In blocking mode (the default) the application does not receive control back from the subroutine until the operation is complete. For example if a program issues a read() it is stopped (blocked) until some data actually arrives on the socket. In non- blocking mode an error (EWOULDBLOCK) is given in response to the read() if no data is present. rc = fcntl(s, cmd, data) rc - Return code. A 0 or positive value indicates success. s - Socket number cmd - Indicates what to do data - Data depending on cmd The are currently three possible calls.... rc = fcntl(s, 4, 4) : put socket into nonblocking mode. rc = fcntl(s, 4, 0) : put socket into blocking mode. rc = fcntl(s, 3, 0) : rc is set to 4 if socket is nonblocking, or to 0 if socket is in blocking mode. Common errors: EBADF -9 : s is not a valid socket descriptor EINVAL -22 : 2nd or 3rd arg is an invalid value. getclientid/GCLNID This routine is used to find out the client ID by which an application is known to TCPIP. It is used in passing sockets from one application to another through the givesocket() and takesocket() routines. The 40-byte clientid structure is described in the Data Structures section above. Note: This function is specific to VM and MUSIC/SP, and is not available in Windows (WinSock) or Unix. rc = getclientid(domain, clientid) rc - Return code. 0 if successful. domain - (In) Caller sets this to 2 for AF_INET clientid - (Out) If the call is successful, the clientid is returned in this 40-byte area. Common errors: EPFNOSUPPORT -46 : domain is not AF_INET (2) gethostid/GHSTID This returns the default internet address for the host running the application that calls the routine. On Sim390, the special IP address 127.0.0.1 (x'7F000001') (localhost, INADDR_LOOPBACK) is returned. Note: This function is specific to VM and MUSIC/SP, and is not available in Windows (WinSock) or Unix. id = gethostid() id - 32 bit internet address (in network byte order) Common errors: (no name) -999 : Connection to IUCV failed because the MUSIC job does not have the SYSCOM privilege or some other IUCV error occurred. This error number is indistinguishable from the IP address 255.255.252.25 (x'FFFFFC19'). gethostname/GHSTNM This returns the name of the host running the calling application. Note, this is the actual character name, not the port number/ internet address combination that are referred to in other calls as the name. On Sim390, the special name "LOCALHOST" is returned. rc = gethostname(name, namelen) rc - Return code. 0 indicates success. name - (Out) The returned name of the host. The name is truncated or extended with x'00' bytes, to match the length specified in namelen. namelen - (In) The size of the name buffer. Common errors: (no name) -999 : Connection to IUCV failed because the MUSIC job does not have the SYSCOM privilege or some other IUCV error occurred. getpeername/GPRNM This routine retrieves the name of the remote host. The name contains the port number and internet address. rc = getpeername(s, name, namelen) s - (In) Socket number name - (Out) The port number and network address of the application that the caller is connected to. namelen - (In/Out) The length of the name. Should be 16. This argument must be a variable, not a constant. The caller sets it to the length of the area for the name argument. The function sets it to the number of bytes moved into the name area. Theoretically, the input value could be different from 16, but this should be avoided. Common errors: EBADF -9 : s is not a valid socket ENOTCONN -57 : the socket is not connected. For example, for a UDP socket for which a call to connect() has not been done, getpername() gives this error, even after a call to sendto(). getsockname/GSCKNM This routine retrieves the name associated with the local socket. This contains the port number and internet address of the local side of the connection. rc = getsockname(s, name, namelen) s - Socket number name - (Out) The port number and network address of the application that the caller is connected to. namelen - (In/Out) The length of the name. Should be 16. This argument must be a variable, not a constant. The caller sets it to the length of the area for the name argument. The function sets it to the number of bytes moved into the name area. Theoretically, the input value could be different from 16, but this should be avoided. Common errors: EBADF -9 : s is not a valid socket EINVAL -22 : local socket info is not available, e.g. because there is no current connection and bind() was not used getsockopt/GSCKOP This is used to get the options associated with a particular socket. This function is not supported in Sim390 (gives rc=-1000). rc = getsockopt(s, level, optname, optval, optlen) s - Socket number. level - Set to x'0000ffff' for sockets. optname - Integer indicating which option to get. See setsockopt() for a list of valid values. optval - (Out) The value returned for that option. optlen - (In/Out) The length of the option value. In a Fortran call, this argument must be a variable, not a constant, since it is changed by the function. If an error occurs rc is set to a negative value. Common errors are: EBADF -9 : s is not a valid socket descriptor ENOPROTOOPT -42 : optname is invalid (no name) -1000 : (Sim390) This socket function is not supported givesocket/GIVESK This is used to pass a socket to another application. For a complete discussion of the givesocket() and takesocket() routines see the comments in the files $TCP:INETD.S and $TCP:GETSOC.S . They explain the steps that must be taken to start up a new task and pass a socket on to it. The socket should not be closed until the other task has successfully acquired it using the takesocket() routine. Note: This function is specific to VM and MUSIC/SP, and is not available in Windows (WinSock) or Unix. rc = givesocket(s, clientid) rc - Return code. 0 indicates success. s - The socket number to be given to the the other task. clientid - The client ID of the task that you wish to give the socket to. The 40-byte clientid is described in the Data Structures section above. The subtaskid in the clientid specifies the MUSIC task (IUCV path) that will be allowed to take the socket. Common errors: EBADF -9 : s is not a valid socket descriptor EBUSY -16 : listen() has been called for the socket EINVAL -22 : clientid does not specify a valid client ID ENOTCONN -57 : the socket is not connected EOPNOTSUPP -45 : s is not a stream socket inet_addr (Waterloo C only) This function is available only in Waterloo C sockets; for other environments, use MUSIC-specific function cvip2x or cnvd2x. Prototype: unsigned long inet_addr(char *str); Converts an IP address in character dotted decimal form, as a null-terminated string, to 32-bit binary form (in network byte order). The return value is suitable to be stored into a sockaddr_in structure. Example: struct sockaddr_in saddr; saddr.sin_addr.s_addr=inet_addr("132.206.120.4"); The string must be of the form "a.b.c.d", where each of the 4 parts is 1 to 3 decimal digits, each part value is 0 to 255, and a part with a nonzero value must not have leading 0 digits. If the input string is invalid, return value is 0xFFFFFFFF = INADDR_NONE. errno is not changed. inet_ntoa (Waterloo C only) This function is available only in Waterloo C sockets; for other environments, use MUSIC-specific function cnvx2d. Prototype: char *inet_ntoa(struct in_addr inaddr); Converts a 32-bit IP address (in network byte order) to standard character dotted decimal form, as a null-terminated string, and returns a pointer to the string as the function return value. No error conditions. Maximum string length is 15 = 4*3 + 3. Example: struct in_addr ia={0x01020304}; ptr=inet_ntoa(ia); This returns a pointer to the string "1.2.3.4". (On a Little-Endian machine like an Intel PC, the string would be "4.3.2.1". IBM mainframes where WatC runs are Big_Endian.) NOTE: The memory area for the string is allocated in a static area, and the caller should copy the string to his own area if he needs to refer to it later. The contents of the returned area is guaranteed to be preserved only until the next call to any socket function. ioctl/IOCTL Ioctl() provides access to the operating characteristics of the socket. This function is not supported in Sim390 (rc=-1000). This function currently is not used by any MUSIC/SP system utilities. To set a socket to blocking or nonblocking mode, use fcntl(). rc = ioctl(s, cmd, data) rc - Return code. 0 indicates success. s - Socket number. cmd - (In) The command to perform. data - (In/Out) Information passed or returned. Its length depends on cmd. In a Fortran call, this argument must be a variable, not a constant, since its value is changed by the function. Common errors: (no name) -1000 : (Sim390) This socket function is not supported The following table lists the supported requests... Name Value (HEX) Function ---- ----------- -------- FIONBIO 8004A77E Clear or set nonblocking mode. Data=0 to clear, 1 to set. FIONREAD 4004A77F Returns number of byte available for reading in data. SIOCATMARK 4004A707 Queries if current data is out of band. Data=1 if yes, 0 if no SIOCGIFADDR C020A70B Gets network interface address. Data=IFREQ SIOCGIBRDFADDR C020A712 Gets network interface broadcast address. Data=IFREQ SIOCGIFCONF C008A714 Gets network interface configuration. On input data should be set to the length of the output area. On output it will have an IFREQ structure for each interface. SIOCGIFDSTADDR C020A70F Gets network interface destination address. Data=IFREQ SIOCGIFFLAGS C020A711 Gets network interface flags. Data=IFREQ SIOCGIFNETMASK C020A715 Gets network interface mask. Data=IFREQ The IFREQ structure that is returned has a 16 byte request name followed by the requested information. listen/LISTEN Listen() is used by a server to indicate it is ready to accept calls from clients. rc = listen(s, backlog) rc - Return code. 0 indicates success. s - Socket number. backlog - Length of pending connection queue. Usually 1 to 5. Common errors: EBADF -9 : s is not a valid socket descriptor EOPNOTSUPP -45 : s is not a stream socket read/READ This call reads data from a connected socket. The number of bytes read is returned in the return code (rc). In blocking mode this call will block until some data becomes available. In both blocking and nonblocking mode, the number of bytes actually read (rc) may be less than the buffer length (a partial read). rc=0 on a stream socket indicates EOF (End of File): the remote side has shutdown the connection gracefully, and all data has been received. read() is equivalent to recv() with flags argument 0. Note: read() is not available on Windows (WinSock); use recv(). rc = read(s, buf, len) rc - Return code. <0: error. 0: EOF, >0: # of bytes read. s - Socket number. buf - (Out) Buffer to receive the data. len - Buffer length. Must be > 0. For MUSIC/SP, the maximum length is 32744 = 2**15 - 24, because the maximum number of 512-byte system buffers that can be used is 64. (The value 24 is for overhead bytes in the IUCV Sockets API call.) Common errors: EBADF -9 : s is not a valid socket descriptor EINVAL -22 : invalid argument, including a call with len=0 EWOULDBLOCK -35 : set in nonblocking mode if no data to read readv/READV This call is similar to the read() except that the data is read into a group of buffers pointed to by an I/O vector structure. Each entry in the I/O vector contains a buffer address and a length. The buffers are filled in order. Note: readv is not available on Windows (WinSock). rc = readv(s, iov, iovcnt) rc - Return code. <0: error. 0: EOF, >0: # of bytes read. s - Socket number. iov - I/O vector containing buffer address / length pairs iovcnt - Number of entries in the iov. Note: The total data length (the sum of the lengths in iov) must be from 1 to 32744. See READ. Common errors: EBADF -9 : s is not a valid socket descriptor EWOULDBLOCK -35 : set in nonblocking mode if no data to read recv/RECV This receives data from a connected socket. The return code (rc) is set to the number of bytes received. It is very similar to read() except for allowing certain flags to be set. On a blocking-mode socket, the call will block until some data becomes available. In both blocking and nonblocking mode, the number of bytes actually read (rc) may be less than the buffer length (a partial read). rc=0 on a stream socket indicates EOF (End of File): the remote side has shutdown the connection gracefully, and all data has been received. rc = recv(s, buf, len, flags) rc - Return code. <0: error. 0: EOF, >0: # of bytes read. s - Socket number. buf - (Out) Buffer to receive the data. len - Buffer length. Must be > 0. Max len is 32744 (see READ). flags - Flag value of MSG_OOB (1) or MSG_PEEK (2) Common errors: EBADF -9 : s is not a valid socket descriptor EINVAL -22 : invalid argument, including a call with len=0 EWOULDBLOCK -35 : set in nonblocking mode if no data to read recvfrom/RECVFM This receives data from a datagram socket. The return code (rc) is set to the number of bytes received. rc = recvfrom(s, buf, len, flags, name, namelen) rc - Return code. <0: error. 0: EOF, >0: # of bytes read. s - Socket number. buf - (Out) Buffer to receive the data. len - Buffer length. Must be > 0. Max is 32744 (see READ). flags - Flag value of MSG_OOB (1) or MSG_PEEK (2) name - (Out) Port number and network address of the sending application. namelen - (In/Out) Length of name. Should be 16. This argument must be a variable, not a constant. The caller sets it to the length of the area for the name argument. The function sets it to the number of bytes moved into the name area. Theoretically, the input value could be different from 16, but this should be avoided. Common errors: EBADF -9 : s is not a valid socket descriptor EWOULDBLOCK -35 : set in nonblocking mode if no data to read recvmsg/RECVMG This function is similar to recvfrom, except it uses a msghdr structure instead of individual arguments, and (similar to readv) it allows the received data to be read into multiple buffer areas in memory. Note: recvmsg is not available on Windows (WinSock). rc = recvmsg(s, msg, flags) rc - Return code. Same as for recv and recvfrom. s - Socket number. msg - A msghdr structure. (In C, the argument is a pointer to a msghdr structure.) The structure has the following elements: msg_name Address of a memory area which receives the Internet address info of the sender. If this element is 0, no address info or address length is returned. msg_namelen (In/Out, int*4) The size of the memory area for the Internet address info of the sender. Normally the caller sets this to 16, and the function returns it as 16. msg_iov Address of a list of (address,length) pairs specifying the buffer areas into which the data is to be read. Note: The total data length (the sum of the lengths in msg_iov) must be 1 to 32744 (see READ). msg_iovlen The number of (address,length) pairs in msg_iov. msg_accrights Address of access rights. (Not used.) msg_accrightslen Length of access rights. (Not used.) flags - (In) Same as for recv and recvfrom. select/SELECT The select() routine is used to wait for an interrupt from the socket interface and to determine which socket caused the interrupt. It is used to wait for connections to come and for data to arrive. It is usually used by applications that field interrupts from a variety of sources or handle a number of different sockets and can't afford to get into a blocking situation. The select() is used to test in advance for an event before issuing the socket call to handle that event. Select() can test a set of sockets for reading, writing, and exceptional conditions. Reading implies that data is available and a read() or recv() call will not block. Writing implies that the socket can be written to without blocking. Exceptional conditions are events like out-of-band data or a connection error. Special cases: (1) For a server socket that is in listening mode, waiting for an incoming connection request, "ready for reading" means that a connection has arrived, and an accept() call will not block. (2) For a client socket (in non-blocking mode) that has called connect() to connect to a server, "ready for writing" means the connection has succeeded. Data can be sent to the socket without blocking (up to the size of the outgoing network buffer in the underlying TCP/IP system). If select says the socket has tested positive for exceptional conditions, that means the connection attempt failed. (3) If an established connection has been closed or reset or terminated, the socket is considered to be "ready for reading", and will satisfy the select() if included in the read mask. Three bit masks are used to specify which sockets should be tested. On output, the return code (rc) is set to the number of sockets that have pending conditions, and the bits are set in the masks to indicate which sockets they are, and all other bits in the masks are set to zero. The bit masks are organized into 32-bit words that are counted from the low order end. Socket number 0 is represented by the low-order bit of the first word, etc. +-------------++--------------+ | word 0 || word 1 | ... +-------------++--------------+ | | | | 31 0 63 32 <--- socket number In Waterloo C sockets: Select masks can be created and manipulated using the standard Windows (WinSock) and Unix fd_set type and macros FD_SETSIZE, FD_ZERO, FD_SET, FD_CLR, FD_ISSET. The default size for an fd_set object is 256 sockets, but a different size can be specified by defining macro FD_SETSIZE before #include . These macros should always be used in C, since some systems (including Windows WinSock) implement the select masks differently e.g. not as bit masks, or as bit masks with a different internal format. rc = select(nfds,readfds,writefds,excptfds,timeout) rc - Return code. <0: error. 0: timeout, no sockets found. >0: the number of sockets found. nfds - Maximum number of sockets to test. Normally nfds is 1 + (the highest socket number in the input bit masks), but it can be higher than that. nfds may be 0, in which case select() will always time out. For efficient processing of the bit masks, it is best to keep nfds as small as possible. For Sim390, nfds must not exceed 1024 (which corresponds to a bit mask length of 128 bytes). NOTE: Difference from Winsock: In Windows (but not MUSIC/SP including Sim390) the nfds value is ignored, since Winsock implements select() differently, internally. readfds - (In/Out) Bit mask for read. If the address of this argument in the argument list is 0 (NULL), there is no read mask. NOTE: Use of a 0 (NULL) address in the arg list is not possible when the function is called from Fortran. NOTE: Difference from Winsock: In Windows (but not MUSIC/SP including Sim390), a non-NULL mask arg (readfds, writefds, or excptfds) must contain at least one socket number. This means that, in Winsock, if a set is empty, NULL must be used for that arg. Also, in Winsock, the 3 set arguments must not all be NULL. writefds - (In/Out) Bit mask for write. If the address of this argument in the argument list is 0 (NULL), there is no write mask. excptfds - (In/Out) Bit mask for exceptional conditions. If the address of this argument in the argument list is 0 (NULL), there is no exceptions mask. timeout - Timeout value (integer seconds, integer microseconds), as an array of 2 integer values. Usually the number of microseconds (the 2nd element of the array) is specified as 0. The resulting value ( timeout(1) + (timeout(2)/1000000.) seconds) is the approximate maximum amount of time that select() will wait. The timeout value may be 0, in which case the function tests the sockets and returns immediately, without waiting. If the address of the timeout argument in the argument list is 0 (NULL), an unlimited timeout value is used, and select() will wait indefinitely. NOTE: Since, on MUSIC/SP, the timeout wait is only approximate, select() should not be used as an accurate timer. Common errors: EBADF -9 : one of the descriptor sets is invalid EFAULT -14 : invalid memory address, or memory access error EINVAL -22 : the timeout value is invalid (no name) -1001 : (Sim390) nfds is too large, or some other value error (no name) -1006 : (Sim390) A previous select is still in progress (no name) -(2000+n) : A non-socket interrupt occurred (n is 0 to 9). The caller may wish to redo the select call. send/SEND This sends data to a connected socket. Return value rc is the number of bytes actually written to the socket. A call to send with flags=0 is equivalent to a call to write. rc = send(s, buf, len, flags) rc - Return code. <0 indicates an error. >0 indicates success, and is the number of bytes sent, which may be less than len if the socket is in nonblocking mode. rc=0 should not occur except if len=0. s - Socket number buf - Buffer containing the data len - Length of the data. Should be > 0. For MUSIC/SP, the maximum length is 32748 = 2**15 - 20. (The value 20 is for overhead bytes in the IUCV Sockets API call.) If len=0, no bytes are sent and rc=0 results. flags - Option flags. Valid values are MSG_OOB (1) and MSG_DONTROUTE (4) See the implementation note in the section "Blocking and Nonblocking Mode". Common errors: EBADF -9 : s is not a valid socket descriptor EWOULDBLOCK -35 : set in nonblocking mode if the socket can not accept any data at this time ENOBUFS -55 : insufficient buffer space to send the data sendmsg/SENDMG This function is similar to sendto, except it uses a msghdr structure instead of individual arguments, and (similar to writev) it allows the sent data to be in multiple buffer areas in memory. Note: sendmsg is not available on Windows (WinSock). rc = sendmsg(s, msg, flags) rc - Return code. Same as for send and sendto. s - Socket number. msg - A msghdr structure. (In C, the argument is a pointer to a msghdr structure.) The structure has the following elements: msg_name Address of a memory area which contains the Internet address info of the application the data is being sent to. If this element is 0, no address info or address length is specified (equivalent to a send call). msg_namelen (In, int*4) The size of the memory area for the Internet address info of the receiver. Normally the caller sets this to 16. msg_iov Address of a list of (address,length) pairs specifying the buffer areas containing the data to be sent. Note: The total data length (the sum of the lengths in msg_iov) must be 0 to 32748 (see SEND). msg_iovlen The number of (address,length) pairs in msg_iov. msg_accrights Address of access rights. (Not used.) msg_accrightslen Length of access rights. (Not used.) flags - (In) Same as for send and sendto. sendto/SENDTO Used to send packets on a datagram socket. Return value rc is the number of bytes actually written to the socket. rc = sendto(s, buf, len, flags, name, namelen) rc - Return code. <0 indicates an error. s - Socket number buf - buffer containing the data to be sent. len - length of the data to be sent. Must be 0 to 32748 (see SEND). flags - Option flags. Valid option is MSG_DONTROUTE (4). name - The port number and internet address of the application that you are sending to. namelen - The length of the name. Normally 16. Common errors: EBADF -9 : s is not a valid socket descriptor EINVAL -22 : namelen is invalid EWOULDBLOCK -35 : set in nonblocking mode if the socket can not accept any data at this time EMSGSIZE -40 : the message is too big to be sent as a single datagram. ENOBUFS -55 : No buffer space available to do send setsockopt/STSKOP This sets various options associated with a socket. It allows you to control broadcast messages, out of band data, and tell the socket interface how to handle the close and bind operations. This function is not supported in Sim390 (gives rc=-1000). To set a socket to blocking or nonblocking mode, use fcntl(). rc = setsockopt(s, level, optname, optval, optlen) rc - Return code. <0 indicates an error. s - Socket number. level - Protocol level (set to x'0000ffff' for socket level) optname - Option name optval - (In) Option value optlen - (In) Option length Common errors: (no name) -1000 : (Sim390) This socket function is not supported The following table of lists the supported options. This list also applies to the getsockopt() routine. For those calls that toggle an option on or off, optval=1 sets it on and optval=0 sets it off. In both cases optlen should be set to 4. For SO_LINGER, optlen is 8. Name Description ---- ----------- SO_BROADCAST X'00000020' Toggle broadcast on or off. SO_OOBINLINE X'00000100' Toggle reception of out of band data. If on, out of band data is placed in the normal input queue. SO_REUSEADDR X'00000004' Toggle address reuse. Setting this on forces bind() to reuse an address SO_LINGER X'00000080' Causes interface to linger on close() if data remains to be sent. optval consists of two fullwords. The first one is a toggle. The second is the number of seconds to wait. shutdown/SHUTDN This shuts down all or part of a socket connection. The socket itself is not closed. rc = shutdown(s, how) rc - Return code. <0 indicates an error. s - Socket number how - 0 (SD_RECEIVE): ends communication from socket 1 (SD_SEND): ends communication to socket 2 (SD_BOTH): ends all communication with socket socket/SOCKET This routine creates a socket and assigns the socket number (s). IUCV may limit the number of sockets that may be created per path. s = socket(domain, type, protocol) s - Return code. <0: error. 0 or more: the socket number of the created socket. domain - Set to 2 for the AF_INET domain (Internet). type - Type of socket. 1=stream (SOCK_STREAM), 2=datagram (SOCK_DGRAM), or 3=raw (SOCK_RAW). (Type raw is used for ICMP, e.g. Ping.) protocol - Protocol to use or 0. Usually 0. If 0, the default protocol for the specified type is used: TCP for stream type, UDP for datagram type. Common errors: EMFILE -24 : system socket table is full EPROTOTYPE -41 : protocol is wrong for specified type EPROTONOSUPPORT -43 : protocol not supported ESOCKTNOSUPPORT -44 : socket type is not supported for the specified domain EAFNOSUPPORT -47 : address family (domain) is not supported ENOBUFS -55 : insufficient buffer space or unable to allocate a buffer (no name) -999 : Connection to IUCV failed because the MUSIC job does not have the SYSCOM privilege or some other IUCV error occurred. takesocket/TAKESK This is used by a program receiving a socket from another program. See the description of the givesocket() function. The subroutine GETSOC performs the handshaking required to get a socket from another program, including issuing the takesocket() call. For further details see the comments in $TCP:GETSOC.S and $TCP:INETD.S . Note: This function is specific to VM and MUSIC/SP, and is not available in Windows (WinSock) or Unix. s = takesocket(clientid, hisdesc) s - Return code. A negative value indicates an error. A nonnegative values indicates success, and is the resulting new socket number by which the caller can refer to the taken socket. clientid - The client ID of the application giving the socket. The 40-byte clientid is described in the Data Structures section above. hisdesc - The socket number used in the application giving the socket. It specifies the socket number to be taken. Common errors: EBADF -9 : hisdec is not a socket owned by the other program, or the other program did not give it EACCES -13 : the other application did not give the socket EINVAL -22 : clientid does not specify a valid client EMFILE -24 : system socket descriptor table is full EPFNOSUPPORT -46 : domain field of the clientid is not AF_INET (2) ENOBUFS -55 : TCP/IP has run out of socket control blocks write/WRITE This writes data to a connected socket. Return value rc is the number of bytes actually written to the socket. write() is equivalent to send() with flags argument 0. Note: write() is not available on Windows (WinSock); use send(). rc = write(s, buf, len) rc - Return code. <0 indicates an error. >0 indicates success, and is the number of bytes sent, which may be less than len if the socket is in nonblocking mode. rc=0 should not occur except if len=0. s - Socket number buf - Buffer containing the data len - Length of the data to be written. Should be > 0. For MUSIC/SP, the maximum length is 32748 = 2**15 - 20. (20 is for overhead in the IUCV Sockets API call.) If len=0, no bytes are sent and rc=0 results. See the implementation note in the section "Blocking and Nonblocking Mode". Common errors: EBADF -9 : s is not a valid socket descriptor EWOULDBLOCK -35 : set in nonblocking mode if the socket can not accept any data at this time ENOBUFS -55 : no buffer space for write writev/WRITEV This call is similar to the write() except that the data is written from a group of buffers pointed to by an I/O vector structure. Each entry in the I/O vector contains a buffer address and a length. Note: writev is not available on Windows (WinSock). rc = writev(s, iov, iovcnt) s - Socket number. iov - I/O vector containing buffer address / length pairs iovcnt - Number of entries in the iov. Note: The total data length (the sum of the lengths in iov) must be from 0 to 32748. See SEND. Common errors: EBADF -9 : s is not a valid socket descriptor EWOULDBLOCK -35 : set in nonblocking mode if the socket can not accept any data at this time ENOBUFS -55 : no buffer space for write 9. MUSIC/SP-Specific Functions ------------------------------ The following routines are specific to the implementation of the socket interface on MUSIC/SP. a2e/A2E (In WatC use: musa2e) Converts ASCII to EBCDIC. Note that the default representation for character data on the internet is ASCII whereas IBM mainframes tend to use EBCDIC. (MA2E routine is preferred.) call a2e(buf,len) buf - (In/Out) Buffer containing ASCII data len - Number of characters in the buffer. No action if len <= 0. cnvd2x/CNVD2X (Not available in WatC) Converts a dotted decimal character format Internet address to a 32 bit binary number. For example 132.206.120.2 is converted to X'84CE7802'. See $tcp:convad.s . See also cvip2x function below. This function is not available in Waterloo C sockets; use the standard function inet_addr instead. call cnvd2x(daddr,xaddr) daddr - (In) Character format dotted decimal IP address terminated by a blank. It must be in 4 parts, separated by periods. Each part must be 1 to 3 decimal digits, without leading zeros (except when the part value itself is 0) and have a value from 0 to 255. Note: Currently, for compatibility reasons, the requirement of no leading 0 digits is not enforced. The cvip2x function (see below) does enforce it. Some other systems use a leading zero to indicate octal. xaddr - (Out) 32 bit binary internet address. If the input is invalid, 4 bytes of zeros are stored here (equivalent to input '0.0.0.0 '). Return value: none Examples: call cnvd2x('127.0.0.1 ',n) sets n to hex 7F000001 call cnvd2x('132.206.3.300 ',n) sets n to 0 (bad input) cnvx2d/CNVX2D (Not available in WatC) Converts a 32 bit binary internet address to the dotted decimal character format. For example X'84CE7802' is converted to '132.206.120.2 '. See $tcp:convad.s . The output string is always 16 characters long, blank padded on the right. This function is not available in Waterloo C sockets; use the standard function inet_ntoa instead. call cnvx2d(xaddr,daddr) xaddr - (In) 32 bit binary internet address. daddr - (Out) 16 character decimal address, with trailing blanks. The area provided by the caller must be 16 bytes long. Return value: none Example: integer ipaddr/z84CE7802/ character decip*16 call cnvx2d(ipaddr,decip) Sets decip to '132.206.120.2 ' cvip2x/CVIP2X (Not available in WatC) This function converts an IP address in dotted decimal character form (blank-terminated) to a 32-bit 4-byte integer value, and gives a return value indicating whether the input is valid. It is the same as cnvd2x, except: (1) It is a function that returns a value, and (2) It considers any leading 0 digits in any of the 4 parts (except when the part has value 0) to be an error. This function is not available in Waterloo C sockets; use the standard function inet_addr instead. rc = cvip2x(daddr,xaddr) daddr - (In) IP address as a blank-terminated character string, in dotted decimal form a.b.c.d where each of the 4 parts is 1 to 3 decimal digits, value 0 to 255, without leading 0 digits (except when the part's value is 0, in which case leading 0's are allowed). xaddr - (Out) 32-bit integer area, to receive the 4-byte hex IP address. If the input is invalid, xaddr is set to 0. Return value: rc = 0 No error, input is valid. rc = -1 Error, input is invalid, xaddr is set to 0. Examples: rc=cvip2x('255.2.00.4 ',n) sets rc=0, n=x'FF020004'. rc=cvip2x('255.2.03.4 ',n) sets rc=-1, n=0 (error). e2a/E2A (In WatC use: muse2a) Convert EBCDIC to ASCII. Note that the default representation for character data on the internet is ASCII whereas IBM mainframes tend to use EBCDIC. (ME2A is preferred.) call e2a(buf,len) buf - (In/Out) Buffer containing EBCDIC data len - Number of characters in the buffer. No action if len <= 0. e2e/E2E (Not available in WatC) This removes control characters from an EBCDIC character string. Control characters are converted to blanks. Printables are left as is. call e2e(buf,len) buf - (In/Out) Buffer containing EBCDIC data len - Number of characters in the buffer. No action if len <= 0. getcon/GETCON (Not available in WatC) This routine is used by a server application to wait for a connection on a specific port. It supports only one connection on the port and is intended to be used in debugging servers that would normally be run in the background by INETD. This allows the server to establish a connection without intervention of INETD and thus be debugged as a foreground task. Usually once the server has been debugged this call would be replaced by a call to getsoc() and the server would be set up to run under INETD. See $tcp:getcon.s . Note: This function is not provided in WatC sockets. s = getcon(port) s - Socket number assigned to connection. port - Port number getsoc/GETSOC (In WatC use: mugetsoc) This routine used by a server application that has been invoked by INETD, to get the socket passed from INETD. It automatically handles the protocol to successfully transfer a socket from one application to another, using the GIVESK() and TAKESK() routines. See $tcp:getsoc.s . Name in Waterloo C sockets: mugetsoc. WatC prototype: int mugetsoc(void); s = getsoc() s - Socket number of passed socket. Common errors: EBADF -9 : (Error from TAKESK routine) EINVAL -22 : (Error from TAKESK routine) (no name) -2002 : Bad /PARM field received from INETD (no name) -2003 : ENQ limit checking failed (no name) -5000 : XSAY or XHEAR error; possible time-out gtport/GTPORT This function gets a unique port number from the system that can be used to create a unique port-number/internet-address combination that is referred to as the socket name. It can be used to get a temporary port number. MUSIC/SP implements GTPORT by a system-wide counter (sequence) which is reset only when MUSIC/SP is IPL'd. NOTE: If more than 1 MUSIC/SP system is running under the same VM or mainframe emulator (e.g. Sim390), it is possible that gtport calls on different MUSIC/SP systems may return the same number, since each system has its own sequence. In that case, the port number would not be unique within the entire machine, and the application should be prepared to handle errors such as EADDRINUSE from bind(). A better method is to use special port number 0 in the bind() call, which causes the underlying TCP/IP system to assign an actual port number which is unique within the machine. After bind(), the application can use getsockname() to get the actual socket number assigned. On most systems, including Sim390 on Windows, the port number assigned by bind() is in the range 1025 to 5000. num = gtport() num - unique port number between 11001 and 30000 (or between 4001 and 32000 on some older MUSIC/SP systems). intsel/INTSEL This routine toggles a flag (value 0 or 1) which determines which types of MUSIC/SP (non-socket) interrupts can terminate a select() wait. If the flag is 0, INTSEL changes it to 1; if 1, it changes it to 0. The routine returns the new value of the flag, in the output argument. At the start of the program, the flag is 0. During a select() wait, if the flag is 1, all types of non-socket interrupts (attn, multi, msg, async, etc.) terminate the select. If the flag is 0 (which is the default initial value), the "multi" type of interrupt does not terminate select but the other types do. call intsel(flgout) flgout - (Out; int*4) The new value, 0 or 1, of the flag is returned here. ma2e/MA2E (In WatC use: musa2e) Converts data from ASCII to EBCDIC. The translation is 1-to-1 among all the 256 possible character codes, and it can be undone exactly by the ME2A routine. Name in Waterloo C sockets: musa2e. call ma2e(buf,len) buf - (In/Out) Buffer containing the data len - Number of characters in the buffer. No action if len <= 0. me2a/ME2A (In WatC use: muse2a) Converts data from EBCDIC to ASCII. The translation is 1-to-1 among all the 256 possible character codes, and it can be undone exactly by the MA2E routine. Name in Waterloo C sockets: muse2a. call me2a(buf,len) buf - (In/Out) Buffer containing the data len - Number of characters in the buffer. No action if len <= 0. mxiuwt/MXIUWT This call specifies the maximum amount of time that the MUSIC/SP application program will wait for IUCV to process and respond to an IUCV Send request for any socket operation. After (approximately) the specified amount of time, the socket operation is terminated with an error code rc = -101. The time is specified as a number of seconds. The initial value is a large value representing unlimited time. Any value 50000 seconds or more (about 13.9 hours) is treated as an unlimited time. The application program can call MXIUWT at any time to change the current timeout value. A server may need to set a large value when waiting for an incoming connection or waiting for data to arrive on a socket, but may choose to set a smaller value (such as 120 seconds) when writing to a socket or waiting to make a connection. call mxiuwt(nsecs) nsecs - Maximum timeout for IUCV response, in seconds. A value of 50000 or more is interpreted as unlimited. resolv/RESOLV (In Watc use: muresolve) Calls a domain name server (DNS) to convert a host name to a 32-bit IP address. See $tcp:resolv.s . If necessary, the IP addresses of the DNS name servers to use are obtained from system file $tcp:tcpip.config (NAMESERV records). If you use the RESOLV routine, at least one DNS server should be defined in $tcp:tcpip.config . Usually the IP addresses of your DNS's are provided by your ISP (Internet Service Provider) or your organization. File $tcp:ip.alias, if it exists, is searched before using a DNS. The host name string must be terminated by a blank. The host name can be up to 250 characters long. An IP address, in dotted decimal character format, followed by a blank (the same format as is input to the CVIP2X routine), can be given instead of a host name, in which case no DNS lookup is required. If a DNS lookup is required, the call may take several seconds to complete. In Waterloo C sockets: the function name is muresolve, and the name is a null-terminated string, instead of blank-terminated. Unlike most other WatC socket functions, muresolve does NOT set errno if an error occurs. The function return value rc indicates the type of error, if it is negative (rc = -1, -2, or -3). WatC prototype: int muresolve(char *name, unsigned long *ipaddr); rc = resolv(hostname,ipaddr) or call resolv(hostname,ipaddr) NOTE: When called from Rexx, the function form (rc=) is not supported. Only the CALL form is supported. rc - Return value. 0 if OK. Negative indicates an error: -1 DNS reports the name does not exist. ipaddr is set to x'FFFFFFFF'. -2 Invalid input. ipaddr is set to 0. -3 DNS is not available or does not respond, or some other network error, or the DNS reports a temporary error or some error other than "name does not exist". The caller should retry later. ipaddr is set to 0. hostname - (In) Character host domain name terminated by a blank. It may also be a numeric IP address, in character dotted decimal form, terminated by a blank. ipaddr - (Out) 32-bit internet address. If the input name is invalid or a DNS error occurs, ipaddr is set to 0; this occurs, for example, if there is no DNS server defined but one is needed, or if the DNS server does not respond. If the DNS reports that the name does not exist, ipaddr is set to -1 (x'FFFFFFFF'). Examples: rc=resolv('www.mcgill.ca ',n) sets rc=0, n=x'84D8B18C' rc=resolv('132.216.177.140 ',n) sets rc=0, n=x'84D8B18C' call resolv('www.mcgill.ca ',n) sets rc=0, n=x'84D8B18C' trsock/TRSOCK This routine turns on socket level tracing (basically detailing the interface between the socket calls and IUCV). Two files are created: $TCP:@TCPIP.LOG, which contains trace records for each socket call, and $TCP:@TCPIP.BUFFERS, which contains the inbound and outbound buffers at the socket level. call trsock Note that no parameters are needed. Errors: none. xpath/XPATH This routine specifies the 8-character TASKID field (subtaskid) that is to be used when connecting the application to TCP/IP. This forms part of the client ID that is used in the givesocket() and takesocket() routines. If used, this routine must be called before any socket routine that requires an IUCV connection to TCP/IP. In Waterloo C, the argument is a string of exactly 8 characters, NOT necessarily null-terminated. call xpath(taskid) taskid - An 8 character string that uniquely identified the task within MUSIC/SP. - - - - - 10. Socket Error Codes ---------------------- An error number n (positive) is returned as a negative return code rc = -n from the socket routine. The error codes include the following. (Note: In WatC sockets, the return value is -1 for an error, in which case errno contains a positive error number, which may be different from the numeric values listed below; see the section on Waterloo C; always use the error name in C coding, not the number.) Standard Unix errors: EPERM 1 Not owner or permission denied ENOENT 2 No such file or directory ESRCH 3 No such process EINTR 4 Interrupted system call EIO 5 I/O error ENXIO 6 No such device or address E2BIG 7 Arg list too long ENOEXEC 8 Exec format error EBADF 9 Bad file number or socket number ECHILD 10 No children EAGAIN 11 No more processes ENOMEM 12 Not enough memory EACCES 13 Permission denied EFAULT 14 Bad memory address or memory access error ENOTBLK 15 Block device required EBUSY 16 Device busy EEXIST 17 File exists EXDEV 18 Cross device link ENODEV 19 No such device ENOTDIR 20 Not a directory EISDIR 21 Is a directory EINVAL 22 Invalid argument ENFILE 23 File table overflow EMFILE 24 Too many open files or sockets ENOTTY 25 Not a typewriter or inappropriate device call ETXTBSY 26 Text file busy EFBIG 27 File too large ENOSPC 28 No space left on device ESPIPE 29 Illegal seek EROFS 30 Read-only file system EMLINK 31 Too many links EPIPE 32 Broken pipe EDOM 33 Domain error (argument out of range) ERANGE 34 Range error EWOULDBLOCK 35 Operation would block EINPROGRESS 36 Operation now in progress EALREADY 37 Operation already in progress ENOTSOCK 38 Socket operation on a non-socket handle EDESTADDRREQ 39 Destination address required EMSGSIZE 40 Message too long EPROTOTYPE 41 Protocol wrong type for socket ENOPROTOOPT 42 Protocol not available EPROTONOSUPPORT 43 Protocol not supported ESOCKTNOSUPPORT 44 Socket type not supported EOPNOTSUPP 45 Operation not supported on socket EPFNOSUPPORT 46 Protocol family not supported EAFNOSUPPORT 47 Address family not supported EADDRINUSE 48 Address or port already in use EADDRNOTAVAIL 49 Cannot assign requested address ENETDOWN 50 Network is down ENETUNREACH 51 Network is unreachable ENETRESET 52 Network dropped connection ECONNABORTED 53 Software caused connection abort ECONNRESET 54 Connection reset by peer ENOBUFS 55 No buffer space available EISCONN 56 Socket is already connected ENOTCONN 57 Socket is not connected ESHUTDOWN 58 Cannot send after socket is shut down ETOOMANYREFS 59 Too many references ETIMEDOUT 60 Connection timed out ECONNREFUSED 61 Connection refused ELOOP 62 Too many levels of symbolic loops ENAMETOOLONG 63 File name too long EHOSTDOWN 64 Host is down EHOSTUNREACH 65 No route to host ENOTEMPTY 66 Directory not empty EPROCLIM 67 Too many processes EUSERS 68 Too many users EDQUOT 69 Disk quota exceeded ESTALE 70 Stale NFS file handle EREMOTE 71 Too many levels of remote in path ENOSTR 72 Device is not a stream ETIME 73 Timer expired ENOSR 74 Out of stream resources ENOMSG 75 No message of desired type EBADMSG 76 Trying to read unreadable EIDRM 77 Identifier removed EDEADLK 78 Deadlock condition ENOLCK 79 No record locks available ENONET 80 Machine is not on the network ERREMOTE 81 Object is remote ENOLINK 82 Link has been severed EADV 83 Advertise error ESRMNT 84 Srmount error ECOMM 85 Communication error on send EPROTO 86 Protocol error EMULTIHOP 87 Multihop attempted EDOTDOT 88 Cross mount point EREMCHG 89 Remote address changed IUCV errors: 97 IUCV instruction gave nonzero Condition Code for LASTERRNO request. 98 LASTERRNO call for IPAUDIT field with reject bit on: IUCV Send did not respond within the allowed time, or its IPAUDIT field was also nonzero. 99 IPAUDIT field not zero, but rejected bit was not on. 101 IUCV SEND did not respond, after we waited for at least the length of time given by DLYTIME i.e. the time specified by call MXIUWT, or a very large value by default. Something went wrong. Default is a large value (85000 secs), but a call to MXIUWT can set a lower value. (101 is special for MUSIC.) [Note: This value is a possible conflict with Windows Socket error WSAEDISCON, which Sim390 would convert to error number 101. WSAEDISCON does not seem to be returned by any socket functions that Sim390 uses.] 999 IUCV initial Connect (done by the GETCONN routine in $tcp:sockets.s) gave a nonzero Condition Code. Usually this means the user or job does not have the SYSCOM privilege. See the comments in GETCONN in $tcp:sockets.s . Special values for the IUCV Socket interface: 1000 Unrecognized socket call constant found in the high- order half-word of the Target Message Class field. This may mean an unsupported socket call. 1001 Other IUCV header error, bad length, etc. 1002 Socket number assigned by this program for ACCEPT, SOCKET, or TAKESOCKET is out of range. 1003 Socket number assigned by this program for ACCEPT, SOCKET, or TAKESOCKET is already in use. 1005 (Sim390) SOCKET(): unable to set PC socket to nonblocking mode. 1006 (Sim390) A previous socket operation is still in progress. 1007 (Sim390) givesocket() has been called; only close() and takesocket() are valid. 1009 (Sim390) Unable to convert Winsock error code. 1011 (Sim390) Could not get error code after a socket connect error. Error codes specific to MUSIC/SP or Sim390: 2000+n While waiting for the IUCV interrupt record after an IUCV Send for a select() operation, the task was woken up, but not with an IUCV interrupt. The MUSIC/SP Post Code is fetched to check the type of interrupt. If type is MULTI and INTFLAG is 0 (INTFLAG is 0 by default, but can be toggled by CALL INTSEL), the error is not given, and the job continues to wait. Otherwise any interrupt terminates the select(), and this error is given; the application that did the select() may wish to retry it. See comments at INTSEL and SENDWAI for more info. n = 0 ATTN interrupt 1 MSG interrupt 2 MULTI interrupt 3 ASYN interrupt 9 Other (unknown) interrupt Note: Functions GETSOC and mugetsoc can give error codes 2002 and 2003, which are not related to the above codes. Refer to the description of GETSOC. 2010 When calling QRDSEL to get the IUCV interrupt record after an IUCV Send instruction, rc=3 (busy) occurred, even after several retries. The IUCV Send is Purged. 2021 The interrupt record from an IUCV Send is an IUCV record, but the interrupt type (IPTYPE byte) is not 7. (7 = Message Complete External Interr, for a non-priority message.) 3000+n The IUCV instr for an IUCV Send operation gave a nonzero Condition Code. n is the IPRCODE value returned in the IUCV IPARM area (the byte at IPARM+3), or may be 0 for CC=3 (error detected by MUSIC/SP's IUCV module, e.g. no SYSCOM privilege, an invalid memory address, or not enough table or buffer space). See $sys:iucv.s . However, in the case of CC=3 and IPRCODE=2 (not enough table or buffer space), errno=55 (ENOBUFS) is given instead. Possible IPRCODE values include: n = 0 (CC=3) Error detected by MUSIC/SP's IUCV module. Note: If no SYSCOM privilege, normally errno 999 is given rather than 3000, since the initial Connect (in GETCONN routine) is the first IUCV operation in the job. 1 Invalid IUCV path id. 26 Buffer list not on 8-byte boundary. 27 Answer list not on 8-byte boundary. 91 (Sim390) Unsupported option bit in IUCV Send. 92 (Sim390) Buffer addr or buffer list addr < x'100'. 93 (Sim390) Initial IUCV Send expected but not done. 94 (Sim390) Message data len or answer len too big. 95 (Sim390) Scheduled External interrupt table is full. 5000 GETSOC or mugetsoc error. Refer to the description of function GETSOC. - - - - -