<varlistentry>
<term><varname>NonBlocking=</varname></term>
- <listitem><para>Set the <constant>O_NONBLOCK</constant> flag
- for all file descriptors passed via socket-based activation.
- If true, all file descriptors >= 3 (i.e. all except stdin,
- stdout, and stderr) will have the
- <constant>O_NONBLOCK</constant> flag set and hence are in
- non-blocking mode. This option is only useful in conjunction
- with a socket unit, as described in
- <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- Defaults to false.</para></listitem>
+ <listitem><para>Set the <constant>O_NONBLOCK</constant> flag for all file descriptors passed via socket-based
+ activation. If true, all file descriptors >= 3 (i.e. all except stdin, stdout, stderr), excluding those passed
+ in via the file descriptor storage logic (see <varname>FileDescriptorStoreMax=</varname> for details), will
+ have the <constant>O_NONBLOCK</constant> flag set and hence are in non-blocking mode. This option is only
+ useful in conjunction with a socket unit, as described in
+ <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> and has no
+ effect on file descriptors which were previously saved in the file-descriptor store for example. Defaults to
+ false.</para></listitem>
</varlistentry>
<varlistentry>
return 0;
}
-static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
+static int flags_fds(const int fds[], unsigned n_fds, unsigned n_socket_fds, bool nonblock) {
unsigned i;
int r;
assert(fds);
- /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
+ /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags.
+ * O_NONBLOCK only applies to socket activation though. */
for (i = 0; i < n_fds; i++) {
- r = fd_nonblock(fds[i], nonblock);
- if (r < 0)
- return r;
+ if (i < n_socket_fds) {
+ r = fd_nonblock(fds[i], nonblock);
+ if (r < 0)
+ return r;
+ }
/* We unconditionally drop FD_CLOEXEC from the fds,
* since after all we want to pass these fds to our
int socket_fd,
int named_iofds[3],
int *fds, unsigned n_fds,
+ unsigned n_socket_fds,
char **files_env,
int user_lookup_fd,
int *exit_status,
if (r >= 0)
r = shift_fds(fds, n_fds);
if (r >= 0)
- r = flags_fds(fds, n_fds, context->non_blocking);
+ r = flags_fds(fds, n_fds, n_socket_fds, context->non_blocking);
if (r < 0) {
*exit_status = EXIT_FDS;
return r;
pid_t *ret) {
_cleanup_strv_free_ char **files_env = NULL;
- int *fds = NULL; unsigned n_fds = 0;
+ int *fds = NULL;
+ unsigned n_fds = 0, n_socket_fds = 0;
_cleanup_free_ char *line = NULL;
int socket_fd, r;
int named_iofds[3] = { -1, -1, -1 };
socket_fd = -1;
fds = params->fds;
n_fds = params->n_fds;
+ n_socket_fds = params->n_socket_fds;
}
r = exec_context_named_iofds(unit, context, params, named_iofds);
socket_fd,
named_iofds,
fds, n_fds,
+ n_socket_fds,
files_env,
unit->manager->user_lookup_fds[1],
&exit_status,
int *fds;
char **fd_names;
unsigned n_fds;
+ unsigned n_socket_fds;
ExecFlags flags;
bool selinux_context_net:1;
return 0;
}
-static int service_collect_fds(Service *s, int **fds, char ***fd_names) {
+static int service_collect_fds(Service *s, int **fds, char ***fd_names, unsigned *n_socket_fds) {
_cleanup_strv_free_ char **rfd_names = NULL;
_cleanup_free_ int *rfds = NULL;
- int rn_fds = 0, r;
+ unsigned rn_socket_fds = 0;
+ int rn_fds = 0, r;
assert(s);
assert(fds);
assert(fd_names);
+ assert(n_socket_fds);
if (s->socket_fd >= 0) {
}
}
+ rn_socket_fds = rn_fds;
+
if (s->n_fd_store > 0) {
ServiceFDStore *fs;
char **nl;
*fds = rfds;
*fd_names = rfd_names;
+ *n_socket_fds = rn_socket_fds;
rfds = NULL;
rfd_names = NULL;
_cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
_cleanup_free_ int *fds = NULL;
- unsigned n_fds = 0, n_env = 0;
+ unsigned n_fds = 0, n_socket_fds = 0, n_env = 0;
const char *path;
pid_t pid;
s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
s->exec_context.std_error == EXEC_OUTPUT_SOCKET) {
- r = service_collect_fds(s, &fds, &fd_names);
+ r = service_collect_fds(s, &fds, &fd_names, &n_socket_fds);
if (r < 0)
return r;
exec_params.fds = fds;
exec_params.fd_names = fd_names;
exec_params.n_fds = n_fds;
+ exec_params.n_socket_fds = n_socket_fds;
exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
exec_params.cgroup_path = path;