2011-06-01 6 views
5

Estoy tratando de llamar a la función reboot desde libc en Python a través de ctypes y simplemente no puedo hacer que funcione. He estado haciendo referencia a la página man 2 reboot (http://linux.die.net/man/2/reboot). Mi versión del kernel es 2.6.35.Python ctypes llamando al reinicio() desde libc en Linux

A continuación se muestra el registro de la consola desde el aviso interactivo de Python donde intento que mi máquina se reinicie. ¿Qué estoy haciendo mal?

¿Por qué no está trabajando ctypes.get_errno()?

>>> from ctypes import CDLL, get_errno 
>>> libc = CDLL('libc.so.6') 
>>> libc.reboot(0xfee1dead, 537993216, 0x1234567, 0) 
-1 
>>> get_errno() 
0 
>>> libc.reboot(0xfee1dead, 537993216, 0x1234567) 
-1 
>>> get_errno() 
0 
>>> from ctypes import c_uint32 
>>> libc.reboot(c_uint32(0xfee1dead), c_uint32(672274793), c_uint32(0x1234567), c_uint32(0)) 
-1 
>>> get_errno() 
0 
>>> libc.reboot(c_uint32(0xfee1dead), c_uint32(672274793), c_uint32(0x1234567)) 
-1 
>>> get_errno() 
0 
>>> 

Editar:

Via Nemos Recordatorio- puedo conseguir get_errno para regresar 22 (argumento no válido). No es una sorpresa ¿Cómo debo llamar al reboot()? Claramente, no estoy transmitiendo argumentos que la función espera. =)

+0

¿Está en el directorio raíz al ejecutar este script? –

+0

acceso denegado? No sé ... intente (re) leer esto: http://linux.die.net/man/2/reboot – Manux

+1

Incluso si se denegó el acceso, uno esperaría que 'errno' informara' EPERM'. – sarnold

Respuesta

3

Probar:

>>> libc = CDLL('libc.so.6', use_errno=True) 

que debe permitir get_errno() para trabajar.

[Actualización]

Además, el último argumento es una void *. Si se trata de un sistema de 64 bits, entonces el entero 0 no es una representación válida para NULL. Intentaría None o quizás c_void_p(None). (No estoy seguro de cómo podría importa en este contexto, sin embargo.)

[Actualización 2]

Al parecer reboot(0x1234567) hace el truco (ver comentarios).

+0

oh, a la derecha, eso suena. Gracias – tMC

+0

tratando de 'libc.reboot (0xfee1dead, 672274793, 0x1234567, c_void_p (None))' todavía devuelve errno 22. gracias por la idea. (también lo hace tratando de usar 'c_uint()' alrededor de los argumentos) – tMC

+0

¿Ha intentado simplemente 'reiniciar (0x1234567)'? Esa es la firma que veo en sys/reboot.h ... – Nemo

2

El reboot() en libc es un contenedor alrededor del syscall, que solo toma el argumento cmd. A fin de tratar:

libc.reboot(0x1234567) 

Tenga en cuenta que normalmente debería estar iniciando un reinicio mediante el envío de SIGINT al PID 1 - dice el kernel para reiniciar no dará a cualquier sistema de demonios de la posibilidad de cerrar limpiamente, y ni siquiera sincronizar la memoria caché del sistema de archivos en el disco.

+0

gran información sobre libc, gracias. – tMC

Cuestiones relacionadas