@@ -1098,3 +1098,61 @@ PyFile_WriteString(char *s, PyObject *f)
10981098 else
10991099 return -1 ;
11001100}
1101+
1102+ /* Try to get a file-descriptor from a Python object. If the object
1103+ is an integer or long integer, its value is returned. If not, the
1104+ object's fileno() method is called if it exists; the method must return
1105+ an integer or long integer, which is returned as the file descriptor value.
1106+ -1 is returned on failure.
1107+ */
1108+
1109+ int PyObject_AsFileDescriptor (PyObject * o )
1110+ {
1111+ int fd ;
1112+ PyObject * meth ;
1113+
1114+ if (PyInt_Check (o )) {
1115+ fd = PyInt_AsLong (o );
1116+ }
1117+ else if (PyLong_Check (o )) {
1118+ fd = PyLong_AsLong (o );
1119+ }
1120+ else if ((meth = PyObject_GetAttrString (o , "fileno" )) != NULL )
1121+ {
1122+ PyObject * fno = PyEval_CallObject (meth , NULL );
1123+ Py_DECREF (meth );
1124+ if (fno == NULL )
1125+ return -1 ;
1126+
1127+ if (PyInt_Check (fno )) {
1128+ fd = PyInt_AsLong (fno );
1129+ Py_DECREF (fno );
1130+ }
1131+ else if (PyLong_Check (fno )) {
1132+ fd = PyLong_AsLong (fno );
1133+ Py_DECREF (fno );
1134+ }
1135+ else {
1136+ PyErr_SetString (PyExc_TypeError ,
1137+ "fileno() returned a non-integer" );
1138+ Py_DECREF (fno );
1139+ return -1 ;
1140+ }
1141+ }
1142+ else {
1143+ PyErr_SetString (PyExc_TypeError ,
1144+ "argument must be an int, or have a fileno() method." );
1145+ return -1 ;
1146+ }
1147+
1148+ if (fd < 0 ) {
1149+ PyErr_Format (PyExc_ValueError ,
1150+ "file descriptor cannot be a negative integer (%i)" ,
1151+ fd );
1152+ return -1 ;
1153+ }
1154+ return fd ;
1155+ }
1156+
1157+
1158+
0 commit comments