pythondaemon阻止对ctypes链接的C userlib的ioctl调用

2024-10-02 10:33:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我在bottleweb服务器中有一个Python应用程序,它通过Linux平台上的cypes Python模块访问C共享对象库。cso库打开一个设备节点(/dev/myhwdev),并根据设备的文件描述符断言IOCTL函数。尽管这是一个复杂的堆栈,但它的工作效果非常好,直到我将瓶子应用程序包装在Python的Python守护进程上下文中,如下所示:

# -*- coding: utf-8 -*-
import daemon
import bottle
from bottle import run, route, request

from userlib_via_ctypes_module import *
userlib_grab_device_file_descriptor()

@route('/regread')
def show_regread():
    address = request.query.address or request.forms.address
    length = request.query.length or request.forms.length
    return {'results':assert_ioctl_via_userlib(address, length)}

daemonContext = daemon.DaemonContext(
    detach_process = False
    )
with daemonContext:
    try:
        run(host = '0.0.0.0', port = '80', debug = True)
    except:
        print "(E) Bottle web-service was stopped.\n";

简单地注释掉with daemonContext行(并更正缩进)就可以使该代码正常工作(即,提供正确的JSON结果)。但是,在daemonContext中,userlib中的print语句显示设备节点的文件描述符已正确打开,但ioctl函数会自动失败,错误代码为-1。在

关闭设备的文件描述符并重新打开它(在userlib代码或上面的路由处理程序中)允许命令正确工作一次。并忽略服务器的所有请求。在

建议?目前,我已经准备好放弃守护程序模块了,因为没有它一切都可以正常工作。在

谢谢!在


Tags: 文件函数fromimport服务器应用程序bottle节点
1条回答
网友
1楼 · 发布于 2024-10-02 10:33:43

在准备这个问题时,答案对我来说是显而易见的。在

userlib_grab_device_file_descriptor()函数调用了一个C级SO lib函数,该函数打开了硬件设备节点的文件描述符,该描述符被传递给userlib ioctl函数。在

python守护进程在输入上下文时关闭所有文件句柄,包括硬件设备继承的文件描述符。userlib仍然认为文件描述符是有效的。至少,它会将调试消息中的FD打印为整数>;2。然而,在userlib不知道的情况下,文件句柄确实已经关闭,所以IOCTL将悄无声息地失败。我希望uclib或内核提供了更好的错误消息。:(

总之,答案是将打开的文件句柄移动到守护进程上下文的内部,如下所示:

...
with daemonContext:
    try:
        userlib_grab_device_file_descriptor()   # open fd here
        run(host = '0.0.0.0', port = '80', debug = True)
    except:
        print "(E) Bottle web-service was stopped.\n";

我尝试使用python守护进程的files_preserve属性,但它适用于文件描述符编号,而不是文件名。因此,在打开fd之后,我的userlib必须将fd编号传递给守护进程,以便在进入守护进程之前排除fd。。。我发现打开守护进程内部的文件描述符更容易。:)

希望这对其他人有帮助。:)

相关问题 更多 >

    热门问题