memfd.c revision 4632777024b7ba210e4efe5cfabc8cd0b5991045
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering/***
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering This file is part of systemd.
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering Copyright 2013 Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering systemd is free software; you can redistribute it and/or modify it
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering under the terms of the GNU Lesser General Public License as published by
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering (at your option) any later version.
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering systemd is distributed in the hope that it will be useful, but
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering Lesser General Public License for more details.
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering You should have received a copy of the GNU Lesser General Public License
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering***/
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include <stdio.h>
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include <fcntl.h>
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include <sys/ioctl.h>
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include <sys/mman.h>
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include <sys/prctl.h>
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include "util.h"
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include "bus-label.h"
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include "missing.h"
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include "memfd.h"
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering#include "sd-bus.h"
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringstruct sd_memfd {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering int fd;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering FILE *f;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering};
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_new(sd_memfd **m, const char *name) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering _cleanup_close_ int kdbus = -1;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering _cleanup_free_ char *g = NULL;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering sd_memfd *n;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering kdbus = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (kdbus < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (name) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering /* The kernel side is pretty picky about the character
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering * set here, let's do the usual bus escaping to deal
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering * with that. */
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering g = bus_label_escape(name);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!g)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -ENOMEM;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering name = g;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering } else {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering char pr[17] = {};
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering /* If no name is specified we generate one. We include
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering * a hint indicating our library implementation, and
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering * add the thread name to it */
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (isempty(pr))
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering name = "sd";
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering else {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering _cleanup_free_ char *e = NULL;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering e = bus_label_escape(pr);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!e)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -ENOMEM;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering g = strappend("sd-", e);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!g)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -ENOMEM;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering name = g;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering }
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering }
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering n = new0(struct sd_memfd, 1);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!n)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -ENOMEM;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering n->fd = memfd_create(name, MFD_ALLOW_SEALING);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (n->fd < 0) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering free(n);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering }
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering *m = n;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return 0;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_new_from_fd(sd_memfd **m, int fd) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering sd_memfd *n;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(fd >= 0, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering /* Check if this is a sealable fd */
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (fcntl(fd, F_GET_SEALS) < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -ENOTTY;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering n = new0(struct sd_memfd, 1);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!n)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -ENOMEM;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering n->fd = fd;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering *m = n;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return 0;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringvoid sd_memfd_free(sd_memfd *m) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!m)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (m->f)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering fclose(m->f);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering else
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering safe_close(m->fd);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering free(m);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_get_fd(sd_memfd *m) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return m->fd;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_get_file(sd_memfd *m, FILE **f) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(f, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!m->f) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering m->f = fdopen(m->fd, "r+");
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!m->f)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering }
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering *f = m->f;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return 0;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_dup_fd(sd_memfd *m) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering int fd;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering fd = fcntl(m->fd, F_DUPFD_CLOEXEC, 3);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (fd < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return fd;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_map(sd_memfd *m, uint64_t offset, size_t size, void **p) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering void *q;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering int sealed;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(size > 0, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(p, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering sealed = sd_memfd_get_sealed(m);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (sealed < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return sealed;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering q = mmap(NULL, size, sealed ? PROT_READ : PROT_READ|PROT_WRITE, MAP_PRIVATE, m->fd, offset);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (q == MAP_FAILED)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering *p = q;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return 0;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_set_sealed(sd_memfd *m) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering int r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering r = fcntl(m->fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (r < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return 0;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_get_sealed(sd_memfd *m) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering int r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering r = fcntl(m->fd, F_GET_SEALS);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (r < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return (r & (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE)) ==
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_get_size(sd_memfd *m, uint64_t *sz) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering int r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering struct stat stat;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(sz, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering r = fstat(m->fd, &stat);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (r < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering *sz = stat.st_size;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_set_size(sd_memfd *m, uint64_t sz) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering int r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering r = ftruncate(m->fd, sz);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (r < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_new_and_map(sd_memfd **m, const char *name, size_t sz, void **p) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering sd_memfd *n;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering int r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering r = sd_memfd_new(&n, name);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (r < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering r = sd_memfd_set_size(n, sz);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (r < 0) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering sd_memfd_free(n);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering }
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering r = sd_memfd_map(n, 0, sz, p);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (r < 0) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering sd_memfd_free(n);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return r;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering }
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering *m = n;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return 0;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poetteringint sd_memfd_get_name(sd_memfd *m, char **name) {
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering char path[sizeof("/proc/self/fd/") + DECIMAL_STR_MAX(int)], buf[FILENAME_MAX+1], *e;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering const char *delim, *end;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering _cleanup_free_ char *n = NULL;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering ssize_t k;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(m, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering assert_return(name, -EINVAL);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering sprintf(path, "/proc/self/fd/%i", m->fd);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering k = readlink(path, buf, sizeof(buf));
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (k < 0)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -errno;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if ((size_t) k >= sizeof(buf))
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -E2BIG;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering buf[k] = 0;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering delim = strstr(buf, ":[");
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!delim)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -EIO;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering delim = strchr(delim + 2, ':');
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!delim)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -EIO;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering delim++;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering end = strchr(delim, ']');
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!end)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -EIO;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering n = strndup(delim, end - delim);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!n)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -ENOMEM;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering e = bus_label_unescape(n);
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering if (!e)
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return -ENOMEM;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering *name = e;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering return 0;
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering}
839a4a20d8b4f6ebf3a342fd05c821358be5a313Lennart Poettering