@@ -59,7 +59,6 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
59
59
int ret ;
60
60
char * str ;
61
61
Py_ssize_t len ;
62
- char buf [1024 ];
63
62
int async_err = 0 ;
64
63
65
64
if (PySys_Audit ("fcntl.fcntl" , "iiO" , fd , code , arg ? arg : Py_None ) < 0 ) {
@@ -68,20 +67,15 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
68
67
69
68
if (arg != NULL ) {
70
69
int parse_result ;
71
- #ifdef F_KINFO
72
- if (code == F_KINFO ) {
73
- PyErr_SetString (PyExc_ValueError ,
74
- "fcntl arg not permitted with F_KINFO" );
75
- }
76
- #endif
77
70
78
71
if (PyArg_Parse (arg , "s#" , & str , & len )) {
72
+ char buf [4096 ];
79
73
if ((size_t )len > sizeof buf ) {
80
74
PyErr_SetString (PyExc_ValueError ,
81
75
"fcntl string arg too long" );
82
76
return NULL ;
83
77
}
84
- memcpy (buf , str , len );
78
+ memcpy (buf , str , len );
85
79
do {
86
80
Py_BEGIN_ALLOW_THREADS
87
81
ret = fcntl (fd , code , buf );
@@ -103,21 +97,6 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
103
97
}
104
98
}
105
99
106
- #ifdef F_KINFO
107
- if (code == F_KINFO ) {
108
- struct kinfo_file f = {.kf_structsize = KINFO_FILE_SIZE };
109
- do {
110
- Py_BEGIN_ALLOW_THREADS
111
- ret = fcntl (fd , code , & f );
112
- Py_END_ALLOW_THREADS
113
- } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals ()));
114
- if (ret < 0 ) {
115
- return !async_err ? PyErr_SetFromErrno (PyExc_OSError ) : NULL ;
116
- }
117
- return PyBytes_FromString (f .kf_path );
118
- }
119
- #endif
120
-
121
100
do {
122
101
Py_BEGIN_ALLOW_THREADS
123
102
ret = fcntl (fd , code , (int )int_arg );
@@ -463,13 +442,70 @@ fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
463
442
Py_RETURN_NONE ;
464
443
}
465
444
445
+ #ifdef F_KINFO
446
+ /*[clinic input]
447
+ fcntl.kinfoalloc
448
+
449
+ Return a FreeBSD's kinfo_file buffer with the `kf_structsize` field pre-initialised.
450
+
451
+ [clinic start generated code]*/
452
+
453
+ static PyObject *
454
+ fcntl_kinfoalloc_impl (PyObject * module )
455
+ /*[clinic end generated code: output=c61603aeb3d91a0e input=28e2e82cc296f82c]*/
456
+ {
457
+ char buf [KINFO_FILE_SIZE + 1 ];
458
+ ((struct kinfo_file * )buf )-> kf_structsize = KINFO_FILE_SIZE ;
459
+ return PyBytes_FromStringAndSize (buf , KINFO_FILE_SIZE );
460
+ }
461
+
462
+ /*[clinic input]
463
+ fcntl.kinfodict
464
+
465
+ arg: object(c_default='NULL') = 0
466
+ /
467
+
468
+ Return a FreeBSD's kinfo_file as dictionary.
469
+
470
+ [clinic start generated code]*/
471
+
472
+ static PyObject *
473
+ fcntl_kinfodict_impl (PyObject * module , PyObject * arg )
474
+ /*[clinic end generated code: output=3873ae40aeac8e7f input=faba1f2ce099752f]*/
475
+ {
476
+ PyObject * dict ;
477
+
478
+ if (PySys_Audit ("fcntl.kinfodict" , "O" , arg ) < 0 || arg == NULL ) {
479
+ return NULL ;
480
+ }
481
+
482
+ dict = PyDict_New ();
483
+ if (dict ) {
484
+ struct kinfo_file * kf ;
485
+ kf = (struct kinfo_file * )PyBytes_AsString (arg );
486
+
487
+ PyDict_SetItemString (dict , "status" , PyLong_FromLong (kf -> kf_status ));
488
+ PyDict_SetItemString (dict , "type" , PyLong_FromLong (kf -> kf_type ));
489
+ PyDict_SetItemString (dict , "offset" , PyLong_FromLongLong (kf -> kf_offset ));
490
+ PyDict_SetItemString (dict , "path" , PyBytes_FromString (kf -> kf_path ));
491
+ return dict ;
492
+ }
493
+
494
+ PyErr_SetString (PyExc_ValueError , "fcntl.kinfodict could not create its dictionary" );
495
+ return NULL ;
496
+ }
497
+
498
+ #endif
499
+
466
500
/* List of functions */
467
501
468
502
static PyMethodDef fcntl_methods [] = {
469
503
FCNTL_FCNTL_METHODDEF
470
504
FCNTL_IOCTL_METHODDEF
471
505
FCNTL_FLOCK_METHODDEF
472
506
FCNTL_LOCKF_METHODDEF
507
+ FCNTL_KINFOALLOC_METHODDEF
508
+ FCNTL_KINFODICT_METHODDEF
473
509
{NULL , NULL } /* sentinel */
474
510
};
475
511
0 commit comments