Page MenuHomeFreeBSD

D21206.id62200.diff
No OneTemporary

D21206.id62200.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,69 @@
+.\" 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 executes a callback for each file descriptor open at the time of its
+invocation.
+The
+.Nm
+function passes the
+.Ar cbd
+argument into the callback, along with each file descriptor.
+If
+.Ar cbd
+returns non-zero, iteration is terminated.
+It is async-signal-safe.
+.Sh RETURN VALUES
+The
+.Nm
+function always returns 0.
+.Sh SEE ALSO
+.Xr closefrom 2 ,
+.Xr kinfo_getfile 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in SunOS.
+.Sh BUGS
+It 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,89 @@
+/*-
+ * 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];
+ size_t oldlen, newlen;
+ int error, i, j, len;
+ NDSLOTTYPE *buf, tmp;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_FDMAP;
+ mib[3] = 0;
+
+ oldlen = 0;
+ for (;;) {
+ error = sysctl(mib, nitems(mib), NULL, &newlen, NULL, 0);
+ if (error == -1)
+ return (0);
+ if (oldlen < newlen) {
+ oldlen = newlen;
+ buf = alloca(newlen);
+ }
+ newlen = oldlen;
+ error = sysctl(mib, nitems(mib), buf, &newlen, NULL, 0);
+ if (error == 0)
+ break;
+ if (errno != ENOMEM)
+ return (0);
+ }
+
+ /*
+ * Go through the full file list. The fdmap is an integral multiple of
+ * sizeof(NDSLOTTYPE).
+ */
+ len = howmany(newlen, 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)
+ return (error);
+ }
+ }
+ }
+ return (0);
+}
Index: lib/libc/sys/sigaction.2
===================================================================
--- lib/libc/sys/sigaction.2
+++ lib/libc/sys/sigaction.2
@@ -393,6 +393,7 @@
.Fn fchown ,
.Fn fchownat ,
.Fn fcntl ,
+.Fn fdwalk ,
.Fn fork ,
.Fn fstat ,
.Fn fstatat ,
Index: sys/kern/kern_descrip.c
===================================================================
--- sys/kern/kern_descrip.c
+++ sys/kern/kern_descrip.c
@@ -144,6 +144,7 @@
#define NDSLOT(x) ((x) / NDENTRIES)
#define NDBIT(x) ((NDSLOTTYPE)1 << ((x) % NDENTRIES))
#define NDSLOTS(x) (((x) + NDENTRIES - 1) / NDENTRIES)
+#define NFD2MAPSIZE(x) (NDSLOTS(x) * NDSLOTSIZE)
/*
* SLIST entry used to keep track of ofiles which must be reclaimed when
@@ -1680,7 +1681,7 @@
* entries than the table can hold.
*/
if (NDSLOTS(nnfiles) > NDSLOTS(onfiles)) {
- nmap = malloc(NDSLOTS(nnfiles) * NDSLOTSIZE, M_FILEDESC,
+ nmap = malloc(NFD2MAPSIZE(nnfiles), M_FILEDESC,
M_ZERO | M_WAITOK);
/* copy over the old data and update the pointer */
memcpy(nmap, omap, NDSLOTS(onfiles) * sizeof(*omap));
@@ -3313,6 +3314,55 @@
CTLFLAG_RD|CTLFLAG_CAPRD|CTLFLAG_MPSAFE, sysctl_kern_proc_nfds,
"Number of open file descriptors");
+static int
+sysctl_kern_proc_fdmap(SYSCTL_HANDLER_ARGS)
+{
+ struct filedesc *fdp;
+ NDSLOTTYPE lmap[NDSLOTS(NDFILE) * 16];
+ NDSLOTTYPE *map;
+ size_t bsize, csize;
+ int error;
+
+ CTASSERT(sizeof(lmap) <= 128);
+
+ if (*(int *)arg1 != 0)
+ return (EINVAL);
+
+ fdp = curproc->p_fd;
+
+ if (req->oldptr == NULL)
+ return (SYSCTL_OUT(req, NULL, NFD2MAPSIZE(fdp->fd_nfiles)));
+
+ if (curproc->p_numthreads == 1 && fdp->fd_refcnt == 1)
+ /* No need to lock anything as only we can modify the map. */
+ return (SYSCTL_OUT(req, fdp->fd_map, NFD2MAPSIZE(fdp->fd_nfiles)));
+
+ /* Potential other threads modifying the map. */
+ map = lmap;
+ bsize = sizeof(lmap);
+ for (;;) {
+ FILEDESC_SLOCK(fdp);
+ csize = NFD2MAPSIZE(fdp->fd_nfiles);
+ if (bsize >= csize)
+ break;
+ FILEDESC_SUNLOCK(fdp);
+ if (map != lmap)
+ free(map, M_TEMP);
+ bsize = csize;
+ map = malloc(bsize, M_TEMP, M_WAITOK);
+ }
+ memcpy(map, fdp->fd_map, csize);
+ FILEDESC_SUNLOCK(fdp);
+ error = SYSCTL_OUT(req, map, csize);
+ if (map != lmap)
+ free(map, M_TEMP);
+ return (error);
+}
+
+static SYSCTL_NODE(_kern_proc, KERN_PROC_FDMAP, fdmap,
+ CTLFLAG_RD|CTLFLAG_CAPRD|CTLFLAG_MPSAFE, sysctl_kern_proc_fdmap,
+ "File descriptor map");
+
/*
* Get file structures globally.
*/
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, Jan 19, 4:21 AM (8 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15922609
Default Alt Text
D21206.id62200.diff (9 KB)

Event Timeline