The daemon which is handling the service user side of things will read configuration files to decide what to do. If it decides to allow the service to be provided it will fork a subprocess to execute the service.
The service will have no controlling terminal, but it will be a process group leader.
If the client is killed or times out or a file or descriptor being
read or written by the client process gets an error then the service
will be disconnected from the client. The client will return an exit
status of 255 and some the service's pipes may be closed at the other
end. The service will become a child of init
. The service may
well not notice the disconnection, though writing to a pipe after this
may produce a SIGPIPE
and the facility exists to have a
SIGHUP
sent to the service on disconnection.
The service program's standard filedescriptors, and possibly other
file descriptors, will be connected to pipes or to
/dev/null
. The userv
client/daemon pair will arrange
that data is copied between the files or file descriptors specified to
to the client by the caller and these these pipes.
Pipes which may be written to will be closed if a write error occurs
on the corresponding client-side file or descriptor, which may result
in a SIGPIPE
in the service program; pipes open for reading
will get EOF
if the client-side file descriptor gets EOF
or an error.
If the service closes one of its reading file descriptors the writing
end of the corresponding pipe will generate a SIGPIPE
when
attempts are made by the client/daemon pair to write to it. This will
not be considered an error; rather, the relevant pipe will be
discarded and the corresponding file or file descriptor held by the
client will be closed.
Likewise, if one of the file descriptors held by the client for
writing by the service is a pipe whose other end is closed by the
caller then the client/daemon pair will see an error when trying to
copy data provided by the service. This too will not be considered an
error; rather, the pipe correspondong to that descriptor will be
closed and any further writes will cause the service to get a
SIGPIPE
.
Note that not all write errors or broken pipes on file descriptors may
be visible to the service, since buffered data may be discarded by the
operating system and there will be a finite interval between the error
happening and the service being disconnected from the client or the
next write causing a SIGPIPE
.
Read errors on file descriptors (and disconnection) will only be
visible to the service and distinguishable from normal end of file if
disconnect-hup
is in effect.
Read and write errors (other than broken pipes, as described above) will always be visible to the caller; they are system errors, and will therefore cause the client to print an error message to stderr and return with an exit status of 255.
If the main service program process exits while it still has running
children any file descriptors held by those children can remain open,
depending on the use of wait, nowait or close for the
relevant file descriptor in the client's arguments. By default
writing filedescriptors remain open and the client will wait for them
to be closed at the service end, and reading file descriptors are
closed immediately. These leftover child processes will not get a any
SIGHUP
even if a read or write error occurs or the client
disconnects before then.
The service will have some information in environment variables:
LOGNAME
variable is
set (or, if that is unset, if the USER
variable is set) in the
environment passed to the client by the caller then the password entry
for that login name will be looked up; if that password entry's uid is
the same as that of the calling process then that login name will be
used, otherwise (or if neither LOGNAME
nor USER
is set)
the calling process's uid will be looked up to determine their login
name (and if this lookup fails then the service will not be invoked).
USERV_GID
. If no name can be found for any of the
calling process's group(s) then the service will not be invoked.
--hidecwd
flag was used then this variable will be set to an
empty string (this is not considered an error).
HOME
, PATH
, SHELL
, LOGNAME
and USER
will be set appropriately (according to the details of the service
user).