Skip to content
Advertisement

Ctypes linux behavior differs on py2 and py3

While writing a python wrapper for the getmntent linux libc function, there is a strange difference between the behaviour between python 2.x and 3.x for the following code where most of the real work is done by the C library. Since I interface C code with python often, Can anyone explain or correct what is going wrong?

import ctypes
import sys

class mntent(ctypes.Structure):
    _fields_ = [("fsname", ctypes.c_char_p),
                ("dir", ctypes.c_char_p),
                ("type", ctypes.c_char_p),
                ("opts", ctypes.c_char_p),
                ("freq", ctypes.c_int),
                ("passno", ctypes.c_int)]

def main():
    libc = ctypes.cdll.LoadLibrary('libc.so.6')
    libc.getmntent.restype = ctypes.POINTER(mntent)
    libc.fopen.restype = ctypes.POINTER(ctypes.c_void_p)
    fp = libc.fopen('/etc/mtab', 'r')
    while True:
        mounts = libc.getmntent(fp)
        if bool(mounts) == False:
            libc.fclose(fp)
            break
        print("%30s   %10s    %s"%(mounts.contents.dir, mounts.contents.type, mounts.contents.fsname))

main()

The expected output contains all the mount devices listed with their types and mount points. On python 3.x it gives an empty list.

Advertisement

Answer

In Python 3, all strings are unicode, but libc.fopen() wants simple bytes strings as its arguments:

fp = libc.fopen(b'/etc/mtab', b'r')
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement