예제 #1
0
static void test_fdset_cloexec(void) {
        int fd = -1;
        _cleanup_fdset_free_ FDSet *fdset = NULL;
        int flags = -1;
        char name[] = "/tmp/test-fdset_cloexec.XXXXXX";

        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
        assert_se(fd >= 0);

        fdset = fdset_new();
        assert_se(fdset);
        assert_se(fdset_put(fdset, fd));

        assert_se(fdset_cloexec(fdset, false) >= 0);
        flags = fcntl(fd, F_GETFD);
        assert_se(flags >= 0);
        assert_se(!(flags & FD_CLOEXEC));

        assert_se(fdset_cloexec(fdset, true) >= 0);
        flags = fcntl(fd, F_GETFD);
        assert_se(flags >= 0);
        assert_se(flags & FD_CLOEXEC);

        unlink(name);
}
예제 #2
0
파일: fdset.c 프로젝트: pwaller/systemd
int fdset_new_listen_fds(FDSet **_s, bool unset) {
        int n, fd, r;
        FDSet *s;

        assert(_s);

        /* Creates an fdset and fills in all passed file descriptors */

        s = fdset_new();
        if (!s) {
                r = -ENOMEM;
                goto fail;
        }

        n = sd_listen_fds(unset);
        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
                r = fdset_put(s, fd);
                if (r < 0)
                        goto fail;
        }

        *_s = s;
        return 0;


fail:
        if (s)
                set_free(MAKE_SET(s));

        return r;
}
예제 #3
0
int fdset_new_fill(FDSet **_s) {
        DIR *d;
        struct dirent *de;
        int r = 0;
        FDSet *s;

        assert(_s);

        /* Creates an fdset and fills in all currently open file
         * descriptors. */

        d = opendir("/proc/self/fd");
        if (!d)
                return -errno;

        s = fdset_new();
        if (!s) {
                r = -ENOMEM;
                goto finish;
        }

        while ((de = readdir(d))) {
                int fd = -1;

                if (ignore_file(de->d_name))
                        continue;

                r = safe_atoi(de->d_name, &fd);
                if (r < 0)
                        goto finish;

                if (fd < 3)
                        continue;

                if (fd == dirfd(d))
                        continue;

                r = fdset_put(s, fd);
                if (r < 0)
                        goto finish;
        }

        r = 0;
        *_s = s;
        s = NULL;

finish:
        closedir(d);

        /* We won't close the fds here! */
        if (s)
                set_free(MAKE_SET(s));

        return r;
}
예제 #4
0
파일: fdset.c 프로젝트: josephgbr/systemd
int fdset_consume(FDSet *s, int fd) {
        int r;

        assert(s);
        assert(fd >= 0);

        r = fdset_put(s, fd);
        if (r <= 0)
                safe_close(fd);

        return r;
}
예제 #5
0
static void test_fdset_iterate(void) {
        int fd = -1;
        FDSet *fdset = NULL;
        char name[] = "/tmp/test-fdset_iterate.XXXXXX";
        Iterator i;
        int c = 0;
        int a;

        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
        assert_se(fd >= 0);

        fdset = fdset_new();
        assert_se(fdset);
        assert_se(fdset_put(fdset, fd) >= 0);
        assert_se(fdset_put(fdset, fd) >= 0);
        assert_se(fdset_put(fdset, fd) >= 0);

        FDSET_FOREACH(a, fdset, i) {
                c++;
                assert_se(a == fd);
        }
예제 #6
0
파일: fdset.c 프로젝트: adsr/systemd
int fdset_put_dup(FDSet *s, int fd) {
        int copy, r;

        assert(s);
        assert(fd >= 0);

        if ((copy = fcntl(fd, F_DUPFD_CLOEXEC, 3)) < 0)
                return -errno;

        if ((r = fdset_put(s, copy)) < 0) {
                close_nointr_nofail(copy);
                return r;
        }

        return copy;
}
예제 #7
0
파일: fdset.c 프로젝트: pwaller/systemd
int fdset_put_dup(FDSet *s, int fd) {
        int copy, r;

        assert(s);
        assert(fd >= 0);

        copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
        if (copy < 0)
                return -errno;

        r = fdset_put(s, copy);
        if (r < 0) {
                safe_close(copy);
                return r;
        }

        return copy;
}
예제 #8
0
static void test_fdset_remove(void) {
        _cleanup_close_ int fd = -1;
        FDSet *fdset = NULL;
        char name[] = "/tmp/test-fdset_remove.XXXXXX";

        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
        assert_se(fd >= 0);

        fdset = fdset_new();
        assert_se(fdset);
        assert_se(fdset_put(fdset, fd) >= 0);
        assert_se(fdset_remove(fdset, fd) >= 0);
        assert_se(!fdset_contains(fdset, fd));
        fdset_free(fdset);

        assert_se(fcntl(fd, F_GETFD) >= 0);

        unlink(name);
}
예제 #9
0
파일: fdset.c 프로젝트: AOSC-Dev/systemd
int fdset_new_array(FDSet **ret, const int *fds, unsigned n_fds) {
        unsigned i;
        FDSet *s;
        int r;

        assert(ret);

        s = fdset_new();
        if (!s)
                return -ENOMEM;

        for (i = 0; i < n_fds; i++) {

                r = fdset_put(s, fds[i]);
                if (r < 0) {
                        set_free(MAKE_SET(s));
                        return r;
                }
        }

        *ret = s;
        return 0;
}
예제 #10
0
static int server_init(Server *s, unsigned n_sockets) {
        int r;
        unsigned i;
        struct epoll_event ev;
        sigset_t mask;

        assert(s);
        assert(n_sockets > 0);

        zero(*s);

        s->kmsg_fd = s->signal_fd = -1;

        if ((s->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) {
                r = -errno;
                log_error("Failed to create epoll object: %s", strerror(errno));
                goto fail;
        }

        if (!(s->syslog_fds = fdset_new())) {
                r = -ENOMEM;
                log_error("Failed to allocate file descriptor set: %s", strerror(errno));
                goto fail;
        }

        for (i = 0; i < n_sockets; i++) {
                int fd, one = 1;

                fd = SD_LISTEN_FDS_START+i;

                if ((r = sd_is_socket(fd, AF_UNSPEC, SOCK_DGRAM, -1)) < 0) {
                        log_error("Failed to determine file descriptor type: %s", strerror(-r));
                        goto fail;
                }

                if (!r) {
                        log_error("Wrong file descriptor type.");
                        r = -EINVAL;
                        goto fail;
                }

                if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
                        log_error("SO_PASSCRED failed: %m");

                zero(ev);
                ev.events = EPOLLIN;
                ev.data.fd = fd;
                if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
                        r = -errno;
                        log_error("Failed to add server fd to epoll object: %s", strerror(errno));
                        goto fail;
                }

                if ((r = fdset_put(s->syslog_fds, fd)) < 0) {
                        log_error("Failed to store file descriptor in set: %s", strerror(-r));
                        goto fail;
                }
        }

        if ((s->kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) {
                log_error("Failed to open /dev/kmsg for logging: %m");
                return -errno;
        }

        assert_se(sigemptyset(&mask) == 0);
        sigset_add_many(&mask, SIGINT, SIGTERM, -1);
        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);

        if ((s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
                log_error("signalfd(): %m");
                return -errno;
        }

        zero(ev);
        ev.events = EPOLLIN;
        ev.data.fd = s->signal_fd;

        if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) {
                log_error("epoll_ctl(): %m");
                return -errno;
        }

        return 0;

fail:
        server_done(s);
        return r;
}