@@ -502,13 +502,68 @@ fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
502502 Py_RETURN_NONE ;
503503}
504504
505+
506+ /*[clinic input]
507+ fcntl.preallocate
508+
509+ fd: fildes
510+ flags: int
511+ posmode: int
512+ offset: long
513+ length: long
514+ /
515+
516+ Preallocate file storage space.
517+
518+ This is a wrapper around the F_PREALLOCATE fcntl command.
519+ [clinic start generated code]*/
520+
521+ static PyObject *
522+ fcntl_preallocate_impl (PyObject * module , int fd , int flags , int posmode ,
523+ long offset , long length )
524+ /*[clinic end generated code: output=4934b8a4dc1f5dc1 input=b8e76ad8be51da32]*/
525+ {
526+ #ifdef F_PREALLOCATE
527+ int ret ;
528+ int async_err = 0 ;
529+
530+ if (PySys_Audit ("fcntl.preallocate" , "iiill" , fd , flags , posmode , offset , length ) < 0 ) {
531+ return NULL ;
532+ }
533+
534+ struct fstore fstore = {
535+ .fst_flags = (unsigned int )flags ,
536+ .fst_posmode = posmode ,
537+ .fst_offset = (off_t )offset ,
538+ .fst_length = (off_t )length ,
539+ .fst_bytesalloc = 0
540+ };
541+
542+ do {
543+ Py_BEGIN_ALLOW_THREADS
544+ ret = fcntl (fd , F_PREALLOCATE , & fstore );
545+ Py_END_ALLOW_THREADS
546+ } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals ()));
547+
548+ if (ret < 0 ) {
549+ return !async_err ? PyErr_SetFromErrno (PyExc_OSError ) : NULL ;
550+ }
551+
552+ return PyLong_FromLong ((long )fstore .fst_bytesalloc );
553+ #else
554+ PyErr_SetString (PyExc_OSError , "F_PREALLOCATE not supported on this platform" );
555+ return NULL ;
556+ #endif
557+ }
558+
505559/* List of functions */
506560
507561static PyMethodDef fcntl_methods [] = {
508562 FCNTL_FCNTL_METHODDEF
509563 FCNTL_IOCTL_METHODDEF
510564 FCNTL_FLOCK_METHODDEF
511565 FCNTL_LOCKF_METHODDEF
566+ FCNTL_PREALLOCATE_METHODDEF
512567 {NULL , NULL } /* sentinel */
513568};
514569
@@ -687,6 +742,18 @@ all_ins(PyObject* m)
687742#ifdef F_NOCACHE
688743 if (PyModule_AddIntMacro (m , F_NOCACHE )) return -1 ;
689744#endif
745+ #ifdef F_PREALLOCATE
746+ if (PyModule_AddIntMacro (m , F_PREALLOCATE )) return -1 ;
747+ #endif
748+ #ifdef F_ALLOCATECONTIG
749+ if (PyModule_AddIntMacro (m , F_ALLOCATECONTIG )) return -1 ;
750+ #endif
751+ #ifdef F_ALLOCATEALL
752+ if (PyModule_AddIntMacro (m , F_ALLOCATEALL )) return -1 ;
753+ #endif
754+ #ifdef F_ALLOCATEPERSIST
755+ if (PyModule_AddIntMacro (m , F_ALLOCATEPERSIST )) return -1 ;
756+ #endif
690757
691758/* FreeBSD specifics */
692759#ifdef F_DUP2FD
0 commit comments