summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/fdset.c83
-rw-r--r--src/core/fdset.h12
2 files changed, 88 insertions, 7 deletions
diff --git a/src/core/fdset.c b/src/core/fdset.c
index fe918cd8cc..fd27398ebb 100644
--- a/src/core/fdset.c
+++ b/src/core/fdset.c
@@ -28,6 +28,7 @@
#include "util.h"
#include "macro.h"
#include "fdset.h"
+#include "sd-daemon.h"
#define MAKE_SET(s) ((Set*) s)
#define MAKE_FDSET(s) ((FDSet*) s)
@@ -75,10 +76,12 @@ int fdset_put_dup(FDSet *s, int fd) {
assert(s);
assert(fd >= 0);
- if ((copy = fcntl(fd, F_DUPFD_CLOEXEC, 3)) < 0)
+ copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ if (copy < 0)
return -errno;
- if ((r = fdset_put(s, copy)) < 0) {
+ r = fdset_put(s, copy);
+ if (r < 0) {
close_nointr_nofail(copy);
return r;
}
@@ -108,13 +111,15 @@ int fdset_new_fill(FDSet **_s) {
assert(_s);
- /* Creates an fdsets and fills in all currently open file
+ /* Creates an fdset and fills in all currently open file
* descriptors. */
- if (!(d = opendir("/proc/self/fd")))
+ d = opendir("/proc/self/fd");
+ if (!d)
return -errno;
- if (!(s = fdset_new())) {
+ s = fdset_new();
+ if (!s) {
r = -ENOMEM;
goto finish;
}
@@ -125,7 +130,8 @@ int fdset_new_fill(FDSet **_s) {
if (ignore_file(de->d_name))
continue;
- if ((r = safe_atoi(de->d_name, &fd)) < 0)
+ r = safe_atoi(de->d_name, &fd);
+ if (r < 0)
goto finish;
if (fd < 3)
@@ -134,7 +140,8 @@ int fdset_new_fill(FDSet **_s) {
if (fd == dirfd(d))
continue;
- if ((r = fdset_put(s, fd)) < 0)
+ r = fdset_put(s, fd);
+ if (r < 0)
goto finish;
}
@@ -165,3 +172,65 @@ int fdset_cloexec(FDSet *fds, bool b) {
return 0;
}
+
+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;
+}
+
+int fdset_close_others(FDSet *fds) {
+ void *e;
+ Iterator i;
+ int *a;
+ unsigned j, m;
+
+ j = 0, m = fdset_size(fds);
+ a = alloca(sizeof(int) * m);
+ SET_FOREACH(e, MAKE_SET(fds), i)
+ a[j++] = PTR_TO_FD(e);
+
+ assert(j == m);
+
+ return close_all_fds(a, j);
+}
+
+unsigned fdset_size(FDSet *fds) {
+ return set_size(MAKE_SET(fds));
+}
+
+int fdset_iterate(FDSet *s, Iterator *i) {
+ void *p;
+
+ p = set_iterate(MAKE_SET(s), i);
+ if (!p)
+ return -ENOENT;
+
+ return PTR_TO_FD(p);
+}
diff --git a/src/core/fdset.h b/src/core/fdset.h
index c3e408c8ad..a7bd5e2b40 100644
--- a/src/core/fdset.h
+++ b/src/core/fdset.h
@@ -21,6 +21,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "set.h"
+
typedef struct FDSet FDSet;
FDSet* fdset_new(void);
@@ -33,5 +35,15 @@ bool fdset_contains(FDSet *s, int fd);
int fdset_remove(FDSet *s, int fd);
int fdset_new_fill(FDSet **_s);
+int fdset_new_listen_fds(FDSet **_s, bool unset);
int fdset_cloexec(FDSet *fds, bool b);
+
+int fdset_close_others(FDSet *fds);
+
+unsigned fdset_size(FDSet *fds);
+
+int fdset_iterate(FDSet *s, Iterator *i);
+
+#define FDSET_FOREACH(fd, fds, i) \
+ for ((i) = ITERATOR_FIRST, (fd) = fdset_iterate((fds), &(i)); (fd) >= 0; (fd) = fdset_iterate((fds), &(i)))