NeoMutt  2018-07-16 +1360-3df4a2
Teaching an old dog new tricks
DOXYGEN
monitor.c File Reference

Monitor files for changes. More...

#include "config.h"
#include <errno.h>
#include <limits.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "monitor.h"
#include "context.h"
#include "curs_lib.h"
#include "globals.h"
#include "mailbox.h"
#include "mutt_curses.h"
#include "mx.h"
+ Include dependency graph for monitor.c:

Go to the source code of this file.

Data Structures

struct  Monitor
 A watch on a file. More...
 
struct  MonitorInfo
 Information about a monitored file. More...
 

Macros

#define INOTIFY_MASK_DIR   (IN_MOVED_TO | IN_ATTRIB | IN_CLOSE_WRITE | IN_ISDIR)
 
#define INOTIFY_MASK_FILE   IN_CLOSE_WRITE
 
#define EVENT_BUFLEN   MAX(4096, sizeof(struct inotify_event) + NAME_MAX + 1)
 
#define RESOLVERES_FAIL_NOMAILBOX   -3
 
#define RESOLVERES_FAIL_NOMAGIC   -2
 
#define RESOLVERES_FAIL_STAT   -1
 
#define RESOLVERES_OK_NOTEXISTING   0
 
#define RESOLVERES_OK_EXISTING   1
 

Functions

static void mutt_poll_fd_add (int fd, short events)
 Add a file to the watch list. More...
 
static int mutt_poll_fd_remove (int fd)
 Remove a file from the watch list. More...
 
static int monitor_init (void)
 Set up file monitoring. More...
 
static void monitor_check_free (void)
 Close down file monitoring. More...
 
static struct Monitormonitor_new (struct MonitorInfo *info, int descriptor)
 Create a new file monitor. More...
 
static void monitor_delete (struct Monitor *monitor)
 Free a file monitor. More...
 
static int monitor_handle_ignore (int desc)
 Listen for when a backup file is closed. More...
 
static int monitor_resolve (struct MonitorInfo *info, struct Mailbox *m)
 Get the monitor for a mailbox. More...
 
int mutt_monitor_poll (void)
 Check for filesystem changes. More...
 
int mutt_monitor_add (struct Mailbox *m)
 Add a watch for a mailbox. More...
 
int mutt_monitor_remove (struct Mailbox *m)
 Remove a watch for a mailbox. More...
 

Variables

int MonitorFilesChanged = 0
 true after a monitored file has changed More...
 
int MonitorContextChanged = 0
 true after the current mailbox has changed More...
 
static int INotifyFd = -1
 
static struct MonitorMonitor = NULL
 
static size_t PollFdsCount = 0
 
static size_t PollFdsLen = 0
 
static struct pollfd * PollFds = NULL
 
static int MonitorContextDescriptor = -1
 

Detailed Description

Monitor files for changes.

Authors
  • Gero Treuer

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file monitor.c.

Macro Definition Documentation

#define INOTIFY_MASK_DIR   (IN_MOVED_TO | IN_ATTRIB | IN_CLOSE_WRITE | IN_ISDIR)

Definition at line 60 of file monitor.c.

#define INOTIFY_MASK_FILE   IN_CLOSE_WRITE

Definition at line 61 of file monitor.c.

#define EVENT_BUFLEN   MAX(4096, sizeof(struct inotify_event) + NAME_MAX + 1)

Definition at line 63 of file monitor.c.

#define RESOLVERES_FAIL_NOMAILBOX   -3

Definition at line 65 of file monitor.c.

#define RESOLVERES_FAIL_NOMAGIC   -2

Definition at line 66 of file monitor.c.

#define RESOLVERES_FAIL_STAT   -1

Definition at line 67 of file monitor.c.

#define RESOLVERES_OK_NOTEXISTING   0

Definition at line 68 of file monitor.c.

#define RESOLVERES_OK_EXISTING   1

Definition at line 69 of file monitor.c.

Function Documentation

static void mutt_poll_fd_add ( int  fd,
short  events 
)
static

Add a file to the watch list.

Parameters
fdFile to watch
eventsEvents to listen for, e.g. POLLIN

Definition at line 103 of file monitor.c.

104 {
105  int i = 0;
106  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
107  ;
108 
109  if (i == PollFdsCount)
110  {
111  if (PollFdsCount == PollFdsLen)
112  {
113  PollFdsLen += 2;
114  mutt_mem_realloc(&PollFds, PollFdsLen * sizeof(struct pollfd));
115  }
116  PollFdsCount++;
117  PollFds[i].fd = fd;
118  PollFds[i].events = events;
119  }
120  else
121  PollFds[i].events |= events;
122 }
static size_t PollFdsLen
Definition: monitor.c:55
static struct pollfd * PollFds
Definition: monitor.c:56
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:124
static size_t PollFdsCount
Definition: monitor.c:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int mutt_poll_fd_remove ( int  fd)
static

Remove a file from the watch list.

Parameters
fdFile to remove
Return values
0Success
-1Error

Definition at line 130 of file monitor.c.

131 {
132  int i = 0;
133  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
134  ;
135  if (i == PollFdsCount)
136  return -1;
137  int d = PollFdsCount - i - 1;
138  if (d != 0)
139  memmove(&PollFds[i], &PollFds[i + 1], d * sizeof(struct pollfd));
140  PollFdsCount--;
141  return 0;
142 }
static struct pollfd * PollFds
Definition: monitor.c:56
static size_t PollFdsCount
Definition: monitor.c:54

+ Here is the caller graph for this function:

static int monitor_init ( void  )
static

Set up file monitoring.

Return values
0Success
-1Error

Definition at line 149 of file monitor.c.

150 {
151  if (INotifyFd == -1)
152  {
153  INotifyFd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
154  if (INotifyFd == -1)
155  {
156  mutt_debug(LL_DEBUG2, "inotify_init1 failed, errno=%d %s\n", errno, strerror(errno));
157  return -1;
158  }
159  mutt_poll_fd_add(0, POLLIN);
160  mutt_poll_fd_add(INotifyFd, POLLIN);
161  }
162  return 0;
163 }
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
static void mutt_poll_fd_add(int fd, short events)
Add a file to the watch list.
Definition: monitor.c:103
#define mutt_debug(LEVEL,...)
Definition: logging.h:85

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void monitor_check_free ( void  )
static

Close down file monitoring.

Definition at line 168 of file monitor.c.

169 {
170  if (!Monitor && (INotifyFd != -1))
171  {
173  close(INotifyFd);
174  INotifyFd = -1;
176  }
177 }
A watch on a file.
Definition: monitor.c:74
static int INotifyFd
Definition: monitor.c:52
int MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:49
static int mutt_poll_fd_remove(int fd)
Remove a file from the watch list.
Definition: monitor.c:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static struct Monitor* monitor_new ( struct MonitorInfo info,
int  descriptor 
)
static

Create a new file monitor.

Parameters
infoDetails of file to monitor
descriptorWatch descriptor
Return values
ptrNewly allocated Monitor

Definition at line 185 of file monitor.c.

186 {
187  struct Monitor *monitor = mutt_mem_calloc(1, sizeof(struct Monitor));
188  monitor->magic = info->magic;
189  monitor->st_dev = info->st_dev;
190  monitor->st_ino = info->st_ino;
191  monitor->desc = descriptor;
192  monitor->next = Monitor;
193  if (info->magic == MUTT_MH)
194  monitor->mh_backup_path = mutt_str_strdup(info->path);
195 
196  Monitor = monitor;
197 
198  return monitor;
199 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
enum MailboxType magic
Definition: monitor.c:89
ino_t st_ino
Definition: monitor.c:79
int desc
Definition: monitor.c:81
A watch on a file.
Definition: monitor.c:74
struct Monitor * next
Definition: monitor.c:76
char * mh_backup_path
Definition: monitor.c:77
enum MailboxType magic
Definition: monitor.c:80
static struct Monitor * Monitor
Definition: monitor.c:53
dev_t st_dev
Definition: monitor.c:78
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
const char * path
Definition: monitor.c:91
&#39;MH&#39; Mailbox type
Definition: magic.h:39
dev_t st_dev
Definition: monitor.c:92
ino_t st_ino
Definition: monitor.c:93

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void monitor_delete ( struct Monitor monitor)
static

Free a file monitor.

Parameters
monitorMonitor to free

Definition at line 205 of file monitor.c.

206 {
207  struct Monitor **ptr = &Monitor;
208 
209  if (!monitor)
210  return;
211 
212  while (true)
213  {
214  if (!*ptr)
215  return;
216  if (*ptr == monitor)
217  break;
218  ptr = &(*ptr)->next;
219  }
220 
221  FREE(&monitor->mh_backup_path);
222  monitor = monitor->next;
223  FREE(ptr);
224  *ptr = monitor;
225 }
A watch on a file.
Definition: monitor.c:74
struct Monitor * next
Definition: monitor.c:76
char * mh_backup_path
Definition: monitor.c:77
static struct Monitor * Monitor
Definition: monitor.c:53
#define FREE(x)
Definition: memory.h:40

+ Here is the caller graph for this function:

static int monitor_handle_ignore ( int  desc)
static

Listen for when a backup file is closed.

Parameters
descWatch descriptor
Return values
>=0New descriptor
-1Error

Definition at line 233 of file monitor.c.

234 {
235  int new_desc = -1;
236  struct Monitor *iter = Monitor;
237  struct stat sb;
238 
239  while (iter && (iter->desc != desc))
240  iter = iter->next;
241 
242  if (iter)
243  {
244  if ((iter->magic == MUTT_MH) && (stat(iter->mh_backup_path, &sb) == 0))
245  {
246  new_desc = inotify_add_watch(INotifyFd, iter->mh_backup_path, INOTIFY_MASK_FILE);
247  if (new_desc == -1)
248  {
249  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
250  iter->mh_backup_path, errno, strerror(errno));
251  }
252  else
253  {
254  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n",
255  desc, iter->mh_backup_path);
256  iter->st_dev = sb.st_dev;
257  iter->st_ino = sb.st_ino;
258  iter->desc = new_desc;
259  }
260  }
261  else
262  {
263  mutt_debug(LL_DEBUG3, "cleanup watch (implicitly removed) - descriptor=%d\n", desc);
264  }
265 
266  if (MonitorContextDescriptor == desc)
267  MonitorContextDescriptor = new_desc;
268 
269  if (new_desc == -1)
270  {
271  monitor_delete(iter);
273  }
274  }
275 
276  return new_desc;
277 }
#define INOTIFY_MASK_FILE
Definition: monitor.c:61
ino_t st_ino
Definition: monitor.c:79
int desc
Definition: monitor.c:81
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:205
A watch on a file.
Definition: monitor.c:74
struct Monitor * next
Definition: monitor.c:76
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
char * mh_backup_path
Definition: monitor.c:77
enum MailboxType magic
Definition: monitor.c:80
static struct Monitor * Monitor
Definition: monitor.c:53
dev_t st_dev
Definition: monitor.c:78
&#39;MH&#39; Mailbox type
Definition: magic.h:39
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:168
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Log at debug level 3.
Definition: logging.h:58

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int monitor_resolve ( struct MonitorInfo info,
struct Mailbox m 
)
static

Get the monitor for a mailbox.

Parameters
[out]infoDetails of the mailbox's monitor
[in]mMailbox
Return values
>=0mailbox is valid and locally accessible: 0: no monitor / 1: preexisting monitor
-3no mailbox (MonitorInfo: no fields set)
-2magic not set
-1stat() failed (see errno; MonitorInfo fields: magic, isdir, path)

If m is NULL, the current mailbox (Context) is used.

Definition at line 291 of file monitor.c.

292 {
293  struct Monitor *iter;
294  char *fmt = NULL;
295  struct stat sb;
296 
297  if (m)
298  {
299  info->magic = m->magic;
300  info->path = m->realpath;
301  }
302  else if (Context)
303  {
304  info->magic = Context->mailbox->magic;
305  info->path = Context->mailbox->realpath;
306  }
307  else
308  {
310  }
311 
312  if (!info->magic)
313  {
315  }
316  else if (info->magic == MUTT_MAILDIR)
317  {
318  info->isdir = 1;
319  fmt = "%s/new";
320  }
321  else
322  {
323  info->isdir = 0;
324  if (info->magic == MUTT_MH)
325  fmt = "%s/.mh_sequences";
326  }
327 
328  if (fmt)
329  {
330  snprintf(info->path_buf, sizeof(info->path_buf), fmt, info->path);
331  info->path = info->path_buf;
332  }
333  if (stat(info->path, &sb) != 0)
334  return RESOLVERES_FAIL_STAT;
335 
336  iter = Monitor;
337  while (iter && ((iter->st_ino != sb.st_ino) || (iter->st_dev != sb.st_dev)))
338  iter = iter->next;
339 
340  info->st_dev = sb.st_dev;
341  info->st_ino = sb.st_ino;
342  info->monitor = iter;
343 
345 }
The "current" mailbox.
Definition: context.h:37
enum MailboxType magic
Definition: monitor.c:89
ino_t st_ino
Definition: monitor.c:79
#define RESOLVERES_OK_EXISTING
Definition: monitor.c:69
&#39;Maildir&#39; Mailbox type
Definition: magic.h:40
short isdir
Definition: monitor.c:90
A watch on a file.
Definition: monitor.c:74
struct Monitor * next
Definition: monitor.c:76
struct Mailbox * mailbox
Definition: context.h:51
enum MailboxType magic
mailbox type
Definition: mailbox.h:106
struct Monitor * monitor
Definition: monitor.c:94
#define RESOLVERES_FAIL_NOMAGIC
Definition: monitor.c:66
char path_buf[PATH_MAX]
Definition: monitor.c:95
static struct Monitor * Monitor
Definition: monitor.c:53
dev_t st_dev
Definition: monitor.c:78
const char * path
Definition: monitor.c:91
&#39;MH&#39; Mailbox type
Definition: magic.h:39
dev_t st_dev
Definition: monitor.c:92
char realpath[PATH_MAX]
used for duplicate detection, context comparison, and the sidebar
Definition: mailbox.h:86
#define RESOLVERES_FAIL_NOMAILBOX
Definition: monitor.c:65
#define RESOLVERES_FAIL_STAT
Definition: monitor.c:67
ino_t st_ino
Definition: monitor.c:93
#define RESOLVERES_OK_NOTEXISTING
Definition: monitor.c:68

+ Here is the caller graph for this function:

int mutt_monitor_poll ( void  )

Check for filesystem changes.

Return values
-3unknown/unexpected events: poll timeout / fds not handled by us
-2monitor detected changes, no STDIN input
-1error (see errno)
0(1) input ready from STDIN, or (2) monitoring inactive -> no poll()

Wait for I/O ready file descriptors or signals.

MonitorFilesChanged also reflects changes to monitored files.

Only STDIN and INotify file handles currently expected/supported. More would ask for common infrastructure (sockets?).

Definition at line 361 of file monitor.c.

362 {
363  int rc = 0;
364  char buf[EVENT_BUFLEN] __attribute__((aligned(__alignof__(struct inotify_event))));
365 
367 
368  if (INotifyFd != -1)
369  {
370  int fds = poll(PollFds, PollFdsLen, MuttGetchTimeout);
371 
372  if (fds == -1)
373  {
374  rc = -1;
375  if (errno != EINTR)
376  {
377  mutt_debug(LL_DEBUG2, "poll() failed, errno=%d %s\n", errno, strerror(errno));
378  }
379  }
380  else
381  {
382  bool inputReady = false;
383  for (int i = 0; fds && (i < PollFdsCount); i++)
384  {
385  if (PollFds[i].revents)
386  {
387  fds--;
388  if (PollFds[i].fd == 0)
389  {
390  inputReady = true;
391  }
392  else if (PollFds[i].fd == INotifyFd)
393  {
395  mutt_debug(LL_DEBUG3, "file change(s) detected\n");
396  char *ptr = buf;
397  const struct inotify_event *event;
398 
399  while (true)
400  {
401  int len = read(INotifyFd, buf, sizeof(buf));
402  if (len == -1)
403  {
404  if (errno != EAGAIN)
405  mutt_debug(LL_DEBUG2, "read inotify events failed, errno=%d %s\n",
406  errno, strerror(errno));
407  break;
408  }
409 
410  while (ptr < (buf + len))
411  {
412  event = (const struct inotify_event *) ptr;
413  mutt_debug(LL_DEBUG3, "+ detail: descriptor=%d mask=0x%x\n",
414  event->wd, event->mask);
415  if (event->mask & IN_IGNORED)
416  monitor_handle_ignore(event->wd);
417  else if (event->wd == MonitorContextDescriptor)
419  ptr += sizeof(struct inotify_event) + event->len;
420  }
421  }
422  }
423  }
424  }
425  if (!inputReady)
426  rc = MonitorFilesChanged ? -2 : -3;
427  }
428  }
429 
430  return rc;
431 }
#define EVENT_BUFLEN
Definition: monitor.c:63
static size_t PollFdsLen
Definition: monitor.c:55
static struct pollfd * PollFds
Definition: monitor.c:56
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
int MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:49
int MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:50
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
static size_t PollFdsCount
Definition: monitor.c:54
Log at debug level 3.
Definition: logging.h:58
int MuttGetchTimeout
Timeout in ms for mutt_getch()
Definition: curs_lib.c:94
static int monitor_handle_ignore(int desc)
Listen for when a backup file is closed.
Definition: monitor.c:233

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_monitor_add ( struct Mailbox m)

Add a watch for a mailbox.

Parameters
mMailbox to watch
Return values
0success: new or already existing monitor
-1failed: no mailbox, inaccessible file, create monitor/watcher failed

If mailbox is NULL, the current mailbox (Context) is used.

Definition at line 441 of file monitor.c.

442 {
443  struct MonitorInfo info;
444 
445  int desc = monitor_resolve(&info, m);
446  if (desc != RESOLVERES_OK_NOTEXISTING)
447  {
448  if (!m && (desc == RESOLVERES_OK_EXISTING))
449  MonitorContextDescriptor = info.monitor->desc;
450  return (desc == RESOLVERES_OK_EXISTING) ? 0 : -1;
451  }
452 
453  uint32_t mask = info.isdir ? INOTIFY_MASK_DIR : INOTIFY_MASK_FILE;
454  if (((INotifyFd == -1) && (monitor_init() == -1)) ||
455  ((desc = inotify_add_watch(INotifyFd, info.path, mask)) == -1))
456  {
457  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
458  info.path, errno, strerror(errno));
459  return -1;
460  }
461 
462  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n", desc, info.path);
463  if (!m)
465 
466  monitor_new(&info, desc);
467  return 0;
468 }
#define INOTIFY_MASK_FILE
Definition: monitor.c:61
Information about a monitored file.
Definition: monitor.c:87
#define RESOLVERES_OK_EXISTING
Definition: monitor.c:69
static int monitor_init(void)
Set up file monitoring.
Definition: monitor.c:149
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
#define INOTIFY_MASK_DIR
Definition: monitor.c:60
static int monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:291
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
static struct Monitor * monitor_new(struct MonitorInfo *info, int descriptor)
Create a new file monitor.
Definition: monitor.c:185
Log at debug level 3.
Definition: logging.h:58
#define RESOLVERES_OK_NOTEXISTING
Definition: monitor.c:68

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_monitor_remove ( struct Mailbox m)

Remove a watch for a mailbox.

Parameters
mMailbox
Return values
0monitor removed (not shared)
1monitor not removed (shared)
2no monitor

If mailbox is NULL, the current mailbox (Context) is used.

Definition at line 479 of file monitor.c.

480 {
481  struct MonitorInfo info, info2;
482 
483  if (!m)
484  {
487  }
488 
489  if (monitor_resolve(&info, m) != RESOLVERES_OK_EXISTING)
490  return 2;
491 
492  if (Context)
493  {
494  if (m)
495  {
496  if ((monitor_resolve(&info2, NULL) == RESOLVERES_OK_EXISTING) &&
497  (info.st_ino == info2.st_ino) && (info.st_dev == info2.st_dev))
498  {
499  return 1;
500  }
501  }
502  else
503  {
505  return 1;
506  }
507  }
508 
509  inotify_rm_watch(info.monitor->desc, INotifyFd);
510  mutt_debug(LL_DEBUG3, "inotify_rm_watch for '%s' descriptor=%d\n", info.path,
511  info.monitor->desc);
512 
513  monitor_delete(info.monitor);
515  return 0;
516 }
The "current" mailbox.
Definition: context.h:37
struct Mailbox * mutt_find_mailbox(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:262
Information about a monitored file.
Definition: monitor.c:87
#define RESOLVERES_OK_EXISTING
Definition: monitor.c:69
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:205
static int INotifyFd
Definition: monitor.c:52
struct Mailbox * mailbox
Definition: context.h:51
int MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:50
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:168
static int monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:291
static int MonitorContextDescriptor
Definition: monitor.c:58
char realpath[PATH_MAX]
used for duplicate detection, context comparison, and the sidebar
Definition: mailbox.h:86
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Log at debug level 3.
Definition: logging.h:58

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

int MonitorFilesChanged = 0

true after a monitored file has changed

Definition at line 49 of file monitor.c.

int MonitorContextChanged = 0

true after the current mailbox has changed

Definition at line 50 of file monitor.c.

int INotifyFd = -1
static

Definition at line 52 of file monitor.c.

struct Monitor* Monitor = NULL
static

Definition at line 53 of file monitor.c.

size_t PollFdsCount = 0
static

Definition at line 54 of file monitor.c.

size_t PollFdsLen = 0
static

Definition at line 55 of file monitor.c.

struct pollfd* PollFds = NULL
static

Definition at line 56 of file monitor.c.

int MonitorContextDescriptor = -1
static

Definition at line 58 of file monitor.c.