From: Richard Russon Date: Mon, 3 Sep 2018 01:29:51 +0000 (+0100) Subject: tidy upstream changes X-Git-Tag: 2019-10-25~668^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ddf0d5f0d7bfd66c2dd63f3204211fbd638061d5;p=neomutt tidy upstream changes --- diff --git a/curs_lib.c b/curs_lib.c index feccbf22e..dd1409dc1 100644 --- a/curs_lib.c +++ b/curs_lib.c @@ -121,10 +121,14 @@ void mutt_need_hard_redraw(void) mutt_menu_set_current_redraw_full(); } -/* delay is just like for timeout() or poll(): - * the number of milliseconds mutt_getch() should block for input. - * delay == 0 means mutt_getch() is non-blocking. - * delay < 0 means mutt_getch is blocking. +/** + * mutt_getch_timeout - Set the getch() timeout + * @param delay Timeout delay in ms + * + * delay is just like for timeout() or poll(): the number of milliseconds + * mutt_getch() should block for input. + * * delay == 0 means mutt_getch() is non-blocking. + * * delay < 0 means mutt_getch is blocking. */ void mutt_getch_timeout(int delay) { @@ -133,6 +137,11 @@ void mutt_getch_timeout(int delay) } #ifdef USE_INOTIFY +/** + * mutt_monitor_getch - Get a character and poll the filesystem monitor + * @retval num Character pressed + * @retval ERR Timeout + */ static int mutt_monitor_getch(void) { /* ncurses has its own internal buffer, so before we perform a poll, diff --git a/curs_lib.h b/curs_lib.h index 0924629d2..c77529275 100644 --- a/curs_lib.h +++ b/curs_lib.h @@ -55,8 +55,8 @@ void mutt_flush_macro_to_endcond(void); void mutt_flush_unget_to_endcond(void); void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s); void mutt_format_s_tree(char *buf, size_t buflen, const char *prec, const char *s); +void mutt_getch_timeout(int delay); struct Event mutt_getch(void); -void mutt_getch_timeout(int); int mutt_get_field_full(const char *field, char *buf, size_t buflen, int complete, bool multiple, char ***files, int *numfiles); int mutt_get_field_unbuffered(char *msg, char *buf, size_t buflen, int flags); int mutt_multi_choice(const char *prompt, const char *letters); diff --git a/mailbox.c b/mailbox.c index 7471fa4ed..827783b1c 100644 --- a/mailbox.c +++ b/mailbox.c @@ -234,7 +234,7 @@ static int mailbox_maildir_check_dir(struct Mailbox *mailbox, const char *dir_na */ if (check_new && MailCheckRecent) { - if (stat(path, &sb) == 0 && + if ((stat(path, &sb) == 0) && mutt_stat_timespec_compare(&sb, MUTT_STAT_MTIME, &mailbox->last_visited) < 0) { rc = 0; diff --git a/mailbox.h b/mailbox.h index 64bc43c3f..ea991a8f6 100644 --- a/mailbox.h +++ b/mailbox.h @@ -56,9 +56,9 @@ struct Mailbox bool new; /**< mailbox has new mail */ /* These next three are only set when MailCheckStats is set */ - int msg_count; /**< total number of messages */ - int msg_unread; /**< number of unread messages */ - int msg_flagged; /**< number of flagged messages */ + int msg_count; /**< total number of messages */ + int msg_unread; /**< number of unread messages */ + int msg_flagged; /**< number of flagged messages */ bool notified; /**< user has been notified */ enum MailboxType magic; /**< mailbox type */ diff --git a/mbox/mbox.c b/mbox/mbox.c index 9edfbc943..574268a8b 100644 --- a/mbox/mbox.c +++ b/mbox/mbox.c @@ -830,7 +830,9 @@ static int mbox_mbox_check(struct Context *ctx, int *index_hint) { if ((mutt_stat_timespec_compare(&st, MUTT_STAT_MTIME, &ctx->mtime) == 0) && st.st_size == ctx->size) + { return 0; + } if (st.st_size == ctx->size) { diff --git a/monitor.c b/monitor.c index 3de024481..de43a866f 100644 --- a/monitor.c +++ b/monitor.c @@ -40,9 +40,31 @@ #include "mutt_curses.h" #include "mx.h" -int MonitorFilesChanged; -int MonitorContextChanged; +int MonitorFilesChanged = 0; +int MonitorContextChanged = 0; +static int INotifyFd = -1; +static struct Monitor *Monitor = NULL; +static size_t PollFdsCount = 0; +static size_t PollFdsLen = 0; +static struct pollfd *PollFds = NULL; + +static int MonitorContextDescriptor = -1; + +#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 + +/** + * struct Monitor - A watch on a file + */ struct Monitor { struct Monitor *next; @@ -53,14 +75,9 @@ struct Monitor int desc; }; -static int INotifyFd = -1; -static struct Monitor *Monitor = NULL; -static size_t PollFdsCount = 0; -static size_t PollFdsLen = 0; -static struct pollfd *PollFds; - -static int MonitorContextDescriptor = -1; - +/** + * struct MonitorInfo - Information about a monitored file + */ struct MonitorInfo { short magic; @@ -72,13 +89,15 @@ struct MonitorInfo char path_buf[PATH_MAX]; /* access via path only (maybe not initialized) */ }; -#define INOTIFY_MASK_DIR (IN_MOVED_TO | IN_ATTRIB | IN_CLOSE_WRITE | IN_ISDIR) -#define INOTIFY_MASK_FILE IN_CLOSE_WRITE - +/** + * mutt_poll_fd_add - Add a file to the watch list + * @param fd File to watch + * @param events Events to listen for, e.g. POLLIN + */ static void mutt_poll_fd_add(int fd, short events) { int i = 0; - for (; i < PollFdsCount && PollFds[i].fd != fd; ++i) + for (; (i < PollFdsCount) && (PollFds[i].fd != fd); ++i) ; if (i == PollFdsCount) @@ -96,20 +115,31 @@ static void mutt_poll_fd_add(int fd, short events) PollFds[i].events |= events; } +/** + * mutt_poll_fd_remove - Remove a file from the watch list + * @param fd File to remove + * @retval 0 Success + * @retval -1 Error + */ static int mutt_poll_fd_remove(int fd) { - int i = 0, d; - for (i = 0; i < PollFdsCount && PollFds[i].fd != fd; ++i) + int i = 0; + for (; (i < PollFdsCount) && (PollFds[i].fd != fd); ++i) ; if (i == PollFdsCount) return -1; - d = PollFdsCount - i - 1; - if (d) + int d = PollFdsCount - i - 1; + if (d != 0) memmove(&PollFds[i], &PollFds[i + 1], d * sizeof(struct pollfd)); PollFdsCount--; return 0; } +/** + * monitor_init - Set up file monitoring + * @retval 0 Success + * @retval -1 Error + */ static int monitor_init(void) { if (INotifyFd == -1) @@ -126,9 +156,12 @@ static int monitor_init(void) return 0; } +/** + * monitor_check_free - Close down file monitoring + */ static void monitor_check_free(void) { - if (!Monitor && INotifyFd != -1) + if (!Monitor && (INotifyFd != -1)) { mutt_poll_fd_remove(INotifyFd); close(INotifyFd); @@ -137,6 +170,12 @@ static void monitor_check_free(void) } } +/** + * monitor_create - Create a new file monitor + * @param info Details of file to monitor + * @param descriptor Watch descriptor + * @retval ptr Newly allocated Monitor + */ static struct Monitor *monitor_create(struct MonitorInfo *info, int descriptor) { struct Monitor *monitor = mutt_mem_calloc(1, sizeof(struct Monitor)); @@ -153,6 +192,10 @@ static struct Monitor *monitor_create(struct MonitorInfo *info, int descriptor) return monitor; } +/** + * monitor_delete - Free a file monitor + * @param monitor Monitor to free + */ static void monitor_delete(struct Monitor *monitor) { struct Monitor **ptr = &Monitor; @@ -169,27 +212,33 @@ static void monitor_delete(struct Monitor *monitor) ptr = &(*ptr)->next; } - FREE(&monitor->mh_backup_path); /* __FREE_CHECKED__ */ + FREE(&monitor->mh_backup_path); monitor = monitor->next; - FREE(ptr); /* __FREE_CHECKED__ */ + FREE(ptr); *ptr = monitor; } +/** + * monitor_handle_ignore - Listen for when a backup file is closed + * @param desc Watch descriptor + * @retval >=0 New descriptor + * @retval -1 Error + */ static int monitor_handle_ignore(int desc) { int new_desc = -1; struct Monitor *iter = Monitor; struct stat sb; - while (iter && iter->desc != desc) + while (iter && (iter->desc != desc)) iter = iter->next; if (iter) { - if (iter->magic == MUTT_MH && stat(iter->mh_backup_path, &sb) == 0) + if ((iter->magic == MUTT_MH) && (stat(iter->mh_backup_path, &sb) == 0)) { - if ((new_desc = inotify_add_watch(INotifyFd, iter->mh_backup_path, - INOTIFY_MASK_FILE)) == -1) + new_desc = inotify_add_watch(INotifyFd, iter->mh_backup_path, INOTIFY_MASK_FILE); + if (new_desc == -1) { mutt_debug(2, "inotify_add_watch failed for '%s', errno=%d %s\n", iter->mh_backup_path, errno, strerror(errno)); @@ -204,7 +253,7 @@ static int monitor_handle_ignore(int desc) } else { - mutt_debug(3, "cleanup watch (implicitely removed) - descriptor=%d\n", desc); + mutt_debug(3, "cleanup watch (implicitly removed) - descriptor=%d\n", desc); } if (MonitorContextDescriptor == desc) @@ -220,30 +269,98 @@ static int monitor_handle_ignore(int desc) return new_desc; } -#define EVENT_BUFLEN MAX(4096, sizeof(struct inotify_event) + NAME_MAX + 1) +/** + * monitor_resolve - Get the monitor for a mailbox + * @param[out] info Details of the mailbox's monitor + * @param[in] mailbox Mailbox + * @retval >=0 mailbox is valid and locally accessible: + * 0: no monitor / 1: preexisting monitor + * @retval -3 no mailbox (MonitorInfo: no fields set) + * @retval -2 magic not set + * @retval -1 stat() failed (see errno; MonitorInfo fields: magic, isdir, path) + * + * If mailbox is NULL, the current mailbox (Context) is used. + */ +static int monitor_resolve(struct MonitorInfo *info, struct Mailbox *mailbox) +{ + struct Monitor *iter; + char *fmt = NULL; + struct stat sb; + + if (mailbox) + { + info->magic = mailbox->magic; + info->path = mailbox->realpath; + } + else if (Context) + { + info->magic = Context->magic; + info->path = Context->realpath; + } + else + { + return RESOLVERES_FAIL_NOMAILBOX; + } + + if (!info->magic) + { + return RESOLVERES_FAIL_NOMAGIC; + } + else if (info->magic == MUTT_MAILDIR) + { + info->isdir = 1; + fmt = "%s/new"; + } + else + { + info->isdir = 0; + if (info->magic == MUTT_MH) + fmt = "%s/.mh_sequences"; + } -/* mutt_monitor_poll: Waits for I/O ready file descriptors or signals. + if (fmt) + { + snprintf(info->path_buf, sizeof(info->path_buf), fmt, info->path); + info->path = info->path_buf; + } + if (stat(info->path, &sb) != 0) + return RESOLVERES_FAIL_STAT; + + iter = Monitor; + while (iter && ((iter->st_ino != sb.st_ino) || (iter->st_dev != sb.st_dev))) + iter = iter->next; + + info->st_dev = sb.st_dev; + info->st_ino = sb.st_ino; + info->monitor = iter; + + return iter ? RESOLVERES_OK_EXISTING : RESOLVERES_OK_NOTEXISTING; +} + +/** + * mutt_monitor_poll - Check for filesystem changes + * @retval -3 unknown/unexpected events: poll timeout / fds not handled by us + * @retval -2 monitor detected changes, no STDIN input + * @retval -1 error (see errno) + * @retval 0 (1) input ready from STDIN, or (2) monitoring inactive -> no poll() + * + * Wait for I/O ready file descriptors or signals. * - * return values: - * -3 unknown/unexpected events: poll timeout / fds not handled by us - * -2 monitor detected changes, no STDIN input - * -1 error (see errno) - * 0 (1) input ready from STDIN, or (2) monitoring inactive -> no poll() * MonitorFilesChanged also reflects changes to monitored files. * * Only STDIN and INotify file handles currently expected/supported. - * More would ask for common infrastructur (sockets?). + * More would ask for common infrastructure (sockets?). */ int mutt_monitor_poll(void) { - int rc = 0, fds, i, inputReady; + int rc = 0; char buf[EVENT_BUFLEN] __attribute__((aligned(__alignof__(struct inotify_event)))); MonitorFilesChanged = 0; if (INotifyFd != -1) { - fds = poll(PollFds, PollFdsLen, MuttGetchTimeout); + int fds = poll(PollFds, PollFdsLen, MuttGetchTimeout); if (fds == -1) { @@ -255,15 +372,15 @@ int mutt_monitor_poll(void) } else { - inputReady = 0; - for (i = 0; fds && i < PollFdsCount; ++i) + bool inputReady = false; + for (int i = 0; fds && (i < PollFdsCount); ++i) { if (PollFds[i].revents) { fds--; if (PollFds[i].fd == 0) { - inputReady = 1; + inputReady = true; } else if (PollFds[i].fd == INotifyFd) { @@ -284,7 +401,7 @@ int mutt_monitor_poll(void) break; } - while (ptr < buf + len) + while (ptr < (buf + len)) { event = (const struct inotify_event *) ptr; mutt_debug(5, "+ detail: descriptor=%d mask=0x%x\n", event->wd, @@ -307,99 +424,28 @@ int mutt_monitor_poll(void) return rc; } -#define RESOLVERES_OK_NOTEXISTING 0 -#define RESOLVERES_OK_EXISTING 1 -#define RESOLVERES_FAIL_NOMAILBOX -3 -#define RESOLVERES_FAIL_NOMAGIC -2 -#define RESOLVERES_FAIL_STAT -1 - -/* monitor_resolve: resolve monitor entry match by Mailbox, or - if NULL - by Context. - * - * return values: - * >=0 mailbox is valid and locally accessible: - * 0: no monitor / 1: preexisting monitor - * -3 no mailbox (MONITORINFO: no fields set) - * -2 magic not set - * -1 stat() failed (see errno; MONITORINFO fields: magic, isdir, path) - */ -static int monitor_resolve(struct MonitorInfo *info, struct Mailbox *mailbox) -{ - struct Monitor *iter; - char *fmt = NULL; - struct stat sb; - - if (mailbox) - { - info->magic = mailbox->magic; - info->path = mailbox->realpath; - } - else if (Context) - { - info->magic = Context->magic; - info->path = Context->realpath; - } - else - { - return RESOLVERES_FAIL_NOMAILBOX; - } - - if (!info->magic) - { - return RESOLVERES_FAIL_NOMAGIC; - } - else if (info->magic == MUTT_MAILDIR) - { - info->isdir = 1; - fmt = "%s/new"; - } - else - { - info->isdir = 0; - if (info->magic == MUTT_MH) - fmt = "%s/.mh_sequences"; - } - - if (fmt) - { - snprintf(info->path_buf, sizeof(info->path_buf), fmt, info->path); - info->path = info->path_buf; - } - if (stat(info->path, &sb) != 0) - return RESOLVERES_FAIL_STAT; - - iter = Monitor; - while (iter && (iter->st_ino != sb.st_ino || iter->st_dev != sb.st_dev)) - iter = iter->next; - - info->st_dev = sb.st_dev; - info->st_ino = sb.st_ino; - info->monitor = iter; - - return iter ? RESOLVERES_OK_EXISTING : RESOLVERES_OK_NOTEXISTING; -} - -/* mutt_monitor_add: add file monitor from Mailbox, or - if NULL - from Context. +/** + * mutt_monitor_add - Add a watch for a mailbox + * @param mailbox Mailbox to watch + * @retval 0 success: new or already existing monitor + * @retval -1 failed: no mailbox, inaccessible file, create monitor/watcher failed * - * return values: - * 0 success: new or already existing monitor - * -1 failed: no mailbox, inaccessible file, create monitor/watcher failed + * If mailbox is NULL, the current mailbox (Context) is used. */ int mutt_monitor_add(struct Mailbox *mailbox) { struct MonitorInfo info; - uint32_t mask; - int desc; - desc = monitor_resolve(&info, mailbox); + int desc = monitor_resolve(&info, mailbox); if (desc != RESOLVERES_OK_NOTEXISTING) { if (!mailbox && (desc == RESOLVERES_OK_EXISTING)) MonitorContextDescriptor = info.monitor->desc; - return desc == RESOLVERES_OK_EXISTING ? 0 : -1; + return (desc == RESOLVERES_OK_EXISTING) ? 0 : -1; } - mask = info.isdir ? INOTIFY_MASK_DIR : INOTIFY_MASK_FILE; - if ((INotifyFd == -1 && monitor_init() == -1) || + uint32_t mask = info.isdir ? INOTIFY_MASK_DIR : INOTIFY_MASK_FILE; + if (((INotifyFd == -1) && (monitor_init() == -1)) || (desc = inotify_add_watch(INotifyFd, info.path, mask)) == -1) { mutt_debug(2, "inotify_add_watch failed for '%s', errno=%d %s\n", info.path, @@ -415,12 +461,14 @@ int mutt_monitor_add(struct Mailbox *mailbox) return 0; } -/* mutt_monitor_remove: remove file monitor from Mailbox, or - if NULL - from Context. +/** + * mutt_monitor_remove - Remove a watch for a mailbox + * @param mailbox Mailbox + * @retval 0 monitor removed (not shared) + * @retval 1 monitor not removed (shared) + * @retval 2 no monitor * - * return values: - * 0 monitor removed (not shared) - * 1 monitor not removed (shared) - * 2 no monitor + * If mailbox is NULL, the current mailbox (Context) is used. */ int mutt_monitor_remove(struct Mailbox *mailbox) { @@ -439,9 +487,11 @@ int mutt_monitor_remove(struct Mailbox *mailbox) { if (mailbox) { - if (monitor_resolve(&info2, NULL) == RESOLVERES_OK_EXISTING && - info.st_ino == info2.st_ino && info.st_dev == info2.st_dev) + if ((monitor_resolve(&info2, NULL) == RESOLVERES_OK_EXISTING) && + (info.st_ino == info2.st_ino) && (info.st_dev == info2.st_dev)) + { return 1; + } } else { diff --git a/mutt.h b/mutt.h index 21e7175a3..5878071ec 100644 --- a/mutt.h +++ b/mutt.h @@ -55,6 +55,9 @@ struct Mapping; #endif #ifndef HAVE_STRUCT_TIMESPEC +/** + * struct timespec - Time value with nanosecond precision + */ struct timespec { time_t tv_sec; @@ -62,7 +65,11 @@ struct timespec }; #endif -/* flags for mutt_get_stat_timespec */ +/** + * enum MuttStatType - Flags for mutt_get_stat_timespec + * + * These represent filesystem timestamps returned by stat() + */ enum MuttStatType { MUTT_STAT_ATIME, diff --git a/muttlib.c b/muttlib.c index cd01c7763..be2382f0d 100644 --- a/muttlib.c +++ b/muttlib.c @@ -1434,6 +1434,14 @@ void mutt_sleep(short s) sleep(s); } +/** + * mutt_timespec_compare - Compare to time values + * @param a First time value + * @param b Second time value + * @retval -1 a precedes b + * @retval 0 a and b are identical + * @retval 1 b precedes a + */ int mutt_timespec_compare(struct timespec *a, struct timespec *b) { if (a->tv_sec < b->tv_sec) @@ -1448,6 +1456,12 @@ int mutt_timespec_compare(struct timespec *a, struct timespec *b) return 0; } +/** + * mutt_get_stat_timespec - Read the stat() time into a time value + * @param dest Time value to populate + * @param sb stat info + * @param type Type of stat info to read, e.g. #MUTT_STAT_ATIME + */ void mutt_get_stat_timespec(struct timespec *dest, struct stat *sb, enum MuttStatType type) { dest->tv_nsec = 0; @@ -1475,6 +1489,15 @@ void mutt_get_stat_timespec(struct timespec *dest, struct stat *sb, enum MuttSta } } +/** + * mutt_stat_timespec_compare - Compare stat info with a time value + * @param sba stat info + * @param type Type of stat info, e.g. #MUTT_STAT_ATIME + * @param b Time value + * @retval -1 a precedes b + * @retval 0 a and b are identical + * @retval 1 b precedes a + */ int mutt_stat_timespec_compare(struct stat *sba, enum MuttStatType type, struct timespec *b) { struct timespec a; @@ -1483,6 +1506,16 @@ int mutt_stat_timespec_compare(struct stat *sba, enum MuttStatType type, struct return mutt_timespec_compare(&a, b); } +/** + * mutt_stat_compare - Compare two stat infos + * @param sba First stat info + * @param sba_type Type of first stat info, e.g. #MUTT_STAT_ATIME + * @param sbb Second stat info + * @param sbb_type Type of second stat info, e.g. #MUTT_STAT_ATIME + * @retval -1 a precedes b + * @retval 0 a and b are identical + * @retval 1 b precedes a + */ int mutt_stat_compare(struct stat *sba, enum MuttStatType sba_type, struct stat *sbb, enum MuttStatType sbb_type) {