Skip to content

Commit d15a9af

Browse files
committed
fcntl add the F_KINFO constant for FreeBSD 13.1 and onwards.
1 parent bf26bdf commit d15a9af

File tree

7 files changed

+47
-2
lines changed

7 files changed

+47
-2
lines changed

Doc/library/fcntl.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ descriptor.
5757
``FICLONERANGE`` constants, which allow to share some data of one file with
5858
another file by reflinking on some filesystems (e.g., btrfs, OCFS2, and
5959
XFS). This behavior is commonly referred to as "copy-on-write".
60+
On FreeBSD >= 13.1, the :mod:`fcntl` module exposes the ``F_KINFO``
61+
constant which allow to get the path of the file descriptor.
6062

6163
The module defines the following functions:
6264

Doc/whatsnew/3.12.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ dis
253253
:data:`~dis.hasarg` collection instead.
254254
(Contributed by Irit Katriel in :gh:`94216`.)
255255

256+
fcntl
257+
-----
258+
259+
Added constants :data:`~fcntl.F_KINFO`
260+
256261
os
257262
--
258263

Lib/test/test_fcntl.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,13 @@ def test_fcntl_f_getpath(self):
190190
res = fcntl.fcntl(self.f.fileno(), fcntl.F_GETPATH, bytes(len(expected)))
191191
self.assertEqual(expected, res)
192192

193+
@unittest.skipUnless(sys.platform.startswith("freebsd") and hasattr(fcntl, "F_KINFO"), "F_KINFO is only available on freebsd")
194+
def test_fcntl_f_kinfo(self):
195+
self.f = open(TESTFN, 'wb')
196+
expected = os.path.abspath(TESTFN).encode('utf-8')
197+
res = fcntl.fcntl(self.f.fileno(), fcntl.F_KINFO)
198+
self.assertEqual(expected, res)
199+
193200
@unittest.skipUnless(
194201
hasattr(fcntl, "F_SETPIPE_SZ") and hasattr(fcntl, "F_GETPIPE_SZ"),
195202
"F_SETPIPE_SZ and F_GETPIPE_SZ are not available on all platforms.")

Modules/fcntlmodule.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#include <stropts.h>
1919
#endif
2020

21+
#ifdef HAVE_SYS_USER_H
22+
#include <sys/user.h>
23+
#endif
24+
2125
/*[clinic input]
2226
module fcntl
2327
[clinic start generated code]*/
@@ -63,6 +67,12 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
6367

6468
if (arg != NULL) {
6569
int parse_result;
70+
#ifdef F_KINFO
71+
if (code == F_KINFO) {
72+
PyErr_SetString(PyExc_ValueError,
73+
"fcntl arg not permitted with F_KINFO");
74+
}
75+
#endif
6676

6777
if (PyArg_Parse(arg, "s#", &str, &len)) {
6878
if ((size_t)len > sizeof buf) {
@@ -92,6 +102,21 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
92102
}
93103
}
94104

105+
#ifdef F_KINFO
106+
if (code == F_KINFO) {
107+
struct kinfo_file f = {.kf_structsize = KINFO_FILE_SIZE};
108+
do {
109+
Py_BEGIN_ALLOW_THREADS
110+
ret = fcntl(fd, code, &f);
111+
Py_END_ALLOW_THREADS
112+
} while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
113+
if (ret < 0) {
114+
return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
115+
}
116+
return PyBytes_FromString(f.kf_path);
117+
}
118+
#endif
119+
95120
do {
96121
Py_BEGIN_ALLOW_THREADS
97122
ret = fcntl(fd, code, (int)int_arg);
@@ -483,6 +508,9 @@ all_ins(PyObject* m)
483508
#ifdef F_DUPFD_CLOEXEC
484509
if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
485510
#endif
511+
#ifdef F_KINFO
512+
if (PyModule_AddIntMacro(m, F_KINFO)) return -1;
513+
#endif
486514
#ifdef F_GETFD
487515
if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
488516
#endif

configure

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2714,7 +2714,7 @@ AC_CHECK_HEADERS([ \
27142714
sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/poll.h \
27152715
sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \
27162716
sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysmacros.h sys/termio.h sys/time.h sys/times.h \
2717-
sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \
2717+
sys/types.h sys/uio.h sys/un.h sys/user.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \
27182718
termios.h util.h utime.h utmp.h \
27192719
])
27202720
AC_HEADER_DIRENT

pyconfig.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,9 @@
13781378
/* Define to 1 if you have the <sys/un.h> header file. */
13791379
#undef HAVE_SYS_UN_H
13801380

1381+
/* Define to 1 if you have the <sys/user.h> header file. */
1382+
#undef HAVE_SYS_USER_H
1383+
13811384
/* Define to 1 if you have the <sys/utsname.h> header file. */
13821385
#undef HAVE_SYS_UTSNAME_H
13831386

0 commit comments

Comments
 (0)