Help me understand why my trivial use of the Cythype Python module does not work

I am trying to understand the Python "ctypes" module. I have put together a trivial example that - ideally - completes the call to the statvfs () function. The code is as follows:

from ctypes import *

class struct_statvfs (Structure):
    _fields_ = [
            ('f_bsize', c_ulong),
            ('f_frsize', c_ulong),
            ('f_blocks', c_ulong),
            ('f_bfree', c_ulong),
            ('f_bavail', c_ulong),
            ('f_files', c_ulong),
            ('f_ffree', c_ulong),
            ('f_favail', c_ulong),
            ('f_fsid', c_ulong),
            ('f_flag', c_ulong),
            ('f_namemax', c_ulong),
            ]


libc = CDLL('libc.so.6')
libc.statvfs.argtypes = [c_char_p, POINTER(struct_statvfs)]
s = struct_statvfs()

res = libc.statvfs('/etc', byref(s))
print 'return = %d, f_bsize = %d, f_blocks = %d, f_bfree = %d' % (
    res, s.f_bsize, s.f_blocks, s.f_bfree)

Doing this invariably returns:

return = 0, f_bsize = 4096, f_blocks = 10079070, f_bfree = 5048834
*** glibc detected *** python: free(): invalid next size (fast): 0x0000000001e51780 ***
*** glibc detected *** python: malloc(): memory corruption (fast): 0x0000000001e517e0 ***

I could not find examples of function calls with complex types as parameters (there are many examples of functions returning complex types), but after I looked at the ctypes documentation for a day or so, I think my calling syntax is correct .. .and actually calls statvfs () and returns the correct results.

Am I misunderstanding ctypes docs? Or is something else happening here?

Thank!

+5
4

, struct statvfs :

echo '#include <sys/statvfs.h>' | gcc -E - | less

/struct statvfs<enter>, .

fusepy .

+4

manpage statvfs , " ", manpage.

, , . , statvfs . , , ​​ _fields_ :

("padding", c_int * 1000),

, script , ; segfault, . , , , , .

+2

, /usr/include/bits/statvfs.h, .

64- Gentoo :

 class struct_statvfs (Structure):
    _fields_ = [
            ('f_bsize', c_ulong),
            ('f_frsize', c_ulong),
            ('f_blocks', c_ulong),
            ('f_bfree', c_ulong),
            ('f_bavail', c_ulong),
            ('f_files', c_ulong),
            ('f_ffree', c_ulong),
            ('f_favail', c_ulong),
            ('f_fsid', c_ulong),
            ('f_flag', c_ulong),
            ('f_namemax', c_ulong),
            ('__f_space', c_int * 6) # you are missing this
            ]
+2

According to the successful pyfusectypes wrappers for Fuse, struct statvfsfor Linux the following is used:

class c_statvfs(Structure):
    _fields_ = [
        ('f_bsize', c_ulong),
        ('f_frsize', c_ulong),
        ('f_blocks', c_fsblkcnt_t),
        ('f_bfree', c_fsblkcnt_t),
        ('f_bavail', c_fsblkcnt_t),
        ('f_files', c_fsfilcnt_t),
        ('f_ffree', c_fsfilcnt_t),
        ('f_favail', c_fsfilcnt_t)]

Additional information: http://code.google.com/p/fusepy/

0
source

All Articles