Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Telling off the Finder



On Nov 28, 2003, at 12:33 PM, David Duncan wrote:

On Nov 28, 2003, at 03:06 PM, Mike Kluev wrote:
Being completely unaware of kqueue mechanism: does it work without
*any* help from the code that makes modifications (i.e. is it
transparent)?

The man pages says/implies that it does (man kqueue).


It does seem to work that way. I tried this out a couple months go; this snippet monitors notifications to the "/tmp" directory (touch /tmp/foo to see it fire.) It also shows how to bottleneck signal handlers, to keep them from coming in at an inopportune time. (Hope this wraps nice ;-)

/*
cc -o kqueuewatcher kqueuewatcher.c
*/

#include <stdio.h>

#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sys/fcntl.h>
#include <sys/signal.h>
#include <sys/errno.h>

static void _user1(int sig)
{
fprintf(stderr, "here is _user1; shouldn't get called\n");
}

int main()
{
// Create a file descriptor that we want to monitor
int fdToWatch = open("/tmp", O_RDONLY | O_CREAT, 0666);

// Pith the USR1 signal handler. We never really want
// to dispatch to it, rather we want to emulate the
// signal using the kqueue event filter.
// This allows us to redirect the signal to a time of
// our choosing, rather than having it delivered haphazardly
// to whatever thread the kernel chooses.
signal(SIGUSR1, SIG_IGN);

// Create a new "kqueue" for this operation
// This gives the kernel a context in which to build the event list
int kq = kqueue();
fprintf(stderr, "kq created: %d\n", kq);

// Build up the list of events we want to filter
struct kevent changelist[2];
int ctChanges = 0;
EV_SET(&changelist[ctChanges++], fdToWatch, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, NULL);
EV_SET(&changelist[ctChanges++], SIGUSR1, EVFILT_SIGNAL, EV_ADD | EV_CLEAR, 0, 0, NULL);

// Register them; note that by specifying NULL, 0 in the eventlist parameters,
// this call will return immediately so we can then go into the polling loop.
// In a more full featured application, you would want to minimize kernel calls by combining
// the kqueue modifications with the event dequeing.
int ctEvents = kevent(kq, changelist, ctChanges, NULL, 0, NULL);

// Now, we can go into our event dequing. We'll listen for ctChanges events,
// since that is how many were registered. You could listen for fewer, or
// a fixed maximum amount.
while (1) {
struct kevent eventlist[ctChanges];

ctEvents = kevent(kq, NULL, 0, eventlist, ctChanges, NULL);

if (ctEvents < 0) {
fprintf(stderr, "An error occurred dequeing events: %d\n", errno);
continue;
} else if (ctEvents == 0) {
fprintf(stderr, "An timeout occurred dequeing events: but we didn't specify one! (%d)\n", errno);
continue;
} else while (ctEvents) {
// Note the pre-increment
struct kevent* oneEvent = &eventlist[--ctEvents];

switch (oneEvent->filter) {
case EVFILT_VNODE:
fprintf(stderr, "note a vnode change: on fd %d, data %d\n", oneEvent->ident, oneEvent->data);
break;
case EVFILT_SIGNAL:
fprintf(stderr, "note a signal: sig %d\n", oneEvent->data);
break;
}
}
}
}

--smz
_______________________________________________
carbon-development mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/carbon-development
Do not post admin requests to the list. They will be ignored.

References: 
 >Re: Telling off the Finder (From: Mike Kluev <email@hidden>)
 >Re: Telling off the Finder (From: David Duncan <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.