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')