prcmd.3n (2010 09)

p
prcmd(3N) prcmd(3N)
DIAGNOSTICS
Unlike rcmd(), prcmd() does not copy messages from
remshd to the local standard error when
remshd fails. It just puts the host in
PRC_CONN_REFUSED state.
EXAMPLES
The following code fragment illustrates how to allocate and initialize an array of hosts, and call
prcmd() once for the entire list of hosts:
int index;
struct prc_host prc_host [MAXHOSTS];
prcmd_init (prc_host, argc, 0, REMCMD, TIMEOUT);
for (index = 0; index < argc; ++index)
(prc_host[index].prc_hostid) = argv [index];
if ((rc = prcmd (prc_host, argc)) != PRC_OK)
...
WARNINGS
prcmd() is unsafe in multi-thread applications.
Like
rcmd(), prcmd() should only be called by a privileged process. Otherwise it puts every host in
PRC_CONN_FAILED status with
errno =13(EACCES) because it cannot bind() to any reserved
port.
At this time
select() calls are done on files specified by prc_fp only, not
prc_fp2. prcmd()
assumes that the remote command will never write to standard error and then block, but will instead ter-
minate or otherwise close stdout. When stdout is read-ready, the calling program can safely do a blocking
read() on prc_fp, and upon EOF or error, check prc_fp2 with a blocking read().
(Exception: For status
PRC_CONN2_WAIT
both files are selected since either might come ready depend-
ing on success or failure, as described earlier. However, this exception is handled internal to
prcmd()
and does not affect the calling program.)
Note that
prcmd_init() saves a pointer to the value of command, not the value itself, so the calling
program must preserve the value through all calls of prcmd().
connect() times out after about two minutes, even with non-blocking I/O. If this happens to a host’s
connection, the result is indistinguishable from
PRC_CONN_REFUSED since write() returns EPIPE
in either case. This is not a problem if the calling program allows less than two minutes for a connection,
that is, sends a timeout value less than 120, and calls prcmd() frequently enough that the latter
catches the timeout itself before connect() does.
Be careful when using buffered I/O. Avoid calls to
fgets(), fread(), and similar functions in cir-
cumstances where they might block indefinitely if less data is available than requested. Also, be sure to
read all available data from a host via the file specified by prc_fp before waiting again for a connection
to be read-ready. The connection might appear not-ready even though buffered, pending data was
already read by the stdio library, and is available. Avoiding these problems might require the use of
non-blocking I/O; see fcntl (2).
Be careful about writing to a socket that might be closed if the remote command terminates, or if the con-
nection is lost. This can cause the calling process to receive
SIGPIPE. The calling program must handle
this signal if appropriate.
When handling a host whose connection failed with
PRC_CONN_REFUSED, remember to free() the
host’s prc_errmsg pointer if it is non-null. This can be skipped if regaining malloc’d memory is not
required.
Performance Issues
It is faster to call
prcmd() with host IDs specified as internet addresses rather than names, because
prcmd() will not need to look up each host in the hosts database. However, when doing so with hosts
that have multiple internet addresses, only the specified internet address is tried.
There is a limit of about 512 reserved ports on each system, and a soft limit for the number of available
file descriptors for each process. Each specified host requires two reserved ports and two file descriptors
for the connection to check its status.
prcmd() defers (serializes) additional connections once all ports
or file descriptors are in use, so additional hosts are not ignored, but the time required for all connections
HP-UX 11i Version 3: September 2010 7 Hewlett-Packard Company 7