Introduce the daemonfd function.

The daemonfd function is equivalent to the daemon(3) function expect that
arguments are descriptors. For example dhclient(8) which is sandboxed is
unable to open /dev/null to close stdio instead it's allows to fail
daemon(3) function to close the descriptors and then do it explicit in code.
Instead of such hacks we can use now daemonfd.

This API can be also helpful to migrate system to platforms like CheriBSD.

Reviewed by:	brooks@, bcr@, jilles@ (earlier version)
Differential Revision:	https://reviews.freebsd.org/D13433
This commit is contained in:
Mariusz Zaborski 2017-12-23 18:07:43 +00:00
parent 6d41588b6b
commit 16545cf5d5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=327115
4 changed files with 70 additions and 14 deletions

View file

@ -274,6 +274,7 @@ int cgetstr(char *, const char *, char **);
int cgetustr(char *, const char *, char **);
int daemon(int, int);
int daemonfd(int, int);
char *devname(__dev_t, __mode_t);
char *devname_r(__dev_t, __mode_t, char *, int);
char *fdevname(int);

View file

@ -394,6 +394,7 @@ FBSD_1.4 {
FBSD_1.5 {
alphasort;
basename;
daemonfd;
devname;
devname_r;
dirname;

View file

@ -28,7 +28,7 @@
.\" @(#)daemon.3 8.1 (Berkeley) 6/9/93
.\" $FreeBSD$
.\"
.Dd June 9, 1993
.Dd December 23, 2017
.Dt DAEMON 3
.Os
.Sh NAME
@ -40,6 +40,8 @@
.In stdlib.h
.Ft int
.Fn daemon "int nochdir" "int noclose"
.Ft int
.Fn daemonfd "int chdirfd" "int nullfd"
.Sh DESCRIPTION
The
.Fn daemon
@ -59,15 +61,39 @@ is non-zero,
.Fn daemon
will redirect standard input, standard output, and standard error to
.Pa /dev/null .
.Pp
The
.Fn daemonfd
function is equivalent to the
.Fn daemon
function except that arguments are the descriptors for the current working
directory and to the descriptor to
.Pa /dev/null .
.Pp
If
.Fa chdirfd
is equal to
.Pq -1
the current working directory is not changed.
.Pp
If
.Fa nullfd
is equals to
.Pq -1
the redirection of standard input, standard output, and standard error is not
closed.
.Sh RETURN VALUES
.Rv -std daemon
.Rv -std daemon daemonfd
.Sh ERRORS
The
.Fn daemon
and
.Fn daemonfd
function may fail and set
.Va errno
for any of the errors specified for the library functions
.Xr fork 2
.Xr open 2,
and
.Xr setsid 2 .
.Sh SEE ALSO
@ -79,6 +105,10 @@ The
.Fn daemon
function first appeared in
.Bx 4.4 .
The
.Fn daemonfd
function first appeared in
.Fx 12.0 .
.Sh CAVEATS
Unless the
.Fa noclose

View file

@ -1,8 +1,9 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1990, 1993 The Regents of the University of California.
* Copyright (c) 2017 Mariusz Zaborski <oshogbo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -46,10 +47,9 @@ __FBSDID("$FreeBSD$");
#include "libc_private.h"
int
daemon(int nochdir, int noclose)
daemonfd(int chdirfd, int nullfd)
{
struct sigaction osa, sa;
int fd;
pid_t newgrp;
int oerrno;
int osa_ok;
@ -83,15 +83,39 @@ daemon(int nochdir, int noclose)
return (-1);
}
if (!nochdir)
(void)chdir("/");
if (chdirfd != -1)
(void)fchdir(chdirfd);
if (!noclose && (fd = _open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
(void)_dup2(fd, STDIN_FILENO);
(void)_dup2(fd, STDOUT_FILENO);
(void)_dup2(fd, STDERR_FILENO);
if (fd > 2)
(void)_close(fd);
if (nullfd != -1) {
(void)_dup2(nullfd, STDIN_FILENO);
(void)_dup2(nullfd, STDOUT_FILENO);
(void)_dup2(nullfd, STDERR_FILENO);
}
return (0);
}
int
daemon(int nochdir, int noclose)
{
int chdirfd, nullfd, ret;
if (!noclose)
nullfd = _open(_PATH_DEVNULL, O_RDWR, 0);
else
nullfd = -1;
if (!nochdir)
chdirfd = _open("/", O_EXEC);
else
chdirfd = -1;
ret = daemonfd(chdirfd, nullfd);
if (chdirfd != -1)
_close(chdirfd);
if (nullfd > 2)
_close(nullfd);
return (ret);
}