Example #1
0
static PyObject *ffi_dlclose(PyObject *self, PyObject *args)
{
    LibObject *lib;
    void *libhandle;
    if (!PyArg_ParseTuple(args, "O!", &Lib_Type, &lib))
        return NULL;

    libhandle = lib->l_libhandle;
    lib->l_libhandle = NULL;

    if (libhandle == NULL) {
        PyErr_Format(FFIError, "library '%s' is already closed "
                     "or was not created with ffi.dlopen()",
                     PyText_AS_UTF8(lib->l_libname));
        return NULL;
    }

    /* Clear the dict to force further accesses to do cdlopen_fetch()
       again, and fail because the library was closed. */
    PyDict_Clear(lib->l_dict);

    if (cdlopen_close(lib->l_libname, libhandle) < 0)
        return NULL;

    Py_INCREF(Py_None);
    return Py_None;
}
Example #2
0
static void *cdlopen_fetch(PyObject *libname, void *libhandle, char *symbol)
{
    void *address;

    if (libhandle == NULL) {
        PyErr_Format(FFIError, "library '%s' has been closed",
                     PyText_AS_UTF8(libname));
        return NULL;
    }

    dlerror();   /* clear error condition */
    address = dlsym(libhandle, symbol);
    if (address == NULL) {
        const char *error = dlerror();
        PyErr_Format(FFIError, "symbol '%s' not found in library '%s': %s",
                     symbol, PyText_AS_UTF8(libname), error);
    }
    return address;
}
Example #3
0
static int cdlopen_close(PyObject *libname, void *libhandle)
{
    if (libhandle != NULL && dlclose(libhandle) != 0) {
        const char *error = dlerror();
        PyErr_Format(FFIError, "closing library '%s': %s",
                     PyText_AS_UTF8(libname), error);
        return -1;
    }
    return 0;
}
Example #4
0
static CTypeDescrObject *_ffi_type(FFIObject *ffi, PyObject *arg,
                                   int accept)
{
    /* Returns the CTypeDescrObject from the user-supplied 'arg'.
       Does not return a new reference!
    */
    if ((accept & ACCEPT_STRING) && PyText_Check(arg)) {
        PyObject *types_dict = ffi->types_builder.types_dict;
        PyObject *x = PyDict_GetItem(types_dict, arg);

        if (x == NULL) {
            char *input_text = PyText_AS_UTF8(arg);
            int err, index = parse_c_type(&ffi->info, input_text);
            if (index < 0)
                return _ffi_bad_type(ffi, input_text);

            x = realize_c_type_or_func(&ffi->types_builder,
                                       ffi->info.output, index);
            if (x == NULL)
                return NULL;

            /* Cache under the name given by 'arg', in addition to the
               fact that the same ct is probably already cached under
               its standardized name.  In a few cases, it is not, e.g.
               if it is a primitive; for the purpose of this function,
               the important point is the following line, which makes
               sure that in any case the next _ffi_type() with the same
               'arg' will succeed early, in PyDict_GetItem() above.
            */
            err = PyDict_SetItem(types_dict, arg, x);
            Py_DECREF(x); /* we know it was written in types_dict (unless out
                             of mem), so there is at least that ref left */
            if (err < 0)
                return NULL;
        }

        if (CTypeDescr_Check(x))
            return (CTypeDescrObject *)x;
        else if (accept & CONSIDER_FN_AS_FNPTR)
            return unwrap_fn_as_fnptr(x);
        else
            return unexpected_fn_type(x);
    }
    else if ((accept & ACCEPT_CTYPE) && CTypeDescr_Check(arg)) {
        return (CTypeDescrObject *)arg;
    }
    else if ((accept & ACCEPT_CDATA) && CData_Check(arg)) {
        return ((CDataObject *)arg)->c_type;
    }
#if PY_MAJOR_VERSION < 3
    else if (PyUnicode_Check(arg)) {
        CTypeDescrObject *result;
        arg = PyUnicode_AsASCIIString(arg);
        if (arg == NULL)
            return NULL;
        result = _ffi_type(ffi, arg, accept);
        Py_DECREF(arg);
        return result;
    }
#endif
    else {
        const char *m1 = (accept & ACCEPT_STRING) ? "string" : "";
        const char *m2 = (accept & ACCEPT_CTYPE) ? "ctype object" : "";
        const char *m3 = (accept & ACCEPT_CDATA) ? "cdata object" : "";
        const char *s12 = (*m1 && (*m2 || *m3)) ? " or " : "";
        const char *s23 = (*m2 && *m3) ? " or " : "";
        PyErr_Format(PyExc_TypeError, "expected a %s%s%s%s%s, got '%.200s'",
                     m1, s12, m2, s23, m3,
                     Py_TYPE(arg)->tp_name);
        return NULL;
    }
}