1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
/*
* watch.c -- generic data structures and routines for watching
* file descriptors and timers (eventually)
*/
#include "estruct.h"
#include "edef.h"
typedef struct {
char *callback; /* a vile command to run... */
long otherid; /* e.g, the XtInputId is stored here for x11. */
WATCHTYPE type; /* one of WATCHINPUT, WATCHOUTPUT, or WATCHERROR */
} watchrec;
#define NWATCHFDS 256
static watchrec *watchfds[NWATCHFDS];
static void unwatch_dealloc(int fd);
static void unwatch_free_callback(char *callback);
int
watchfd(int fd, WATCHTYPE type, char *callback)
{
long otherid;
int status;
if (watchfds[fd]) {
/* Already allocated/watched, so deallocate/unwatch */
unwatchfd(fd);
}
watchfds[fd] = typealloc(watchrec);
if (watchfds[fd] == NULL) {
unwatch_free_callback(callback);
return FALSE;
}
status = term.watchfd(fd, type, &otherid);
watchfds[fd]->callback = callback;
watchfds[fd]->type = type;
watchfds[fd]->otherid = otherid;
if (status != TRUE) {
unwatch_dealloc(fd);
}
return status;
}
void
unwatchfd(int fd)
{
if (watchfds[fd] == NULL)
return;
term.unwatchfd(fd, watchfds[fd]->otherid);
unwatch_dealloc(fd);
}
void
dowatchcallback(int fd)
{
/* Not safe to do one of these callbacks when the user is
typing on the message line. FIXME. */
if (reading_msg_line)
return;
if (watchfds[fd] == NULL || watchfds[fd]->callback == NULL)
return;
(void) docmd(watchfds[fd]->callback, TRUE, FALSE, 1);
}
static void
unwatch_dealloc(int fd)
{
if (watchfds[fd] == NULL)
return;
unwatch_free_callback(watchfds[fd]->callback);
FreeAndNull(watchfds[fd]);
}
static void
unwatch_free_callback(char *callback)
{
if (callback == NULL)
return;
#if OPT_PERL
if (strncmp("perl", callback, 4) == 0)
perl_free_callback(callback);
#endif
free(callback);
}
|