Page MenuHomeFreeBSD

D21206.id60815.diff
No OneTemporary

D21206.id60815.diff

Index: include/stdlib.h
===================================================================
--- include/stdlib.h
+++ include/stdlib.h
@@ -278,6 +278,7 @@
char *devname_r(__dev_t, __mode_t, char *, int);
char *fdevname(int);
char *fdevname_r(int, char *, int);
+int fdwalk(int (*)(void *, int), void *);
int getloadavg(double [], int);
const char *
getprogname(void);
Index: lib/libc/stdlib/Makefile.inc
===================================================================
--- lib/libc/stdlib/Makefile.inc
+++ lib/libc/stdlib/Makefile.inc
@@ -7,7 +7,7 @@
MISRCS+=C99_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
bsearch.c \
cxa_thread_atexit.c cxa_thread_atexit_impl.c \
- div.c exit.c getenv.c getopt.c getopt_long.c \
+ div.c exit.c fdwalk.c getenv.c getopt.c getopt_long.c \
getsubopt.c hcreate.c hcreate_r.c hdestroy_r.c heapsort.c heapsort_b.c \
hsearch_r.c imaxabs.c imaxdiv.c \
insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \
@@ -32,7 +32,7 @@
MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 \
atoi.3 atol.3 at_quick_exit.3 bsearch.3 \
- div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 \
+ div.3 exit.3 fdwalk.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 \
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
lsearch.3 memory.3 ptsname.3 qsort.3 \
quick_exit.3 \
Index: lib/libc/stdlib/Symbol.map
===================================================================
--- lib/libc/stdlib/Symbol.map
+++ lib/libc/stdlib/Symbol.map
@@ -124,6 +124,10 @@
set_constraint_handler_s;
};
+FBSD_1.6 {
+ fdwalk;
+};
+
FBSDprivate_1.0 {
__system;
_system;
Index: lib/libc/stdlib/fdwalk.3
===================================================================
--- /dev/null
+++ lib/libc/stdlib/fdwalk.3
@@ -0,0 +1,91 @@
+.\" Copyright (c) 2019 Justin Hibbits
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 9, 2019
+.Dt FDWALK 3
+.Os
+.Sh NAME
+.Nm fdwalk
+.Nd iterate over open file descriptors
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft int
+.Fn fdwalk "int (*cb)(void *, int)" "void *cbd"
+.Sh DESCRIPTION
+The
+.Nm
+function walks the list of currently open file descriptors and calls the
+.Ar cb
+callback function on each descriptor.
+The
+.Nm
+function passes the
+.Ar cbd
+argument into the callback, along with each file descriptor.
+If
+.Ar cbd
+returns non-zero, iteration over the list is terminated and the return value
+from
+.Ar cbd
+is returned up to the caller as the return value of
+.Nm .
+.Sh RETURN VALUES
+The
+.Nm
+function will return 0 on success, or the return value of the last call to the
+callback.
+It will also return -1 and set errno on errors in
+.Xr sysctl 3 ,
+and
+.Xr malloc 3 .
+No errors are defined for it.
+All errors are passed through from
+.Xr sysctl 3 ,
+.Xr malloc 3
+and the callback.
+.Sh SEE ALSO
+.Xr closefrom 2 ,
+.Xr kinfo_getfile 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in SunOS.
+.Sh BUGS
+The
+.Nm
+function is potentially not thread safe.
+It uses
+.Xr malloc 3
+and
+.Xr sysctl 3
+behind the scenes.
+It also only takes a snapshot, so any file descriptors created or removed
+after the snapshot is taken, either in another thread or in the callback
+function, are not handled.
Index: lib/libc/stdlib/fdwalk.c
===================================================================
--- /dev/null
+++ lib/libc/stdlib/fdwalk.c
@@ -0,0 +1,108 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Justin Hibbits
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/filedesc.h>
+#include <sys/sysctl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define FD(slot, bit) ((slot * sizeof(NDSLOTTYPE) * NBBY) + bit)
+
+int
+fdwalk(int (*cb)(void *, int), void *cbd)
+{
+ int mib[4];
+ int error;
+ size_t len, i, j;
+ NDSLOTTYPE *buf, tmp;
+ int retries;
+
+ len = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_FDMAP;
+ mib[3] = 0;
+
+ buf = NULL;
+ retries = 5; /* Arbitrary retry count. */
+
+ /*
+ * Try a few times to get a stable buffer. The buffer size may change
+ * if file descriptors are being created in other threads.
+ */
+ for (; retries > 0; --retries) {
+ error = sysctl(mib, nitems(mib), NULL, &len, NULL, 0);
+ if (error == -1)
+ return (-1);
+ /*
+ * Add some headroom in case more descriptors are added before
+ * the next call.
+ */
+ len = len * 4 / 3;
+ buf = reallocf(buf, len);
+ if (buf == NULL)
+ return (-1);
+ error = sysctl(mib, nitems(mib), buf, &len, NULL, 0);
+ if (error == 0)
+ break;
+ if (errno != ENOMEM) {
+ free(buf);
+ return (-1);
+ }
+ }
+ if (retries == 0) {
+ free(buf);
+ return (-1);
+ }
+ /*
+ * Go through the full file list. The fdmap is an integral multiple of
+ * sizeof(NDSLOTTYPE).
+ */
+ len = howmany(len, sizeof(NDSLOTTYPE));
+
+ for (i = 0; i < len; i++) {
+ /*
+ * Iterate over each bit in the slot, short-circuting when there
+ * are no more file descriptors in use in this slot.
+ */
+ for (j = 0, tmp = buf[i];
+ j < NBBY * sizeof(NDSLOTTYPE) && tmp != 0;
+ j++, tmp >>= 1) {
+ if (tmp & 1) {
+ error = cb(cbd, FD(i, j));
+ if (error != 0)
+ goto done;
+ }
+ }
+ }
+done:
+ free(buf);
+
+ return (error);
+}
Index: sys/kern/kern_descrip.c
===================================================================
--- sys/kern/kern_descrip.c
+++ sys/kern/kern_descrip.c
@@ -3821,6 +3821,52 @@
CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc_filedesc,
"Process filedesc entries");
+static int
+sysctl_kern_proc_fdmap(SYSCTL_HANDLER_ARGS)
+{
+ struct filedesc *fdp;
+ struct proc *p;
+ size_t size;
+ int error, *name;
+ NDSLOTTYPE *map;
+
+ name = (int *)arg1;
+
+ if (name == 0) {
+ p = curproc;
+ PROC_LOCK(p);
+ } else {
+ error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p);
+ if (error != 0)
+ return (error);
+ }
+
+ fdp = fdhold(p);
+ PROC_UNLOCK(p);
+ if (fdp == NULL)
+ return (ENOENT);
+ FILEDESC_SLOCK(fdp);
+ map = NULL;
+ do {
+ if (map != NULL)
+ free(map, M_TEMP);
+ size = NDSLOTS(fdp->fd_nfiles) * NDSLOTSIZE;
+ FILEDESC_SUNLOCK(fdp);
+ map = malloc(size, M_TEMP, M_WAITOK);
+ FILEDESC_SLOCK(fdp);
+ } while (size < NDSLOTS(fdp->fd_nfiles) * NDSLOTSIZE);
+ memcpy(map, fdp->fd_map, size);
+ FILEDESC_SUNLOCK(fdp);
+ fddrop(fdp);
+ error = SYSCTL_OUT(req, map, size);
+ free(map, M_TEMP);
+ return (error);
+}
+
+static SYSCTL_NODE(_kern_proc, KERN_PROC_FDMAP, fdmap,
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc_fdmap,
+ "Process file descriptor map");
+
/*
* Store a process current working directory information to sbuf.
*
Index: sys/sys/sysctl.h
===================================================================
--- sys/sys/sysctl.h
+++ sys/sys/sysctl.h
@@ -977,6 +977,7 @@
#define KERN_PROC_SIGTRAMP 41 /* signal trampoline location */
#define KERN_PROC_CWD 42 /* process current working directory */
#define KERN_PROC_NFDS 43 /* number of open file descriptors */
+#define KERN_PROC_FDMAP 44 /* file descriptor map */
/*
* KERN_IPC identifiers

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 16, 8:25 PM (1 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25387145
Default Alt Text
D21206.id60815.diff (9 KB)

Event Timeline