Hi, I have an extension in which a file object is created in python and passed down to a c extension which attempts to read from it or write to it. Writing to the file pointer seems to work okay, but reading from it results in EBADF and causes python to crash on exit.
I've attached the minimal (I think) c code, python code, build script, build log, and run log. Any and all help is greatly appreciated. Thanks. System: Win-XP Professional Compiler: Vc7 (MSVS 2003) Python: Python 2.4.1 Builder: SCons 0.96.1
#include <Python.h> #define MAXLEN 128 int my_read(char *buffer, int max, FILE *fp) { int n = 0; fprintf (stdout, "[c] pre-read: errno=%d, fp=%x\n", errno, fp); n = fread(buffer, 1, max, fp); fprintf (stdout, "[c] post-write: errno=%d, fp=%x, count=%d, data='%s'\n", errno, fp, n, buffer); return n; } int my_write(const char *buffer, FILE *fp) { int n = 0; fprintf (stdout, "[c] pre-write: errno=%d, fp=%x, data='%s'\n", errno, fp, buffer); n = fprintf(fp, "%s", buffer); fprintf (stdout, "[c] post-write: errno=%d, fp=%x, count=%d\n", errno, fp, n); return n; } static PyObject * my_module_my_read(PyObject *self, PyObject *args) { char buffer[MAXLEN]; int count = 0; FILE *fp = NULL; PyObject* py_file = NULL; memset((void*)&(buffer),0,sizeof(char)*MAXLEN); if (!PyArg_ParseTuple(args, "O", &py_file)) return NULL; if (PyFile_Check(py_file)) { /*count = my_read((char*)&(buffer), MAXLEN, PyFile_AsFile(py_file));*/ count = my_read((char*)&(buffer), MAXLEN, ((PyFileObject *)py_file)->f_fp); return Py_BuildValue("(is)", count, (char*)buffer); } return NULL; } static PyObject * my_module_my_write(PyObject *self, PyObject *args) { char buffer[MAXLEN]; int count = 0; FILE *fp = NULL; PyObject* py_file = NULL; const char* py_string; memset((void*)&(buffer),0,sizeof(char)*MAXLEN); if (!PyArg_ParseTuple(args, "sO", &py_string, &py_file)) return NULL; if ((PyFile_Check(py_file)) && (py_string != NULL)) { count = my_write(py_string, PyFile_AsFile(py_file)); return Py_BuildValue("i", count); } return NULL; } static PyMethodDef MyModuleMethods[] = { {"my_read", my_module_my_read, METH_VARARGS, "read at most 128 bytes from a file"}, {"my_write", my_module_my_write, METH_VARARGS, "write a string to a file"}, {NULL,NULL,0,NULL} }; PyMODINIT_FUNC initmy_module(void) { PyObject *m; m = Py_InitModule("my_module", MyModuleMethods); }
import my_module filename = "hello.txt" fp1 = open(filename, "wb") print "[py] pre-write: fp=%s" % (fp1) result1 = my_module.my_write("Hello, World!", fp1) print "[py] result=", result1 fp1.close() fp2 = open(filename, "rb") print "[py] pre-read: fp=%s" % (fp2) result2 = my_module.my_read(fp2) print "[py] result=", result2 #fp2.close() # <- crashes python here (probably because of EBADF) print "done" # <- crashes python here when fp2.close() is commented out
SConstruct
Description: Binary data
build.log
Description: Binary data
run.log
Description: Binary data
-- http://mail.python.org/mailman/listinfo/python-list