3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering This file is part of systemd.
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering Copyright 2010 Lennart Poettering
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering systemd is free software; you can redistribute it and/or modify it
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering under the terms of the GNU Lesser General Public License as published by
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering (at your option) any later version.
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering systemd is distributed in the hope that it will be useful, but
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering Lesser General Public License for more details.
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering You should have received a copy of the GNU Lesser General Public License
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * Just ignore EINTR; a retry loop is the wrong thing to do on
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * https://bugzilla.gnome.org/show_bug.cgi?id=682819
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * Like close_nointr() but cannot fail. Guarantees errno is
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * unchanged. Is a NOP with negative fds passed, and returns
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * -1, so that it can be used in this syntax:
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * fd = safe_close(fd);
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* The kernel might return pretty much any error code
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * via close(), but the fd will be closed anyway. The
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * only condition we want to check for here is whether
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * the fd was invalid at all... */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering if (p[0] == p[1]) {
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* Special case pairs which use the same fd in both
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * directions... */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poetteringvoid close_many(const int fds[], unsigned n_fd) {
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering for (i = 0; i < n_fd; i++)
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* Same as close_nointr(), but for fclose() */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* Same as safe_close(), but for fclose() */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering assert_se(closedir(d) >= 0 || errno != EBADF);
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering_pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering for (i = 0; i < n_fdset; i++)
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poetteringint close_all_fds(const int except[], unsigned n_except) {
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* When /proc isn't available (for example in chroots)
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * the fallback is brute forcing through the fd
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* Let's better ignore this, just in case */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* Valgrind has its own FD and doesn't want to have it closed */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* Compares two file descriptors. Note that semantics are
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * quite different depending on whether we have kcmp() or we
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * don't. If we have kcmp() this will only return true for
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * dup()ed file descriptors, but not otherwise. If we don't
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * have kcmp() this will also return true for two fds of the same
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * file, created by separate open() calls. Since we use this
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * call mostly for filtering out duplicates in the fd store
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * this difference hopefully doesn't matter too much. */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* Try to use kcmp() if we have it. */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* We don't have kcmp(), use fstat() instead. */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* We consider all device fds different, since two device fds
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * might refer to quite different device contexts even though
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * they share the same inode and backing dev_t. */
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering /* The fds refer to the same inode on disk, let's also check
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * if they have the same fd flags. This is useful to
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering * distinguish the read and write side of a pipe created with
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering const char *p;
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering /* Validates a name for $LISTEN_FDNAMES. We basically allow
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering * everything ASCII that's not a control character. Also, as
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering * special exception the ":" character is not allowed, as we
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering * use that as field separator in $LISTEN_FDNAMES.
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering * Note that the empty string is explicitly allowed
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering * here. However, we limit the length of the names to 255
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering * characters. */
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering for (p = s; *p; p++) {
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering if (*p >= 127)
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering if (*p == ':')
4fee397531c97d22e41fb3f02452e82d412fe2b5Lennart Poettering return p - s < 256;