Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
678 views
in Technique[技术] by (71.8m points)

c - python ctypes and sysctl

I have following code

import sys
from ctypes import *
from ctypes.util import find_library

libc = cdll.LoadLibrary(find_library("c"))
CTL_KERN = 1
KERN_SHMMAX = 34
sysctl_names = {
    'memory_shared_buffers' : (CTL_KERN, KERN_SHMMAX),
    }

def posix_sysctl_long(name):
    _mem = c_uint64(0)
    _arr = c_int * 2
    _name = _arr()
    _name[0] = c_int(sysctl_names[name][0])
    _name[1] = c_int(sysctl_names[name][1])
    result = libc.sysctl(_name, byref(_mem), c_size_t(sizeof(_mem)), None, c_size_t(0))
    if result != 0:
        raise Exception('sysctl returned with error %s' % result)
    return _mem.value

print posix_sysctl_long('memory_shared_buffers')

which produces following result:

Traceback (most recent call last):
  File "test.py", line 23, in <module>
    print posix_sysctl_long('memory_shared_buffers')
  File "test.py", line 20, in posix_sysctl_long
    raise Exception('sysctl returned with error %s' % result)
Exception: sysctl returned with error -1

I gues I did something wrong. What would be the correct calling convention? How would I find out what exactly went wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are not providing the correct values to the sysctl function. Detailed information on the arguments of sysctl() can be found here.

Here are your errors:

  • You have forgotten the nlen argument (second argument)
  • The oldlenp argument is a pointer to the size, not directly the size

Here is the correct function (with minor improvement):

def posix_sysctl_long(name):
    _mem = c_uint64(0)
    _def = sysctl_names[name]
    _arr = c_int * len(_def)
    _name = _arr()
    for i, v in enumerate(_def):
        _name[i] = c_int(v)
    _sz = c_size_t(sizeof(_mem))
    result = libc.sysctl(_name, len(_def), byref(_mem), byref(_sz), None, c_size_t(0))
    if result != 0:
        raise Exception('sysctl returned with error %s' % result)
    return _mem.value

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...