Hello.
I have this C API Python function from the rpm module:
static PyObject * setLogFile (PyObject * self, PyObject *arg)
{
FILE *fp;
int fdno = PyObject_AsFileDescriptor(arg);
if (fdno >= 0) {
/* XXX we dont know the mode here.. guessing append for now */
fp = fdopen(fdno, "a");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
} else if (arg == Py_None) {
fp = NULL;
} else {
PyErr_SetString(PyExc_TypeError, "file object or None expected");
return NULL;
}
(void) rpmlogSetFile(fp);
Py_RETURN_NONE;
}
The librpm
function call is rpmlogSetFile(fdopen(PyObject_AsFileDescriptor(arg), "a"))
. The rest is glue and arg/error handling.
This function is used from Python with sys.stderr
and tempfile.NamedTemporaryFile
instance and both seem to work fine.
I was about to reimplement this in ctypes
.
I have this:
import ctypes
from ctypes.util import find_library
LIBC = ctypes.cdll.LoadLibrary(find_library("c"))
LIBRPM = ctypes.cdll.LoadLibrary(find_library("rpm"))
def rpm_set_log_file(fileobj):
LIBRPM.rpmlogSetFile(LIBC.fdopen(fileobj.fileno(), b"a"))
However, when I call rpm_set_log_file(tempfile.NamedTemporaryFile(...))
and RPM tries to log something, I get a segfault. Same with sys.stderr
.
I debugged this a bit and I get:
>>> LIBC.fdopen(sys.stderr.fileno(), b"a")
-12324400
(Sometimes I get a positive number and it makes no difference.)
Let’s try to write something:
>>> LIBC.fwrite(b"x", 1, 2, -12324400)
Segmentation fault (core dumped)
Whta am I doing wrong? The documentation for PyObject_AsFileDescriptor
says it returns .fileno()
. So I expected I could do this.
Thanks.