NeoMutt  2023-11-03-85-g512e01
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
monitor.h File Reference

Monitor files for changes. More...

#include <stdbool.h>
+ Include dependency graph for monitor.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int mutt_monitor_add (struct Mailbox *m)
 Add a watch for a mailbox.
 
int mutt_monitor_remove (struct Mailbox *m)
 Remove a watch for a mailbox.
 
int mutt_monitor_poll (void)
 Check for filesystem changes.
 

Variables

bool MonitorFilesChanged
 true after a monitored file has changed
 
bool MonitorContextChanged
 true after the current mailbox has changed
 

Detailed Description

Monitor files for changes.

Authors
  • Gero Treuner

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.h.

Function Documentation

◆ 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 m is NULL, try to get the current mailbox from the Index.

Definition at line 480 of file monitor.c.

481{
482 struct MonitorInfo info = { 0 };
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))
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
510cleanup:
511 monitor_info_free(&info);
512 return rc;
513}
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
@ LL_DEBUG3
Log at debug level 3.
Definition: logging2.h:45
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
#define INOTIFY_MASK_DIR
Definition: monitor.c:66
static int MonitorContextDescriptor
Monitor file descriptor of the current mailbox.
Definition: monitor.c:64
static int INotifyFd
Inotify file descriptor.
Definition: monitor.c:54
static enum ResolveResult monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:328
static struct Monitor * monitor_new(struct MonitorInfo *info, int descriptor)
Create a new file monitor.
Definition: monitor.c:213
ResolveResult
Results for the Monitor functions.
Definition: monitor.c:75
@ RESOLVE_RES_OK_NOTEXISTING
File exists, no monitor is attached.
Definition: monitor.c:79
@ RESOLVE_RES_OK_EXISTING
File exists, monitor is already attached.
Definition: monitor.c:80
static int monitor_init(void)
Set up file monitoring.
Definition: monitor.c:164
#define INOTIFY_MASK_FILE
Definition: monitor.c:67
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:233
Information about a monitored file.
Definition: monitor.c:100
struct Monitor * monitor
Definition: monitor.c:106
bool is_dir
Definition: monitor.c:102
const char * path
Definition: monitor.c:103
int desc
Definition: monitor.c:93
+ 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 m is NULL, try to get the current mailbox from the Index.

Definition at line 524 of file monitor.c.

525{
526 struct MonitorInfo info = { 0 };
527 struct MonitorInfo info2 = { 0 };
528 int rc = 0;
529
530 if (!m)
531 {
533 MonitorContextChanged = false;
534 }
535
537 {
538 rc = 2;
539 goto cleanup;
540 }
541
542 struct Mailbox *m_cur = get_current_mailbox();
543 if (m_cur)
544 {
545 if (m)
546 {
547 if ((monitor_resolve(&info2, NULL) == RESOLVE_RES_OK_EXISTING) &&
548 (info.st_ino == info2.st_ino) && (info.st_dev == info2.st_dev))
549 {
550 rc = 1;
551 goto cleanup;
552 }
553 }
554 else
555 {
556 if (mailbox_find(m_cur->realpath))
557 {
558 rc = 1;
559 goto cleanup;
560 }
561 }
562 }
563
564 inotify_rm_watch(info.monitor->desc, INotifyFd);
565 mutt_debug(LL_DEBUG3, "inotify_rm_watch for '%s' descriptor=%d\n", info.path,
566 info.monitor->desc);
567
570
571cleanup:
572 monitor_info_free(&info);
573 monitor_info_free(&info2);
574 return rc;
575}
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition: index.c:662
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:143
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:242
bool MonitorContextChanged
Set to true when the current mailbox has changed.
Definition: monitor.c:51
static void monitor_check_cleanup(void)
Close down file monitoring.
Definition: monitor.c:196
A mailbox.
Definition: mailbox.h:79
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
dev_t st_dev
Definition: monitor.c:104
ino_t st_ino
Definition: monitor.c:105
+ 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]
401 __attribute__((aligned(__alignof__(struct inotify_event)))) = { 0 };
402
403 MonitorFilesChanged = false;
404
405 if (INotifyFd != -1)
406 {
407 int fds = poll(PollFds, PollFdsCount, 1000); // 1 Second
408
409 if (fds == -1)
410 {
411 rc = -1;
412 if (errno != EINTR)
413 {
414 mutt_debug(LL_DEBUG2, "poll() failed, errno=%d %s\n", errno, strerror(errno));
415 }
416 }
417 else
418 {
419 bool input_ready = false;
420 for (int i = 0; fds && (i < PollFdsCount); i++)
421 {
422 if (PollFds[i].revents)
423 {
424 fds--;
425 if (PollFds[i].fd == 0)
426 {
427 input_ready = true;
428 }
429 else if (PollFds[i].fd == INotifyFd)
430 {
431 MonitorFilesChanged = true;
432 mutt_debug(LL_DEBUG3, "file change(s) detected\n");
433 char *ptr = buf;
434 const struct inotify_event *event = NULL;
435
436 while (true)
437 {
438 int len = read(INotifyFd, buf, sizeof(buf));
439 if (len == -1)
440 {
441 if (errno != EAGAIN)
442 {
443 mutt_debug(LL_DEBUG2, "read inotify events failed, errno=%d %s\n",
444 errno, strerror(errno));
445 }
446 break;
447 }
448
449 while (ptr < (buf + len))
450 {
451 event = (const struct inotify_event *) ptr;
452 mutt_debug(LL_DEBUG3, "+ detail: descriptor=%d mask=0x%x\n",
453 event->wd, event->mask);
454 if (event->mask & IN_IGNORED)
455 monitor_handle_ignore(event->wd);
456 else if (event->wd == MonitorContextDescriptor)
458 ptr += sizeof(struct inotify_event) + event->len;
459 }
460 }
461 }
462 }
463 }
464 if (!input_ready)
465 rc = MonitorFilesChanged ? -2 : -3;
466 }
467 }
468
469 return rc;
470}
static int monitor_handle_ignore(int desc)
Listen for when a backup file is closed.
Definition: monitor.c:270
static size_t PollFdsCount
Number of used entries in the PollFds array.
Definition: monitor.c:58
bool MonitorFilesChanged
Set to true when a monitored file has changed.
Definition: monitor.c:49
#define EVENT_BUFLEN
Definition: monitor.c:69
static struct pollfd * PollFds
Array of monitored file descriptors.
Definition: monitor.c:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ MonitorFilesChanged

bool MonitorFilesChanged
extern

true after a monitored file has changed

true after a monitored file has changed

Definition at line 49 of file monitor.c.

◆ MonitorContextChanged

bool MonitorContextChanged
extern

true after the current mailbox has changed

true after the current mailbox has changed

Definition at line 51 of file monitor.c.