如何使用信号处理linux文件系统监视?
linux下c的代码原型如下:#define _GNU_SOURCE
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
static volatile int event_fd;
static void handler(int signum, siginfo_t *si, void *data){
event_fd = si->si_fd;
printf("info size:%d, data:%d/n", sizeof(siginfo_t), sizeof(data));
}
int main(int argc, char **argv){
struct sigaction action;
int fd;
action.sa_sigaction = handler;
sigemptyset(&action.sa_mask);
action.sa_flags = SA_SIGINFO;
sigaction(SIGRTMIN+1, &action, NULL);
fd = open("test", O_RDONLY);
fcntl(fd, F_SETSIG, SIGRTMIN+1);
fcntl(fd, F_NOTIFY, DN_MODIFY | DN_CREATE | DN_MULTISHOT);
fd = open(".", O_RDONLY);
fcntl(fd, F_SETSIG, SIGRTMIN+1);
fcntl(fd, F_NOTIFY, DN_MODIFY | DN_CREATE | DN_MULTISHOT);
while(1){
pause();
printf("got event on fd=%d/n", event_fd);
}
}
我要使用python,可以使用嵌入式方式,如果不是嵌入式方式,将会有1个以上的进程出现。
//#define _GNU_SOURCE
#include "Python.h"
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
typedef void my_handler_t(int, int);
typedef my_handler_t * my_handler;
static void * current_handler;
static volatile int event_fd;
static void default_handler(int signum, siginfo_t * siginfo, void * context){
event_fd = siginfo->si_fd;
printf("event_fd %d, %p, sizeof /n", event_fd, siginfo);
//current_handler(signum, siginfo->si_fd);
PyObject *arglist = Py_BuildValue("(ii)", signum, siginfo->si_fd);
PyObject_Print(arglist, stdout, Py_PRINT_RAW);
printf("arglist end/n");
PyGILState_STATE state;
state = PyGILState_Ensure();
Py_INCREF(arglist);
PyObject *result =
PyEval_CallObject(current_handler, arglist);
Py_DECREF(arglist);
PyGILState_Release(state);
PyObject_Print(result, stdout, Py_PRINT_RAW);
printf("-->result %p/n", result);
//TODO: PyEval_InitThreads
}
typedef void sigaction_handler_t(int, siginfo_t *, void *);
typedef sigaction_handler_t * sigaction_handler;
static PyObject * dnsig_register(PyObject *self, PyObject *args){
int signum;
PyObject *handler;
if(!PyArg_ParseTuple(args, "iO", &signum, &handler))
return NULL;
printf("%d, %p/n", signum, handler);
Py_XINCREF(handler); /* Add a reference to new callback */
//Py_XDECREF(current_handler); /* Dispose of previous callback */
current_handler = handler;
struct sigaction action;
//action.sa_sigaction=(sigaction_handler)handler;
action.sa_sigaction = default_handler;
sigemptyset(&action.sa_mask);
action.sa_flags = SA_SIGINFO;
sigaction(signum, &action, NULL);
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef dnsigMethods[]={
{"register", dnsig_register, METH_VARARGS, "register signal handler"},
{NULL, NULL}//, 0, NULL}
};
PyMODINIT_FUNC
initdnsig(void){
(void)Py_InitModule("dnsig", dnsigMethods);
}
int main(int argc, char **argv){
/* Pass argv[0] to the Python interpreter */
Py_SetProgramName(argv[0]);
/* Initialize the Python interpreter. Required. */
Py_Initialize();
/* Add a static module */
initdnsig();
/* Define sys.argv. It is up to the application if you
want this; you can also let it undefined (since the Python
code is generally not a main program it has no business
touching sys.argv...) */
PySys_SetArgv(argc, argv);
/* Do some application specific code */
printf("Hello, brave new world/n/n");
/* Execute some Python statements (in module __main__) */
PyRun_SimpleString("import sys/n");
PyRun_SimpleString("print sys.builtin_module_names/n");
PyRun_SimpleString("print sys.modules.keys()/n");
PyRun_SimpleString("print sys.executable/n");
PyRun_SimpleString("print sys.argv/n");
PyRun_SimpleString("import dm/n");
/* Note that you can call any public function of the Python
interpreter here, e.g. call_object(). */
/* Some more application specific code */
printf("/nGoodbye, cruel world/n");
int fd;
struct sigaction action;
//action.sa_sigaction = handler;
sigemptyset(&action.sa_mask);
action.sa_flags = SA_SIGINFO;
// sigaction(SIGRTMIN+1, &action, NULL);
//fd = open("test", O_RDONLY);
//fcntl(fd, F_SETSIG, SIGRTMIN+1);
//fcntl(fd, F_NOTIFY, DN_MODIFY | DN_CREATE | DN_MULTISHOT);
//fd = open(".", O_RDONLY);
//fcntl(fd, F_SETSIG, SIGRTMIN+1);
//fcntl(fd, F_NOTIFY, DN_MODIFY | DN_CREATE | DN_MULTISHOT);
//while(1){
// pause();
// printf("got event on fd=%d/n", event_fd);
//}
Py_Exit(0);
}
具体的处理使用python来写,简单灵活多了。
#!/usr/bin/env py
#coding: UTF-8
#
import fcntl,os, signal, time, inspect, struct, traceback, dnsig;
def fmember(attr):
return attr[0]=='f';
handlerCount = 0;
def handler(signum, frame):
global handlerCount;
handlerCount += 1;
print "handle", handlerCount, time.time();
#print inspect.getmembers(frame);
#def sighandler(signum, siginfo, ucontext):
def sighandler(signum, fd):
print signum, fd;
#print signum, str(siginfo), str(ucontext);
#print struct.unpack('iiiiiilllllllllllll', str(siginfo));
pass
#
def dummy(signum):
print 'dummy', signum;
pass
#
#set event handler for SIGIO, otherwise the program will terminate
#signal.signal(signal.SIGIO, lambda signum, stack:None);
#signal.signal(signal.SIGIO, handler);
#signal.sigaction(signal.SIGRTMIN+1, sighandler);
dnsig.register(signal.SIGRTMIN+1, sighandler);
#dnsig.register(signal.SIGRTMIN+1, dummy);
watchDir="test"
filedesc = os.open(watchDir, os.O_RDONLY);
print "fd %s, signum %s, sighandler: %s" %(filedesc, signal.SIGRTMIN+1, sighandler);
count =0;
flags=[fcntl.DN_CREATE, fcntl.DN_MODIFY, fcntl.DN_RENAME];
__innerFlags=reduce(lambda x, y: x | y, flags) | fcntl.DN_MULTISHOT;
#fcntl.DN_MULTISHOT;
try:
try:
#register watching service
print 'register fcntl';
fcntl.fcntl(filedesc, fcntl.F_SETSIG, signal.SIGRTMIN+1);
fcntl.fcntl(filedesc,fcntl.F_NOTIFY, __innerFlags);
while True:
print 'start main loop'
#block until signal received
signal.pause();
print 'signal recievd', time.time();
#count+=1;
#print "EVENT", count
except KeyboardInterrupt:
print "program exit now!"
except:
traceback.print_exec();
finally:
os.close(filedesc);
本文地址:http://www.45fan.com/bcdm/73620.html