Skip to content

Commit 62ea0ae

Browse files
committed
fcntl module update supporting FreeBSD's F_KINFO proposal.
1 parent 5de39f4 commit 62ea0ae

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

Modules/fcntlmodule.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
#include <stropts.h>
1616
#endif
1717

18+
#ifdef __FreeBSD__
19+
#include <sys/user.h>
20+
#endif
21+
1822
/*[clinic input]
1923
module fcntl
2024
[clinic start generated code]*/
@@ -60,6 +64,13 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
6064

6165
if (arg != NULL) {
6266
int parse_result;
67+
#ifdef F_KINFO
68+
if (code == F_KINFO) {
69+
PyErr_SetString(PyExc_ValueError,
70+
"fnctl arg not permitted with F_KINFO");
71+
return NULL;
72+
}
73+
#endif
6374

6475
if (PyArg_Parse(arg, "s#", &str, &len)) {
6576
if ((size_t)len > sizeof buf) {
@@ -89,6 +100,33 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
89100
}
90101
}
91102

103+
#ifdef F_KINFO
104+
if (code == F_KINFO) {
105+
struct kinfo_file f = {.kf_structsize = KINFO_FILE_SIZE};
106+
do {
107+
Py_BEGIN_ALLOW_THREADS
108+
ret = fcntl(fd, code, &f);
109+
Py_END_ALLOW_THREADS
110+
} while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
111+
if (ret < 0) {
112+
return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
113+
}
114+
115+
PyObject *ret = PyDict_New();
116+
if (ret) {
117+
PyDict_SetItemString(ret, "status", PyLong_FromLong(f.kf_status));
118+
PyDict_SetItemString(ret, "type", PyLong_FromLong(f.kf_type));
119+
PyDict_SetItemString(ret, "offset", PyLong_FromLongLong(f.kf_offset));
120+
PyDict_SetItemString(ret, "path", PyBytes_FromString(f.kf_path));
121+
return ret;
122+
} else {
123+
PyErr_SetString(PyExc_ValueError,
124+
"fcntl could not create F_KINFO data");
125+
return NULL;
126+
}
127+
}
128+
#endif
129+
92130
do {
93131
Py_BEGIN_ALLOW_THREADS
94132
ret = fcntl(fd, code, (int)int_arg);
@@ -588,6 +626,9 @@ all_ins(PyObject* m)
588626
#ifdef F_DUP2FD_CLOEXEC
589627
if (PyModule_AddIntMacro(m, F_DUP2FD_CLOEXEC)) return -1;
590628
#endif
629+
#ifdef F_KINFO
630+
if (PyModule_AddIntMacro(m, F_KINFO)) return -1;
631+
#endif
591632

592633
/* For F_{GET|SET}FL */
593634
#ifdef FD_CLOEXEC

0 commit comments

Comments
 (0)