core: simplify how we create socket fds

Let's always return the allocated fds as return values where possible,
and make more use of _cleanup_close_
This commit is contained in:
Lennart Poettering 2015-09-23 19:52:23 +02:00
parent ed460b077a
commit e8da24a642
1 changed files with 94 additions and 118 deletions

View File

@ -19,38 +19,39 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <sys/stat.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <signal.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <mqueue.h>
#include <netinet/tcp.h>
#include <signal.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <unistd.h>
#include "sd-event.h"
#include "bus-error.h"
#include "bus-util.h"
#include "copy.h"
#include "dbus-socket.h"
#include "def.h"
#include "exit-status.h"
#include "formats-util.h"
#include "label.h"
#include "log.h"
#include "strv.h"
#include "missing.h"
#include "mkdir.h"
#include "path-util.h"
#include "selinux-util.h"
#include "signal-util.h"
#include "smack-util.h"
#include "socket.h"
#include "special.h"
#include "strv.h"
#include "unit-name.h"
#include "unit-printf.h"
#include "missing.h"
#include "special.h"
#include "label.h"
#include "exit-status.h"
#include "def.h"
#include "smack-util.h"
#include "bus-util.h"
#include "bus-error.h"
#include "selinux-util.h"
#include "dbus-socket.h"
#include "unit.h"
#include "formats-util.h"
#include "signal-util.h"
#include "socket.h"
#include "copy.h"
static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
[SOCKET_DEAD] = UNIT_INACTIVE,
@ -967,38 +968,36 @@ static void socket_apply_fifo_options(Socket *s, int fd) {
static int fifo_address_create(
const char *path,
mode_t directory_mode,
mode_t socket_mode,
int *_fd) {
mode_t socket_mode) {
int fd = -1, r = 0;
struct stat st;
_cleanup_close_ int fd = -1;
mode_t old_mask;
struct stat st;
int r;
assert(path);
assert(_fd);
mkdir_parents_label(path, directory_mode);
r = mac_selinux_create_file_prepare(path, S_IFIFO);
if (r < 0)
goto fail;
return r;
/* Enforce the right access mode for the fifo */
old_mask = umask(~ socket_mode);
/* Include the original umask in our mask */
umask(~socket_mode | old_mask);
(void) umask(~socket_mode | old_mask);
r = mkfifo(path, socket_mode);
umask(old_mask);
(void) umask(old_mask);
if (r < 0 && errno != EEXIST) {
r = -errno;
goto fail;
}
fd = open(path,
O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
fd = open(path, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
if (fd < 0) {
r = -errno;
goto fail;
@ -1015,13 +1014,14 @@ static int fifo_address_create(
(st.st_mode & 0777) != (socket_mode & ~old_mask) ||
st.st_uid != getuid() ||
st.st_gid != getgid()) {
r = -EEXIST;
goto fail;
}
*_fd = fd;
return 0;
r = fd;
fd = -1;
return r;
fail:
mac_selinux_create_file_clear();
@ -1030,51 +1030,36 @@ fail:
return r;
}
static int special_address_create(
const char *path,
int *_fd) {
int fd = -1, r = 0;
static int special_address_create(const char *path) {
_cleanup_close_ int fd = -1;
struct stat st;
int r;
assert(path);
assert(_fd);
fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
if (fd < 0) {
r = -errno;
goto fail;
}
if (fd < 0)
return -errno;
if (fstat(fd, &st) < 0) {
r = -errno;
goto fail;
}
if (fstat(fd, &st) < 0)
return -errno;
/* Check whether this is a /proc, /sys or /dev file or char device */
if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
r = -EEXIST;
goto fail;
}
if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode))
return -EEXIST;
*_fd = fd;
return 0;
fail:
safe_close(fd);
r = fd;
fd = -1;
return r;
}
static int ffs_address_create(
const char *path,
int *_fd) {
static int ffs_address_create(const char *path) {
_cleanup_close_ int fd = -1;
struct stat st;
int r;
assert(path);
assert(_fd);
fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
if (fd < 0)
@ -1087,32 +1072,32 @@ static int ffs_address_create(
if (!S_ISREG(st.st_mode))
return -EEXIST;
*_fd = fd;
r = fd;
fd = -1;
return 0;
return r;
}
static int mq_address_create(
const char *path,
mode_t mq_mode,
long maxmsg,
long msgsize,
int *_fd) {
long msgsize) {
int fd = -1, r = 0;
_cleanup_close_ int fd = -1;
struct stat st;
mode_t old_mask;
struct mq_attr _attr, *attr = NULL;
int r;
assert(path);
assert(_fd);
if (maxmsg > 0 && msgsize > 0) {
zero(_attr);
_attr.mq_flags = O_NONBLOCK;
_attr.mq_maxmsg = maxmsg;
_attr.mq_msgsize = msgsize;
_attr = (struct mq_attr) {
.mq_flags = O_NONBLOCK,
.mq_maxmsg = maxmsg,
.mq_msgsize = msgsize,
};
attr = &_attr;
}
@ -1120,33 +1105,24 @@ static int mq_address_create(
old_mask = umask(~ mq_mode);
/* Include the original umask in our mask */
umask(~mq_mode | old_mask);
(void) umask(~mq_mode | old_mask);
fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr);
umask(old_mask);
(void) umask(old_mask);
if (fd < 0) {
r = -errno;
goto fail;
}
if (fd < 0)
return -errno;
if (fstat(fd, &st) < 0) {
r = -errno;
goto fail;
}
if (fstat(fd, &st) < 0)
return -errno;
if ((st.st_mode & 0777) != (mq_mode & ~old_mask) ||
st.st_uid != getuid() ||
st.st_gid != getgid()) {
st.st_gid != getgid())
return -EEXIST;
r = -EEXIST;
goto fail;
}
r = fd;
fd = -1;
*_fd = fd;
return 0;
fail:
safe_close(fd);
return r;
}
@ -1166,8 +1142,7 @@ static int socket_symlink(Socket *s) {
return 0;
}
static int ffs_write_descs(int fd, Unit *u) {
Service *s = SERVICE(u);
static int ffs_write_descs(int fd, Service *s) {
int r;
if (!s->usb_function_descriptors || !s->usb_function_strings)
@ -1175,11 +1150,9 @@ static int ffs_write_descs(int fd, Unit *u) {
r = copy_file_fd(s->usb_function_descriptors, fd, false);
if (r < 0)
return 0;
return r;
r = copy_file_fd(s->usb_function_strings, fd, false);
return r;
return copy_file_fd(s->usb_function_strings, fd, false);
}
static int select_ep(const struct dirent *d) {
@ -1216,10 +1189,12 @@ static int ffs_dispatch_eps(SocketPort *p) {
path_kill_slashes(ep);
r = ffs_address_create(ep, &p->auxiliary_fds[k]);
r = ffs_address_create(ep);
if (r < 0)
goto fail;
p->auxiliary_fds[k] = r;
++k;
free(ent[i]);
}
@ -1227,9 +1202,7 @@ static int ffs_dispatch_eps(SocketPort *p) {
return r;
fail:
while (k)
safe_close(p->auxiliary_fds[--k]);
close_many(p->auxiliary_fds, k);
p->auxiliary_fds = mfree(p->auxiliary_fds);
p->n_auxiliary_fds = 0;
@ -1303,44 +1276,47 @@ static int socket_open_fds(Socket *s) {
} else if (p->type == SOCKET_SPECIAL) {
r = special_address_create(
p->path,
&p->fd);
if (r < 0)
p->fd = special_address_create(p->path);
if (p->fd < 0) {
r = p->fd;
goto rollback;
}
} else if (p->type == SOCKET_FIFO) {
r = fifo_address_create(
p->fd = fifo_address_create(
p->path,
s->directory_mode,
s->socket_mode,
&p->fd);
if (r < 0)
s->socket_mode);
if (p->fd < 0) {
r = p->fd;
goto rollback;
}
socket_apply_fifo_options(s, p->fd);
socket_symlink(s);
} else if (p->type == SOCKET_MQUEUE) {
r = mq_address_create(
p->fd = mq_address_create(
p->path,
s->socket_mode,
s->mq_maxmsg,
s->mq_msgsize,
&p->fd);
if (r < 0)
s->mq_msgsize);
if (p->fd < 0) {
r = p->fd;
goto rollback;
}
} else if (p->type == SOCKET_USB_FUNCTION) {
r = ffs_address_create(
p->path,
&p->fd);
if (r < 0)
p->fd = ffs_address_create(p->path);
if (p->fd < 0) {
r = p->fd;
goto rollback;
}
r = ffs_write_descs(p->fd, s->service.unit);
r = ffs_write_descs(p->fd, SERVICE(UNIT_DEREF(s->service)));
if (r < 0)
goto rollback;