T
travis ray
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. It also 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
P.S. Sorry for including everything in one message. I keep getting
bounced when I attach them.
### file:my_module.c -------------------------------------------------
#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));
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);
}
### file: my_module.py ------------------------------------------------
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 EBADF when fp2.close() is called
print "done"
# crashes python here when fp2.close() is commented out
### file: Sconstruct --------------------------------------------------
env = Environment()
import os
python_include_path = os.path.join(os.path.sep,'Python24','include')
python_lib_path = os.path.join(os.path.sep,'Python24','libs')
python_libs = 'python24'
my_module_name = 'my_module'
my_module_sources = 'my_module.c'
library = env.SharedLibrary(my_module_name,
my_module_sources,
CPPPATH=[python_include_path],
LIBPATH=[python_lib_path],
LIBS=[python_libs])
### file: build.log ---------------------------------------------------
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
cl /nologo /I\Python24\include /c my_module.c /Fomy_module.obj
my_module.c
link /nologo /dll /out:my_module.dll /implib:my_module.lib
/LIBPATH:\Python24\libs python24.lib my_module.obj
Creating library my_module.lib and object my_module.exp
scons: done building targets.
### file: run.log -----------------------------------------------------
[py] pre-write: fp=<open file 'hello.txt', mode 'wb' at 0x009B54A0>
[c] pre-write: errno=0, fp=7c38b548, data='Hello, World!'
[c] post-write: errno=0, fp=7c38b548, count=13
[py] result= 13
[py] pre-read: fp=<open file 'hello.txt', mode 'rb' at 0x009B5608>
[c] pre-read: errno=0, fp=7c38b548
[c] post-write: errno=9, fp=7c38b548, count=0, data=''
[py] result= (0, '')
done
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. It also 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
P.S. Sorry for including everything in one message. I keep getting
bounced when I attach them.
### file:my_module.c -------------------------------------------------
#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));
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);
}
### file: my_module.py ------------------------------------------------
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 EBADF when fp2.close() is called
print "done"
# crashes python here when fp2.close() is commented out
### file: Sconstruct --------------------------------------------------
env = Environment()
import os
python_include_path = os.path.join(os.path.sep,'Python24','include')
python_lib_path = os.path.join(os.path.sep,'Python24','libs')
python_libs = 'python24'
my_module_name = 'my_module'
my_module_sources = 'my_module.c'
library = env.SharedLibrary(my_module_name,
my_module_sources,
CPPPATH=[python_include_path],
LIBPATH=[python_lib_path],
LIBS=[python_libs])
### file: build.log ---------------------------------------------------
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
cl /nologo /I\Python24\include /c my_module.c /Fomy_module.obj
my_module.c
link /nologo /dll /out:my_module.dll /implib:my_module.lib
/LIBPATH:\Python24\libs python24.lib my_module.obj
Creating library my_module.lib and object my_module.exp
scons: done building targets.
### file: run.log -----------------------------------------------------
[py] pre-write: fp=<open file 'hello.txt', mode 'wb' at 0x009B54A0>
[c] pre-write: errno=0, fp=7c38b548, data='Hello, World!'
[c] post-write: errno=0, fp=7c38b548, count=13
[py] result= 13
[py] pre-read: fp=<open file 'hello.txt', mode 'rb' at 0x009B5608>
[c] pre-read: errno=0, fp=7c38b548
[c] post-write: errno=9, fp=7c38b548, count=0, data=''
[py] result= (0, '')
done