summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-03-28 11:17:23 +0200
committerLennart Poettering <lennart@poettering.net>2023-03-29 19:09:10 +0200
commitbdcad22e8e508308032cba5f8c2d5c093adb7d87 (patch)
tree7ec23bf6b1c13ac10e45190dde4fb42fe56190c5
parent08a0ebc6beef91c54931160b43c10cbc610f7533 (diff)
downloadsystemd-bdcad22e8e508308032cba5f8c2d5c093adb7d87.tar.gz
fdset: add new helper to convert an fdset to an array
-rw-r--r--src/shared/fdset.c41
-rw-r--r--src/shared/fdset.h2
2 files changed, 32 insertions, 11 deletions
diff --git a/src/shared/fdset.c b/src/shared/fdset.c
index 4427c1ce68..49928b66d6 100644
--- a/src/shared/fdset.c
+++ b/src/shared/fdset.c
@@ -192,24 +192,43 @@ int fdset_new_listen_fds(FDSet **ret, bool unset) {
return 0;
}
-int fdset_close_others(FDSet *fds) {
- _cleanup_free_ int *a = NULL;
- size_t j = 0, m;
+int fdset_to_array(FDSet *fds, int **ret) {
+ unsigned j = 0, m;
void *e;
+ int *a;
- m = fdset_size(fds);
- if (m > 0) {
- a = new(int, m);
- if (!a)
- return -ENOMEM;
+ assert(ret);
- SET_FOREACH(e, MAKE_SET(fds))
- a[j++] = PTR_TO_FD(e);
+ m = fdset_size(fds);
+ if (m > INT_MAX) /* We want to be able to return an "int" */
+ return -ENOMEM;
+ if (m == 0) {
+ *ret = NULL; /* suppress array allocation if empty */
+ return 0;
}
+ a = new(int, m);
+ if (!a)
+ return -ENOMEM;
+
+ SET_FOREACH(e, MAKE_SET(fds))
+ a[j++] = PTR_TO_FD(e);
+
assert(j == m);
- return close_all_fds(a, j);
+ *ret = TAKE_PTR(a);
+ return (int) m;
+}
+
+int fdset_close_others(FDSet *fds) {
+ _cleanup_free_ int *a = NULL;
+ int n;
+
+ n = fdset_to_array(fds, &a);
+ if (n < 0)
+ return n;
+
+ return close_all_fds(a, n);
}
unsigned fdset_size(FDSet *fds) {
diff --git a/src/shared/fdset.h b/src/shared/fdset.h
index 39d15ee4aa..0e55db81b4 100644
--- a/src/shared/fdset.h
+++ b/src/shared/fdset.h
@@ -24,6 +24,8 @@ int fdset_new_listen_fds(FDSet **ret, bool unset);
int fdset_cloexec(FDSet *fds, bool b);
+int fdset_to_array(FDSet *fds, int **ret);
+
int fdset_close_others(FDSet *fds);
unsigned fdset_size(FDSet *fds);