Standards
Standards / Extensions |
C or C++ |
Dependencies |
z/OS® UNIX |
both |
|
Format
#define _OPEN_SYS_SOCK_EXT
#include <sys/socket.h>
int givesocket(int d, struct clientid *clientid);
General
description
The givesocket() call makes the specified socket available to a
takesocket() call issued by another program. Any socket can be given.
Typically, givesocket() is used by a master program that obtains
sockets by means of accept() and gives them to application programs
that handle one socket at a time.
- Parameter
- Description
- d
- The descriptor of a socket to be given to another application.
- clientid
- A pointer to a client ID structure specifying the program to
which the socket is to be given.
To pass a socket, the giving program first calls givesocket() with
the client ID structure filled in as follows:
The clientid structure:
struct clientid {
int domain;
union {
char name[8];
struct {
int NameUpper;
pid_t pid;
} c_pid;
} c_name;
char subtaskname[8];
struct {
char type;
union {
char specific[19];
struct {
char unused[3];
int SockToken;
} c_close;
} c_func;
} c_reserved;
};
- Element
- Description
- domain
- The domain of the input socket descriptor.
- c_name.name
- If the clientid was set by a getclientid() call, c_name.name can
be
- set to the application program's address space name, left-justified
and padded with blanks. The application program can run in the same
address space as the master program, in which case this field is set
to the master program's address space.
- set to blanks, so any z/OS address space can take the socket.
- subtaskname
- If the clientid was set by a getclientid() call, subtaskname can
be
- set to the task identifier of the taker. This, combined with
a c_name.name value, allows only a process with this c_name.name and subtaskname to
take the socket.
- set to blanks. If c_name.name has a value and subtaskname is
blank, any task with that c_name.name can take the socket.
- c_pid.pid
- If the clientid was set by a __getclientid() call, c_pid.pid should
be set to the process id (PID) of the taker, so only a process with
that PID can take the socket. The subtaskname field is ignored
when the c_pid has a value.
- c_reserved.type
When set to SO_CLOSE, this indicates the socket should be
automatically closed by givesocket(), and a unique socket identifying
token is to be returned in c_close.SockToken. The c_close.SockToken should
be passed to the taking program to be used as input to takesocket()
instead of the socket descriptor. The now closed socket descriptor
could be re-used by the time the takesocket() is called, so the c_close.SockToken should
be used for takesocket().
When set to _SO_SELECT, this indicates
that the application intends to block on the select() for exception,
waiting for the takesocket() to occur before closing the socket. If c_reserved.type is
set to _SO_SELECT and the caller of givesocket() closes the socket
before it has been taken, the connection will be severed. _SO_SELECT
also allows select() to return exception status if select() is done
after the socket was taken with takesocket().
When
set to zero, this indicates that the application will not be calling
select() to coordinate with the taker of the socket. Either the socket
is not going to be closed or the giver and taker have some other method
of coordination for the giver to know when the taker has called takesocket().
Note that if select() for exception is called before takesocket(),
the select will return when takesocket() is called but if select()
is called after takesocket(), it will hang. _SO_SELECT should be used
if select() is going to be called by the giver.
Also,
if the given socket is closed before the takesocket() is issued, it
is possible for that socket descriptor number to be reused in the
giver's process. A sequence of accept(), givesocket(), and close()
calls issued several times before any takesocket() calls can result
in several sockets with the same descriptor number waiting to be taken.
In this case, the oldest given socket will be taken; that is, in
FIFO order. Note that if select() is called when there are several
given sockets with the same descriptor number waiting to be taken,
select() will operate on the current active socket for that descriptor.
It effectively waits for the last (newest) given socket to be taken;
that is, in LIFO order.
- c_close.SockToken
- The unique socket identifying token returned by givesocket()
to be used as input to takesocket(), instead of the socket descriptor
when c_reserved.type has been set to SO_CLOSE.
- c_reserved
- Specifies binary zeros if an automatic close of a socket is
not to be done by givesocket().
Using name and subtaskname for givesocket/takesocket:
- The giving program calls getclientid() to obtain its client ID.
The giving program calls givesocket() to make the socket available
for a takesocket() call. The giving program passes its client ID
along with the descriptor of the socket to be given to the taking
program by the taking program's startup parameter list.
- The taking program calls takesocket(), specifying the giving program's
client ID and socket descriptor.
- Waiting for the taking program to take the socket, the giving
program uses select() to test the given socket for an exception condition.
When select() reports that an exception condition is pending, the
giving program calls close() to free the given socket.
- If the giving program closes the socket before a pending exception
condition is indicated, the connection is immediately reset, and the
taking program's call to takesocket() is unsuccessful. Calls other
than the close() call issued on a given socket return -1, with errno
set to EBADF.
Note: For backward compatibility, a client ID can point
to the struct client ID structure obtained when the target program
calls getclientid(). In this case, only the target program, and no
other programs in the target program's address space, can take the
socket.
Using process id (PID) for givesocket/takesocket:
- The giving program calls __getclientid() to obtain its client
ID. The giving program sets the c_pid.pid in the clientid
structure to the PID of the taking program that will take the socket
(that is, issue the takesocket() call). This ensures only a process
that has obtained the giver's PID can take the specified socket.
If the giving program wants the socket to be automatically closed
by givesocket(), c_reserved.type should be set to SO_CLOSE.
The giving program calls givesocket() to make the socket available
for a takesocket() call. The giving program passes its client ID,
the descriptor of the socket to be given, and the giving program's
PID to the taking program by the taking program's startup parameter
list.
- The taking program sets the c_pid.pid in the clientid
structure to the PID of the giving program to identify the process
from which the socket is to be taken. If the c_reserved.type field
was set to SO_CLOSE on givesocket(), the c_close.SockToken should
be used as input to the takesocket() instead of the normal socket
descriptor. The taking program calls takesocket(), specifying the
giving program's client ID and either the socket descriptor or c_close.SockToken.
- If the c_reserved.type field in the clientid structure
was set to SO_CLOSE on the givesocket() call, the socket is closed
and the giving program does not have to wait for the taking program
to issue the takesocket(). Otherwise, steps 3 and 4 of "Using name
and subtaskname for givesocket/takesocket" should be followed.
Returned value
If successful, givesocket() returns 0.
If unsuccessful, givesocket() returns -1 and sets errno to one
of the following values:
- Error Code
- Description
- EBADF
- The d parameter is not a valid socket descriptor.
The socket has already been given.
- EFAULT
- Using the clientid parameter as specified would result
in an attempt to access storage outside the caller's address space.
- EINVAL
- The clientid parameter does not specify a valid client
identifier or the clientid domain does not match the domain of the
input socket descriptor.