106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier/***
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier This file is part of systemd
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier Copyright 2014 Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier systemd is free software; you can redistribute it and/or modify it
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier under the terms of the GNU Lesser General Public License as published by
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier the Free Software Foundation; either version 2.1 of the License, or
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier (at your option) any later version.
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier systemd is distributed in the hope that it will be useful, but
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier WITHOUT ANY WARRANTY; without even the implied warranty of
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier Lesser General Public License for more details.
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier You should have received a copy of the GNU Lesser General Public License
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier***/
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier#include <fcntl.h>
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier#include <unistd.h>
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier#include "fdset.h"
0d39fa9c69b97a2ceb156053deef69c0866c2b97Lennart Poettering#include "fileio.h"
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier#include "macro.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "util.h"
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalierstatic void test_fdset_new_fill(void) {
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier int fd = -1;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier _cleanup_fdset_free_ FDSet *fdset = NULL;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier char name[] = "/tmp/test-fdset_new_fill.XXXXXX";
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fd >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset_new_fill(&fdset) >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset_contains(fdset, fd));
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier unlink(name);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier}
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalierstatic void test_fdset_put_dup(void) {
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier _cleanup_close_ int fd = -1;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier int copyfd = -1;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier _cleanup_fdset_free_ FDSet *fdset = NULL;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier char name[] = "/tmp/test-fdset_put_dup.XXXXXX";
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fd >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier fdset = fdset_new();
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier copyfd = fdset_put_dup(fdset, fd);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(copyfd >= 0 && copyfd != fd);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset_contains(fdset, copyfd));
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(!fdset_contains(fdset, fd));
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier unlink(name);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier}
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalierstatic void test_fdset_cloexec(void) {
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier int fd = -1;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier _cleanup_fdset_free_ FDSet *fdset = NULL;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier int flags = -1;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier char name[] = "/tmp/test-fdset_cloexec.XXXXXX";
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fd >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier fdset = fdset_new();
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset_put(fdset, fd));
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset_cloexec(fdset, false) >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier flags = fcntl(fd, F_GETFD);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(flags >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(!(flags & FD_CLOEXEC));
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset_cloexec(fdset, true) >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier flags = fcntl(fd, F_GETFD);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(flags >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(flags & FD_CLOEXEC);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier unlink(name);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier}
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalierstatic void test_fdset_close_others(void) {
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier int fd = -1;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier int copyfd = -1;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier _cleanup_fdset_free_ FDSet *fdset = NULL;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier int flags = -1;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier char name[] = "/tmp/test-fdset_close_others.XXXXXX";
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fd >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier fdset = fdset_new();
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier copyfd = fdset_put_dup(fdset, fd);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(copyfd >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(fdset_close_others(fdset) >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier flags = fcntl(fd, F_GETFD);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(flags < 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier flags = fcntl(copyfd, F_GETFD);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier assert_se(flags >= 0);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier unlink(name);
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier}
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalierstatic void test_fdset_remove(void) {
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier _cleanup_close_ int fd = -1;
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier FDSet *fdset = NULL;
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier char name[] = "/tmp/test-fdset_remove.XXXXXX";
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier assert_se(fd >= 0);
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier fdset = fdset_new();
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier assert_se(fdset);
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier assert_se(fdset_put(fdset, fd) >= 0);
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier assert_se(fdset_remove(fdset, fd) >= 0);
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier assert_se(!fdset_contains(fdset, fd));
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier fdset_free(fdset);
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier assert_se(fcntl(fd, F_GETFD) >= 0);
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier unlink(name);
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier}
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalierstatic void test_fdset_iterate(void) {
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier int fd = -1;
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier FDSet *fdset = NULL;
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier char name[] = "/tmp/test-fdset_iterate.XXXXXX";
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier Iterator i;
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier int c = 0;
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier int a;
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier assert_se(fd >= 0);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier fdset = fdset_new();
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier assert_se(fdset);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier assert_se(fdset_put(fdset, fd) >= 0);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier assert_se(fdset_put(fdset, fd) >= 0);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier assert_se(fdset_put(fdset, fd) >= 0);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier FDSET_FOREACH(a, fdset, i) {
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier c++;
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier assert_se(a == fd);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier }
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier assert_se(c == 1);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier fdset_free(fdset);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier unlink(name);
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier}
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalierstatic void test_fdset_isempty(void) {
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier int fd;
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier _cleanup_fdset_free_ FDSet *fdset = NULL;
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier char name[] = "/tmp/test-fdset_isempty.XXXXXX";
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fd >= 0);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier fdset = fdset_new();
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_isempty(fdset));
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_put(fdset, fd) >= 0);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(!fdset_isempty(fdset));
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier unlink(name);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier}
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalierstatic void test_fdset_steal_first(void) {
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier int fd;
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier _cleanup_fdset_free_ FDSet *fdset = NULL;
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier char name[] = "/tmp/test-fdset_steal_first.XXXXXX";
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fd >= 0);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier fdset = fdset_new();
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_steal_first(fdset) < 0);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_put(fdset, fd) >= 0);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_steal_first(fdset) == fd);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_steal_first(fdset) < 0);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_put(fdset, fd) >= 0);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier unlink(name);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier}
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalierstatic void test_fdset_new_array(void) {
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier int fds[] = {10, 11, 12, 13};
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier _cleanup_fdset_free_ FDSet *fdset = NULL;
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_new_array(&fdset, fds, 4) >= 0);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_size(fdset) == 4);
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_contains(fdset, 10));
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_contains(fdset, 11));
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_contains(fdset, 12));
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier assert_se(fdset_contains(fdset, 13));
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier}
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalierint main(int argc, char *argv[]) {
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier test_fdset_new_fill();
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier test_fdset_put_dup();
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier test_fdset_cloexec();
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier test_fdset_close_others();
2de61bbebfe6a1a97709b3277b150cacc30a79cdRonny Chevalier test_fdset_remove();
d7aeffea144c2c6bfee4e63131bb2b6c460de678Ronny Chevalier test_fdset_iterate();
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier test_fdset_isempty();
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier test_fdset_steal_first();
0805e9a9c87845be9f801efacc0a358da6991190Ronny Chevalier test_fdset_new_array();
4630bbb766d564eafee3bfcd36342fbae8534c15Ronny Chevalier
4630bbb766d564eafee3bfcd36342fbae8534c15Ronny Chevalier return 0;
106ecd769d57116ad81efdea2c27557fba062138Ronny Chevalier}