NeoMutt  2020-08-21-74-g346364
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/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "monitor.h"
#include "context.h"
#include "mutt_globals.h"
#include <fcntl.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)
 

Enumerations

enum  ResolveResult {
  RESOLVE_RES_FAIL_NOMAILBOX = -3, RESOLVE_RES_FAIL_NOTYPE = -2, RESOLVE_RES_FAIL_STAT = -1, RESOLVE_RES_OK_NOTEXISTING = 0,
  RESOLVE_RES_OK_EXISTING = 1
}
 Results for the Monitor functions. More...
 

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_info_init (struct MonitorInfo *info)
 Set up a file monitor. More...
 
static void monitor_info_free (struct MonitorInfo *info)
 Shutdown a 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 enum ResolveResult 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

bool MonitorFilesChanged = false
 true after a monitored file has changed More...
 
bool MonitorContextChanged = false
 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

◆ INOTIFY_MASK_DIR

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

Definition at line 61 of file monitor.c.

◆ INOTIFY_MASK_FILE

#define INOTIFY_MASK_FILE   IN_CLOSE_WRITE

Definition at line 62 of file monitor.c.

◆ EVENT_BUFLEN

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

Definition at line 64 of file monitor.c.

Enumeration Type Documentation

◆ ResolveResult

Results for the Monitor functions.

Enumerator
RESOLVE_RES_FAIL_NOMAILBOX 

No Mailbox to work on.

RESOLVE_RES_FAIL_NOTYPE 

Can't identify Mailbox type.

RESOLVE_RES_FAIL_STAT 

Can't stat() the Mailbox file.

RESOLVE_RES_OK_NOTEXISTING 

File exists, no monitor is attached.

RESOLVE_RES_OK_EXISTING 

File exists, monitor is already attached.

Definition at line 69 of file monitor.c.

70 {
76 };
File exists, monitor is already attached.
Definition: monitor.c:75
No Mailbox to work on.
Definition: monitor.c:71
Can&#39;t identify Mailbox type.
Definition: monitor.c:72
Can&#39;t stat() the Mailbox file.
Definition: monitor.c:73
File exists, no monitor is attached.
Definition: monitor.c:74

Function Documentation

◆ mutt_poll_fd_add()

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 110 of file monitor.c.

111 {
112  int i = 0;
113  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
114  ; // do nothing
115 
116  if (i == PollFdsCount)
117  {
118  if (PollFdsCount == PollFdsLen)
119  {
120  PollFdsLen += 2;
121  mutt_mem_realloc(&PollFds, PollFdsLen * sizeof(struct pollfd));
122  }
123  PollFdsCount++;
124  PollFds[i].fd = fd;
125  PollFds[i].events = events;
126  }
127  else
128  PollFds[i].events |= events;
129 }
static size_t PollFdsLen
Definition: monitor.c:56
static struct pollfd * PollFds
Definition: monitor.c:57
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
static size_t PollFdsCount
Definition: monitor.c:55
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_poll_fd_remove()

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 137 of file monitor.c.

138 {
139  int i = 0;
140  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
141  ; // do nothing
142 
143  if (i == PollFdsCount)
144  return -1;
145  int d = PollFdsCount - i - 1;
146  if (d != 0)
147  memmove(&PollFds[i], &PollFds[i + 1], d * sizeof(struct pollfd));
148  PollFdsCount--;
149  return 0;
150 }
static struct pollfd * PollFds
Definition: monitor.c:57
static size_t PollFdsCount
Definition: monitor.c:55
+ Here is the caller graph for this function:

◆ monitor_init()

static int monitor_init ( void  )
static

Set up file monitoring.

Return values
0Success
-1Error

Definition at line 157 of file monitor.c.

158 {
159  if (INotifyFd == -1)
160  {
161 #ifdef HAVE_INOTIFY_INIT1
162  INotifyFd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
163  if (INotifyFd == -1)
164  {
165  mutt_debug(LL_DEBUG2, "inotify_init1 failed, errno=%d %s\n", errno, strerror(errno));
166  return -1;
167  }
168 #else
169  INotifyFd = inotify_init();
170  if (INotifyFd == -1)
171  {
172  mutt_debug(LL_DEBUG2, "monitor: inotify_init failed, errno=%d %s\n",
173  errno, strerror(errno));
174  return -1;
175  }
176  fcntl(INotifyFd, F_SETFL, O_NONBLOCK);
177  fcntl(INotifyFd, F_SETFD, FD_CLOEXEC);
178 #endif
179  mutt_poll_fd_add(0, POLLIN);
180  mutt_poll_fd_add(INotifyFd, POLLIN);
181  }
182  return 0;
183 }
static int INotifyFd
Definition: monitor.c:53
Log at debug level 2.
Definition: logging.h:41
static void mutt_poll_fd_add(int fd, short events)
Add a file to the watch list.
Definition: monitor.c:110
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_check_free()

static void monitor_check_free ( void  )
static

Close down file monitoring.

Definition at line 188 of file monitor.c.

189 {
190  if (!Monitor && (INotifyFd != -1))
191  {
193  close(INotifyFd);
194  INotifyFd = -1;
195  MonitorFilesChanged = false;
196  }
197 }
A watch on a file.
Definition: monitor.c:81
bool MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:50
static int INotifyFd
Definition: monitor.c:53
static int mutt_poll_fd_remove(int fd)
Remove a file from the watch list.
Definition: monitor.c:137
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_new()

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 205 of file monitor.c.

206 {
207  struct Monitor *monitor = mutt_mem_calloc(1, sizeof(struct Monitor));
208  monitor->type = info->type;
209  monitor->st_dev = info->st_dev;
210  monitor->st_ino = info->st_ino;
211  monitor->desc = descriptor;
212  monitor->next = Monitor;
213  if (info->type == MUTT_MH)
214  monitor->mh_backup_path = mutt_str_dup(info->path);
215 
216  Monitor = monitor;
217 
218  return monitor;
219 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
ino_t st_ino
Definition: monitor.c:86
int desc
Definition: monitor.c:88
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
A watch on a file.
Definition: monitor.c:81
struct Monitor * next
Definition: monitor.c:83
enum MailboxType type
Definition: monitor.c:96
char * mh_backup_path
Definition: monitor.c:84
static struct Monitor * Monitor
Definition: monitor.c:54
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
dev_t st_dev
Definition: monitor.c:85
enum MailboxType type
Definition: monitor.c:87
const char * path
Definition: monitor.c:98
dev_t st_dev
Definition: monitor.c:99
ino_t st_ino
Definition: monitor.c:100
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_info_init()

static void monitor_info_init ( struct MonitorInfo info)
static

Set up a file monitor.

Parameters
infoMonitor to initialise

Definition at line 225 of file monitor.c.

226 {
227  memset(info, 0, sizeof(*info));
228 }
+ Here is the caller graph for this function:

◆ monitor_info_free()

static void monitor_info_free ( struct MonitorInfo info)
static

Shutdown a file monitor.

Parameters
infoMonitor to shut down

Definition at line 234 of file monitor.c.

235 {
237 }
struct Buffer path_buf
access via path only (maybe not initialized)
Definition: monitor.c:102
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_delete()

static void monitor_delete ( struct Monitor monitor)
static

Free a file monitor.

Parameters
monitorMonitor to free

Definition at line 243 of file monitor.c.

244 {
245  if (!monitor)
246  return;
247 
248  struct Monitor **ptr = &Monitor;
249 
250  while (true)
251  {
252  if (!*ptr)
253  return;
254  if (*ptr == monitor)
255  break;
256  ptr = &(*ptr)->next;
257  }
258 
259  FREE(&monitor->mh_backup_path);
260  monitor = monitor->next;
261  FREE(ptr);
262  *ptr = monitor;
263 }
A watch on a file.
Definition: monitor.c:81
struct Monitor * next
Definition: monitor.c:83
char * mh_backup_path
Definition: monitor.c:84
static struct Monitor * Monitor
Definition: monitor.c:54
#define FREE(x)
Definition: memory.h:40
+ Here is the caller graph for this function:

◆ monitor_handle_ignore()

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 271 of file monitor.c.

272 {
273  int new_desc = -1;
274  struct Monitor *iter = Monitor;
275  struct stat sb;
276 
277  while (iter && (iter->desc != desc))
278  iter = iter->next;
279 
280  if (iter)
281  {
282  if ((iter->type == MUTT_MH) && (stat(iter->mh_backup_path, &sb) == 0))
283  {
284  new_desc = inotify_add_watch(INotifyFd, iter->mh_backup_path, INOTIFY_MASK_FILE);
285  if (new_desc == -1)
286  {
287  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
288  iter->mh_backup_path, errno, strerror(errno));
289  }
290  else
291  {
292  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n",
293  desc, iter->mh_backup_path);
294  iter->st_dev = sb.st_dev;
295  iter->st_ino = sb.st_ino;
296  iter->desc = new_desc;
297  }
298  }
299  else
300  {
301  mutt_debug(LL_DEBUG3, "cleanup watch (implicitly removed) - descriptor=%d\n", desc);
302  }
303 
304  if (MonitorContextDescriptor == desc)
305  MonitorContextDescriptor = new_desc;
306 
307  if (new_desc == -1)
308  {
309  monitor_delete(iter);
311  }
312  }
313 
314  return new_desc;
315 }
#define INOTIFY_MASK_FILE
Definition: monitor.c:62
ino_t st_ino
Definition: monitor.c:86
int desc
Definition: monitor.c:88
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:243
A watch on a file.
Definition: monitor.c:81
struct Monitor * next
Definition: monitor.c:83
static int INotifyFd
Definition: monitor.c:53
Log at debug level 2.
Definition: logging.h:41
char * mh_backup_path
Definition: monitor.c:84
static struct Monitor * Monitor
Definition: monitor.c:54
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
dev_t st_dev
Definition: monitor.c:85
enum MailboxType type
Definition: monitor.c:87
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:188
static int MonitorContextDescriptor
Definition: monitor.c:59
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_resolve()

static enum ResolveResult 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)
-2type not set
-1stat() failed (see errno; MonitorInfo fields: type, is_dir, path)

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

Definition at line 329 of file monitor.c.

330 {
331  char *fmt = NULL;
332  struct stat sb;
333 
334  if (m)
335  {
336  info->type = m->type;
337  info->path = m->realpath;
338  }
339  else if (Context && Context->mailbox)
340  {
341  info->type = Context->mailbox->type;
342  info->path = Context->mailbox->realpath;
343  }
344  else
345  {
347  }
348 
349  if (info->type == MUTT_UNKNOWN)
350  {
352  }
353  else if (info->type == MUTT_MAILDIR)
354  {
355  info->is_dir = true;
356  fmt = "%s/new";
357  }
358  else
359  {
360  info->is_dir = false;
361  if (info->type == MUTT_MH)
362  fmt = "%s/.mh_sequences";
363  }
364  if (fmt)
365  {
366  mutt_buffer_printf(&info->path_buf, fmt, info->path);
367  info->path = mutt_b2s(&info->path_buf);
368  }
369  if (stat(info->path, &sb) != 0)
370  return RESOLVE_RES_FAIL_STAT;
371 
372  struct Monitor *iter = Monitor;
373  while (iter && ((iter->st_ino != sb.st_ino) || (iter->st_dev != sb.st_dev)))
374  iter = iter->next;
375 
376  info->st_dev = sb.st_dev;
377  info->st_ino = sb.st_ino;
378  info->monitor = iter;
379 
381 }
The "current" mailbox.
Definition: context.h:38
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
ino_t st_ino
Definition: monitor.c:86
struct Buffer path_buf
access via path only (maybe not initialized)
Definition: monitor.c:102
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
A watch on a file.
Definition: monitor.c:81
struct Monitor * next
Definition: monitor.c:83
File exists, monitor is already attached.
Definition: monitor.c:75
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
bool is_dir
Definition: monitor.c:97
struct Mailbox * mailbox
Definition: context.h:50
enum MailboxType type
Definition: monitor.c:96
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
No Mailbox to work on.
Definition: monitor.c:71
Can&#39;t identify Mailbox type.
Definition: monitor.c:72
struct Monitor * monitor
Definition: monitor.c:101
#define mutt_b2s(buf)
Definition: buffer.h:41
static struct Monitor * Monitor
Definition: monitor.c:54
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
dev_t st_dev
Definition: monitor.c:85
Can&#39;t stat() the Mailbox file.
Definition: monitor.c:73
File exists, no monitor is attached.
Definition: monitor.c:74
const char * path
Definition: monitor.c:98
dev_t st_dev
Definition: monitor.c:99
ino_t st_ino
Definition: monitor.c:100
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_monitor_poll()

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 397 of file monitor.c.

398 {
399  int rc = 0;
400  char buf[EVENT_BUFLEN] __attribute__((aligned(__alignof__(struct inotify_event))));
401 
402  MonitorFilesChanged = false;
403 
404  if (INotifyFd != -1)
405  {
406  int fds = poll(PollFds, PollFdsLen, MuttGetchTimeout);
407 
408  if (fds == -1)
409  {
410  rc = -1;
411  if (errno != EINTR)
412  {
413  mutt_debug(LL_DEBUG2, "poll() failed, errno=%d %s\n", errno, strerror(errno));
414  }
415  }
416  else
417  {
418  bool input_ready = false;
419  for (int i = 0; fds && (i < PollFdsCount); i++)
420  {
421  if (PollFds[i].revents)
422  {
423  fds--;
424  if (PollFds[i].fd == 0)
425  {
426  input_ready = true;
427  }
428  else if (PollFds[i].fd == INotifyFd)
429  {
430  MonitorFilesChanged = true;
431  mutt_debug(LL_DEBUG3, "file change(s) detected\n");
432  char *ptr = buf;
433  const struct inotify_event *event = NULL;
434 
435  while (true)
436  {
437  int len = read(INotifyFd, buf, sizeof(buf));
438  if (len == -1)
439  {
440  if (errno != EAGAIN)
441  {
442  mutt_debug(LL_DEBUG2, "read inotify events failed, errno=%d %s\n",
443  errno, strerror(errno));
444  }
445  break;
446  }
447 
448  while (ptr < (buf + len))
449  {
450  event = (const struct inotify_event *) ptr;
451  mutt_debug(LL_DEBUG3, "+ detail: descriptor=%d mask=0x%x\n",
452  event->wd, event->mask);
453  if (event->mask & IN_IGNORED)
454  monitor_handle_ignore(event->wd);
455  else if (event->wd == MonitorContextDescriptor)
456  MonitorContextChanged = true;
457  ptr += sizeof(struct inotify_event) + event->len;
458  }
459  }
460  }
461  }
462  }
463  if (!input_ready)
464  rc = MonitorFilesChanged ? -2 : -3;
465  }
466  }
467 
468  return rc;
469 }
#define EVENT_BUFLEN
Definition: monitor.c:64
static size_t PollFdsLen
Definition: monitor.c:56
static struct pollfd * PollFds
Definition: monitor.c:57
bool MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:50
static int INotifyFd
Definition: monitor.c:53
Log at debug level 2.
Definition: logging.h:41
bool MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:51
static int MonitorContextDescriptor
Definition: monitor.c:59
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static size_t PollFdsCount
Definition: monitor.c:55
Log at debug level 3.
Definition: logging.h:42
int MuttGetchTimeout
Timeout in ms for mutt_getch()
Definition: curs_lib.c:93
static int monitor_handle_ignore(int desc)
Listen for when a backup file is closed.
Definition: monitor.c:271
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_monitor_add()

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 479 of file monitor.c.

480 {
481  struct MonitorInfo info;
482  monitor_info_init(&info);
483 
484  int rc = 0;
485  enum ResolveResult desc = monitor_resolve(&info, m);
486  if (desc != RESOLVE_RES_OK_NOTEXISTING)
487  {
488  if (!m && (desc == RESOLVE_RES_OK_EXISTING))
489  MonitorContextDescriptor = info.monitor->desc;
490  rc = (desc == RESOLVE_RES_OK_EXISTING) ? 0 : -1;
491  goto cleanup;
492  }
493 
494  uint32_t mask = info.is_dir ? INOTIFY_MASK_DIR : INOTIFY_MASK_FILE;
495  if (((INotifyFd == -1) && (monitor_init() == -1)) ||
496  ((desc = inotify_add_watch(INotifyFd, info.path, mask)) == -1))
497  {
498  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
499  info.path, errno, strerror(errno));
500  rc = -1;
501  goto cleanup;
502  }
503 
504  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n", desc, info.path);
505  if (!m)
507 
508  monitor_new(&info, desc);
509 
510 cleanup:
511  monitor_info_free(&info);
512  return rc;
513 }
#define INOTIFY_MASK_FILE
Definition: monitor.c:62
Information about a monitored file.
Definition: monitor.c:94
File exists, monitor is already attached.
Definition: monitor.c:75
static int monitor_init(void)
Set up file monitoring.
Definition: monitor.c:157
static int INotifyFd
Definition: monitor.c:53
Log at debug level 2.
Definition: logging.h:41
ResolveResult
Results for the Monitor functions.
Definition: monitor.c:69
#define INOTIFY_MASK_DIR
Definition: monitor.c:61
File exists, no monitor is attached.
Definition: monitor.c:74
static void monitor_info_init(struct MonitorInfo *info)
Set up a file monitor.
Definition: monitor.c:225
static int MonitorContextDescriptor
Definition: monitor.c:59
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static struct Monitor * monitor_new(struct MonitorInfo *info, int descriptor)
Create a new file monitor.
Definition: monitor.c:205
static enum ResolveResult monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:329
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:234
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_monitor_remove()

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 524 of file monitor.c.

525 {
526  struct MonitorInfo info, info2;
527  int rc = 0;
528 
529  monitor_info_init(&info);
530  monitor_info_init(&info2);
531 
532  if (!m)
533  {
535  MonitorContextChanged = false;
536  }
537 
538  if (monitor_resolve(&info, m) != RESOLVE_RES_OK_EXISTING)
539  {
540  rc = 2;
541  goto cleanup;
542  }
543 
544  if (Context && Context->mailbox)
545  {
546  if (m)
547  {
548  if ((monitor_resolve(&info2, NULL) == RESOLVE_RES_OK_EXISTING) &&
549  (info.st_ino == info2.st_ino) && (info.st_dev == info2.st_dev))
550  {
551  rc = 1;
552  goto cleanup;
553  }
554  }
555  else
556  {
558  {
559  rc = 1;
560  goto cleanup;
561  }
562  }
563  }
564 
565  inotify_rm_watch(info.monitor->desc, INotifyFd);
566  mutt_debug(LL_DEBUG3, "inotify_rm_watch for '%s' descriptor=%d\n", info.path,
567  info.monitor->desc);
568 
569  monitor_delete(info.monitor);
571 
572 cleanup:
573  monitor_info_free(&info);
574  monitor_info_free(&info2);
575  return rc;
576 }
The "current" mailbox.
Definition: context.h:38
Information about a monitored file.
Definition: monitor.c:94
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:243
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:91
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
File exists, monitor is already attached.
Definition: monitor.c:75
static int INotifyFd
Definition: monitor.c:53
struct Mailbox * mailbox
Definition: context.h:50
static void monitor_info_init(struct MonitorInfo *info)
Set up a file monitor.
Definition: monitor.c:225
bool MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:51
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:188
static int MonitorContextDescriptor
Definition: monitor.c:59
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static enum ResolveResult monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:329
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:234
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ MonitorFilesChanged

bool MonitorFilesChanged = false

true after a monitored file has changed

Definition at line 50 of file monitor.c.

◆ MonitorContextChanged

bool MonitorContextChanged = false

true after the current mailbox has changed

Definition at line 51 of file monitor.c.

◆ INotifyFd

int INotifyFd = -1
static

Definition at line 53 of file monitor.c.

◆ Monitor

struct Monitor* Monitor = NULL
static

Definition at line 54 of file monitor.c.

◆ PollFdsCount

size_t PollFdsCount = 0
static

Definition at line 55 of file monitor.c.

◆ PollFdsLen

size_t PollFdsLen = 0
static

Definition at line 56 of file monitor.c.

◆ PollFds

struct pollfd* PollFds = NULL
static

Definition at line 57 of file monitor.c.

◆ MonitorContextDescriptor

int MonitorContextDescriptor = -1
static

Definition at line 59 of file monitor.c.