1 /* Copyright 2012-present Facebook, Inc.
2  * Licensed under the Apache License, Version 2.0 */
3 
4 #ifndef WATCHMAN_H
5 #define WATCHMAN_H
6 
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
11 #define _GNU_SOURCE 1
12 #include "config.h"
13 
14 #include <assert.h>
15 #if HAVE_UNISTD_H
16 #include <unistd.h>
17 #endif
18 #include <ctype.h>
19 #include <stdint.h>
20 #include <sys/stat.h>
21 #if HAVE_SYS_INOTIFY_H
22 # include <sys/inotify.h>
23 #endif
24 #if HAVE_SYS_EVENT_H
25 # include <sys/event.h>
26 #endif
27 #if HAVE_PORT_H
28 # include <port.h>
29 #endif
30 #include <signal.h>
31 #include <errno.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <pthread.h>
35 #include <stdio.h>
36 #include <sys/types.h>
37 #include <dirent.h>
38 #include <stdbool.h>
39 #include <sys/time.h>
40 #include <time.h>
41 #ifndef _WIN32
42 #include <libgen.h>
43 #endif
44 #include <inttypes.h>
45 #include <limits.h>
46 #ifndef _WIN32
47 #include <sys/socket.h>
48 #include <sys/un.h>
49 #endif
50 #include <fcntl.h>
51 #if defined(__linux__) && !defined(O_CLOEXEC)
52 # define O_CLOEXEC   02000000 /* set close_on_exec, from asm/fcntl.h */
53 #endif
54 #ifndef O_CLOEXEC
55 # define O_CLOEXEC 0
56 #endif
57 #ifndef _WIN32
58 #include <sys/poll.h>
59 #include <sys/wait.h>
60 #endif
61 #ifdef HAVE_PCRE_H
62 # include <pcre.h>
63 #endif
64 #ifdef HAVE_EXECINFO_H
65 # include <execinfo.h>
66 #endif
67 #ifndef _WIN32
68 #include <sys/uio.h>
69 #include <pwd.h>
70 #include <sysexits.h>
71 #endif
72 #include <spawn.h>
73 #include <stddef.h>
74 #ifdef HAVE_SYS_PARAM_H
75 # include <sys/param.h>
76 #endif
77 #ifdef HAVE_SYS_RESOURCE_H
78 # include <sys/resource.h>
79 #endif
80 #ifndef _WIN32
81 // Not explicitly exported on Darwin, so we get to define it.
82 extern char **environ;
83 #endif
84 
85 #ifdef _WIN32
86 # define PRIsize_t "Iu"
87 #else
88 # define PRIsize_t "zu"
89 #endif
90 
91 #ifndef WATCHMAN_DIR_SEP
92 # define WATCHMAN_DIR_SEP '/'
93 # define WATCHMAN_DIR_DOT '.'
94 #endif
95 
96 #ifdef _WIN32
97 # define PRIsize_t "Iu"
98 #else
99 # define PRIsize_t "zu"
100 #endif
101 
102 extern char *poisoned_reason;
103 
104 #include "watchman_hash.h"
105 #include "watchman_stream.h"
106 
107 #include "jansson.h"
108 
109 #ifdef HAVE_CORESERVICES_CORESERVICES_H
110 # include <CoreServices/CoreServices.h>
111 # if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
112 #  define HAVE_FSEVENTS 0
113 # else
114 #  define HAVE_FSEVENTS 1
115 # endif
116 #endif
117 
118 // Helpers for pasting __LINE__ for symbol generation
119 #define w_paste2(pre, post)  pre ## post
120 #define w_paste1(pre, post)  w_paste2(pre, post)
121 #define w_gen_symbol(pre)    w_paste1(pre, __LINE__)
122 
123 // We make use of constructors to glue together modules
124 // without maintaining static lists of things in the build
125 // configuration.  These are helpers to make this work
126 // more portably
127 #ifdef _WIN32
128 #pragma section(".CRT$XCU", read)
129 # define w_ctor_fn_type(sym) void __cdecl sym(void)
130 # define w_ctor_fn_reg(sym) \
131   static __declspec(allocate(".CRT$XCU")) \
132     void (__cdecl * w_paste1(sym, _reg))(void) = sym;
133 #else
134 # define w_ctor_fn_type(sym) \
135   __attribute__((constructor)) void sym(void)
136 # define w_ctor_fn_reg(sym) /* not needed */
137 #endif
138 
139 /* sane, reasonably large filename size that we'll use
140  * throughout; POSIX seems to define smallish buffers
141  * that seem risky */
142 #define WATCHMAN_NAME_MAX   4096
143 
144 // rpmbuild may enable fortify which turns on
145 // warn_unused_result on a number of system functions.
146 // This gives us a reasonably clean way to suppress
147 // these warnings when we're using stack protection.
148 #if __USE_FORTIFY_LEVEL > 0
149 # define ignore_result(x) \
150   do { __typeof__(x) _res = x; (void)_res; } while(0)
151 #elif _MSC_VER >= 1400
152 # define ignore_result(x) \
153   do { int _res = (int)x; (void)_res; } while(0)
154 #else
155 # define ignore_result(x) x
156 #endif
157 
158 // self-documenting hint to the compiler that we didn't use it
159 #define unused_parameter(x)  (void)x
160 
w_refcnt_add(volatile long * refcnt)161 static inline void w_refcnt_add(volatile long *refcnt)
162 {
163   (void)__sync_fetch_and_add(refcnt, 1);
164 }
165 
166 /* returns true if we deleted the last ref */
w_refcnt_del(volatile long * refcnt)167 static inline bool w_refcnt_del(volatile long *refcnt)
168 {
169   return __sync_add_and_fetch(refcnt, -1) == 0;
170 }
171 
w_set_cloexec(int fd)172 static inline void w_set_cloexec(int fd)
173 {
174 #ifndef _WIN32
175   ignore_result(fcntl(fd, F_SETFD, FD_CLOEXEC));
176 #else
177   unused_parameter(fd);
178 #endif
179 }
180 
w_set_nonblock(int fd)181 static inline void w_set_nonblock(int fd)
182 {
183 #ifndef _WIN32
184   ignore_result(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK));
185 #else
186   unused_parameter(fd);
187 #endif
188 }
189 
w_clear_nonblock(int fd)190 static inline void w_clear_nonblock(int fd)
191 {
192 #ifndef _WIN32
193   ignore_result(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK));
194 #else
195   unused_parameter(fd);
196 #endif
197 }
198 
199 // Make a temporary file name and open it.
200 // Marks the file as CLOEXEC
201 w_stm_t w_mkstemp(char *templ);
202 char *w_realpath(const char *filename);
203 bool w_is_path_absolute(const char *path);
204 
205 #ifndef _WIN32
w_path_exists(const char * path)206 static inline bool w_path_exists(const char *path) {
207   return access(path, F_OK) == 0;
208 }
209 #else
210 bool w_path_exists(const char *path);
211 #endif
212 
213 struct watchman_string;
214 typedef struct watchman_string w_string_t;
215 struct watchman_string {
216   long refcnt;
217   uint32_t hval;
218   uint32_t len;
219   w_string_t *slice;
220   const char *buf;
221 };
222 
223 /* small for testing, but should make this greater than the number of dirs we
224  * have in our repos to avoid realloc */
225 #define HINT_NUM_DIRS 128*1024
226 
227 /* We leverage the fact that our aligned pointers will never set the LSB of a
228  * pointer value.  We can use the LSB to indicate whether kqueue entries are
229  * dirs or files */
230 #define SET_DIR_BIT(dir)   ((void*)(((intptr_t)dir) | 0x1))
231 #define IS_DIR_BIT_SET(dir) ((((intptr_t)dir) & 0x1) == 0x1)
232 #define DECODE_DIR(dir)    ((void*)(((intptr_t)dir) & ~0x1))
233 
234 struct watchman_file;
235 struct watchman_dir;
236 struct watchman_root;
237 struct watchman_pending_fs;
238 struct watchman_trigger_command;
239 typedef struct watchman_root w_root_t;
240 
241 // Process global state for the selected watcher
242 typedef void *watchman_global_watcher_t;
243 // Per-watch state for the selected watcher
244 typedef void *watchman_watcher_t;
245 
246 struct watchman_clock {
247   uint32_t ticks;
248   struct timeval tv;
249 };
250 typedef struct watchman_clock w_clock_t;
251 
252 #define W_PENDING_RECURSIVE   1
253 #define W_PENDING_VIA_NOTIFY 2
254 #define W_PENDING_CRAWL_ONLY  4
255 struct watchman_pending_fs {
256   struct watchman_pending_fs *next;
257   w_string_t *path;
258   struct timeval now;
259   int flags;
260 };
261 
262 struct watchman_pending_collection {
263   struct watchman_pending_fs *pending;
264   w_ht_t *pending_uniq;
265   pthread_mutex_t lock;
266   pthread_cond_t cond;
267   bool pinged;
268 };
269 
270 bool w_pending_coll_init(struct watchman_pending_collection *coll);
271 void w_pending_coll_destroy(struct watchman_pending_collection *coll);
272 void w_pending_coll_drain(struct watchman_pending_collection *coll);
273 void w_pending_coll_lock(struct watchman_pending_collection *coll);
274 void w_pending_coll_unlock(struct watchman_pending_collection *coll);
275 bool w_pending_coll_add(struct watchman_pending_collection *coll,
276     w_string_t *path, struct timeval now, int flags);
277 bool w_pending_coll_add_rel(struct watchman_pending_collection *coll,
278     struct watchman_dir *dir, const char *name,
279     struct timeval now, int flags);
280 void w_pending_coll_append(struct watchman_pending_collection *target,
281     struct watchman_pending_collection *src);
282 struct watchman_pending_fs *w_pending_coll_pop(
283     struct watchman_pending_collection *coll);
284 bool w_pending_coll_lock_and_wait(struct watchman_pending_collection *coll,
285     int timeoutms);
286 void w_pending_coll_ping(struct watchman_pending_collection *coll);
287 uint32_t w_pending_coll_size(struct watchman_pending_collection *coll);
288 void w_pending_fs_free(struct watchman_pending_fs *p);
289 
290 struct watchman_dir {
291   /* full path */
292   w_string_t *path;
293   /* files contained in this dir (keyed by file->name) */
294   w_ht_t *files;
295   /* child dirs contained in this dir (keyed by dir->path) */
296   w_ht_t *dirs;
297 };
298 
299 struct watchman_ops {
300   // What's it called??
301   const char *name;
302 
303   // if this watcher notifies for individual files contained within
304   // a watched dir, false if it only notifies for dirs
305 #define WATCHER_HAS_PER_FILE_NOTIFICATIONS 1
306   // if renames do not reliably report the individual
307   // files renamed in the hierarchy
308 #define WATCHER_COALESCED_RENAME 2
309   unsigned flags;
310 
311   // Perform any global initialization needed for the watcher mechanism
312   // and return a context pointer that will be passed to all other ops
313   watchman_global_watcher_t (*global_init)(void);
314 
315   // Perform global shutdown of the watcher at process shutdown time.
316   // We're not guaranteed that this will be called, depending on how
317   // the process is shutdown
318   void (*global_dtor)(watchman_global_watcher_t watcher);
319 
320   // Perform watcher-specific initialization for a watched root.
321   // Do not start threads here
322   bool (*root_init)(watchman_global_watcher_t watcher, w_root_t *root,
323       char **errmsg);
324 
325   // Start up threads or similar.  Called in the context of the
326   // notify thread
327   bool (*root_start)(watchman_global_watcher_t watcher, w_root_t *root);
328 
329   // Perform watcher-specific cleanup for a watched root when it is freed
330   void (*root_dtor)(watchman_global_watcher_t watcher, w_root_t *root);
331 
332   // Initiate an OS-level watch on the provided file
333   bool (*root_start_watch_file)(watchman_global_watcher_t watcher,
334       w_root_t *root, struct watchman_file *file);
335 
336   // Cancel an OS-level watch on the provided file
337   void (*root_stop_watch_file)(watchman_global_watcher_t watcher,
338       w_root_t *root, struct watchman_file *file);
339 
340   // Initiate an OS-level watch on the provided dir, return a DIR
341   // handle, or NULL on error
342   struct watchman_dir_handle *(*root_start_watch_dir)(
343       watchman_global_watcher_t watcher,
344       w_root_t *root, struct watchman_dir *dir, struct timeval now,
345       const char *path);
346 
347   // Cancel an OS-level watch on the provided dir
348   void (*root_stop_watch_dir)(watchman_global_watcher_t watcher,
349       w_root_t *root, struct watchman_dir *dir);
350 
351   // Signal any threads to terminate.  Do not join them here.
352   void (*root_signal_threads)(watchman_global_watcher_t watcher,
353       w_root_t *root);
354 
355   // Consume any available notifications.  If there are none pending,
356   // does not block.
357   bool (*root_consume_notify)(watchman_global_watcher_t watcher,
358       w_root_t *root, struct watchman_pending_collection *coll);
359 
360   // Wait for an inotify event to become available
361   bool (*root_wait_notify)(watchman_global_watcher_t watcher,
362       w_root_t *root, int timeoutms);
363 
364   // Called when freeing a file node
365   void (*file_free)(watchman_global_watcher_t watcher,
366       struct watchman_file *file);
367 };
368 
369 struct watchman_stat {
370   struct timespec atime, mtime, ctime;
371   off_t size;
372   mode_t mode;
373   uid_t uid;
374   gid_t gid;
375   ino_t ino;
376   dev_t dev;
377   nlink_t nlink;
378 };
379 
380 /* opaque (system dependent) type for walking dir contents */
381 struct watchman_dir_handle;
382 
383 struct watchman_dir_ent {
384   bool has_stat;
385   char *d_name;
386   struct watchman_stat stat;
387 };
388 
389 struct watchman_dir_handle *w_dir_open(const char *path);
390 struct watchman_dir_ent *w_dir_read(struct watchman_dir_handle *dir);
391 void w_dir_close(struct watchman_dir_handle *dir);
392 int w_dir_fd(struct watchman_dir_handle *dir);
393 
394 struct watchman_file {
395   /* our name within the parent dir */
396   w_string_t *name;
397   /* the parent dir */
398   struct watchman_dir *parent;
399 
400   /* linkage to files ordered by changed time */
401   struct watchman_file *prev, *next;
402 
403   /* linkage to files ordered by common suffix */
404   struct watchman_file *suffix_prev, *suffix_next;
405 
406   /* the time we last observed a change to this file */
407   w_clock_t otime;
408   /* the time we first observed this file OR the time
409    * that this file switched from !exists to exists.
410    * This is thus the "created time" */
411   w_clock_t ctime;
412 
413   /* whether we believe that this file still exists */
414   bool exists;
415   /* whether we think this file might not exist */
416   bool maybe_deleted;
417 
418   /* cache stat results so we can tell if an entry
419    * changed */
420   struct watchman_stat stat;
421 };
422 
423 #define WATCHMAN_COOKIE_PREFIX ".watchman-cookie-"
424 struct watchman_query_cookie {
425   pthread_cond_t cond;
426   bool seen;
427 };
428 
429 #define WATCHMAN_IO_BUF_SIZE 1048576
430 #define WATCHMAN_BATCH_LIMIT (16*1024)
431 #define DEFAULT_SETTLE_PERIOD 20
432 #define DEFAULT_QUERY_SYNC_MS 60000
433 
434 /* Prune out nodes that were deleted roughly 12-36 hours ago */
435 #define DEFAULT_GC_AGE (86400/2)
436 #define DEFAULT_GC_INTERVAL 86400
437 
438 /* Idle out watches that haven't had activity in several days */
439 #define DEFAULT_REAP_AGE (86400*5)
440 
441 struct watchman_root {
442   long refcnt;
443 
444   /* path to root */
445   w_string_t *root_path;
446   bool case_sensitive;
447 
448   /* our locking granularity is per-root */
449   pthread_mutex_t lock;
450   pthread_t notify_thread;
451   pthread_t io_thread;
452 
453   /* map of rule id => struct watchman_trigger_command */
454   w_ht_t *commands;
455 
456   /* path to the query cookie dir */
457   w_string_t *query_cookie_dir;
458   w_string_t *query_cookie_prefix;
459   w_ht_t *query_cookies;
460 
461   /* map of dir name => dirname
462    * if the map has an entry for a given dir, we're ignoring it */
463   w_ht_t *ignore_vcs;
464   w_ht_t *ignore_dirs;
465 
466   int trigger_settle;
467   int gc_interval;
468   int gc_age;
469   int idle_reap_age;
470 
471   /* config options loaded via json file */
472   json_t *config_file;
473 
474   /* how many times we've had to recrawl */
475   int recrawl_count;
476   w_string_t *last_recrawl_reason;
477 
478   // Why we failed to watch
479   w_string_t *failure_reason;
480 
481   // Last ad-hoc warning message
482   w_string_t *warning;
483 
484   /* queue of items that we need to stat/process */
485   struct watchman_pending_collection pending;
486 
487   // map of state name => watchman_client_state_assertion for
488   // asserted states
489   w_ht_t *asserted_states;
490 
491   /* --- everything below this point will be reset on w_root_init --- */
492   bool _init_sentinel_;
493 
494   /* root number */
495   uint32_t number;
496 
497   // Watcher specific state
498   watchman_watcher_t watch;
499 
500   /* map of dir name to a dir */
501   w_ht_t *dirname_to_dir;
502 
503   /* the most recently changed file */
504   struct watchman_file *latest_file;
505 
506   /* current tick */
507   uint32_t ticks;
508 
509   bool done_initial;
510   /* if true, we've decided that we should re-crawl the root
511    * for the sake of ensuring consistency */
512   bool should_recrawl;
513   bool cancelled;
514 
515   /* map of cursor name => last observed tick value */
516   w_ht_t *cursors;
517 
518   /* map of filename suffix => watchman_file at the head
519    * of the suffix index.  Linkage via suffix_next */
520   w_ht_t *suffixes;
521 
522   uint32_t next_cmd_id;
523   uint32_t last_trigger_tick;
524   uint32_t pending_trigger_tick;
525   uint32_t pending_sub_tick;
526   uint32_t last_age_out_tick;
527   uint32_t last_recheck_tick;
528   time_t last_age_out_timestamp;
529   time_t last_cmd_timestamp;
530   time_t last_reap_timestamp;
531 };
532 
533 enum w_pdu_type {
534   need_data,
535   is_json_compact,
536   is_json_pretty,
537   is_bser
538 };
539 
540 struct watchman_json_buffer {
541   char *buf;
542   uint32_t allocd;
543   uint32_t rpos, wpos;
544   enum w_pdu_type pdu_type;
545 };
546 typedef struct watchman_json_buffer w_jbuffer_t;
547 bool w_json_buffer_init(w_jbuffer_t *jr);
548 void w_json_buffer_reset(w_jbuffer_t *jr);
549 void w_json_buffer_free(w_jbuffer_t *jr);
550 json_t *w_json_buffer_next(w_jbuffer_t *jr, w_stm_t stm, json_error_t *jerr);
551 bool w_json_buffer_passthru(w_jbuffer_t *jr,
552     enum w_pdu_type output_pdu,
553     w_jbuffer_t *output_pdu_buf,
554     w_stm_t stm);
555 bool w_json_buffer_write(w_jbuffer_t *jr, w_stm_t stm, json_t *json, int flags);
556 bool w_json_buffer_write_bser(w_jbuffer_t *jr, w_stm_t stm, json_t *json);
557 bool w_ser_write_pdu(enum w_pdu_type pdu_type,
558     w_jbuffer_t *jr, w_stm_t stm, json_t *json);
559 
560 #define BSER_MAGIC "\x00\x01"
561 int w_bser_write_pdu(json_t *json, json_dump_callback_t dump, void *data);
562 int w_bser_dump(json_t *json, json_dump_callback_t dump, void *data);
563 bool bunser_int(const char *buf, json_int_t avail,
564     json_int_t *needed, json_int_t *val);
565 json_t *bunser(const char *buf, const char *end,
566     json_int_t *needed, json_error_t *jerr);
567 
568 struct watchman_client_response {
569   struct watchman_client_response *next;
570   json_t *json;
571 };
572 
573 struct watchman_client_subscription;
574 
575 struct watchman_client_state_assertion {
576   w_root_t *root; // Holds a ref on the root
577   w_string_t *name;
578   long id;
579 };
580 
581 struct watchman_client {
582   w_stm_t stm;
583   w_evt_t ping;
584   int log_level;
585   w_jbuffer_t reader, writer;
586   bool client_mode;
587   enum w_pdu_type pdu_type;
588 
589   struct watchman_client_response *head, *tail;
590   /* map of subscription name => struct watchman_client_subscription */
591   w_ht_t *subscriptions;
592 
593   /* map of unique id => watchman_client_state_assertion */
594   w_ht_t *states;
595   long next_state_id;
596 };
597 extern pthread_mutex_t w_client_lock;
598 extern w_ht_t *clients;
599 
600 void w_client_vacate_states(struct watchman_client *client);
601 
602 void w_mark_dead(pid_t pid);
603 bool w_reap_children(bool block);
604 
605 #define W_LOG_OFF 0
606 #define W_LOG_ERR 1
607 #define W_LOG_DBG 2
608 #define W_LOG_FATAL -1
609 
610 #ifndef WATCHMAN_FMT_STRING
611 # define WATCHMAN_FMT_STRING(x) x
612 #endif
613 
614 extern int log_level;
615 extern char *log_name;
616 const char *w_set_thread_name(const char *fmt, ...);
617 const char *w_get_thread_name(void);
618 void w_setup_signal_handlers(void);
619 void w_log(int level, WATCHMAN_FMT_STRING(const char *fmt), ...)
620 #ifdef __GNUC__
621   __attribute__((format(printf, 2, 3)))
622 #endif
623 ;
624 void w_request_shutdown(void);
625 
626 bool w_should_log_to_clients(int level);
627 void w_log_to_clients(int level, const char *buf);
628 
629 bool w_is_ignored(w_root_t *root, const char *path, uint32_t pathlen);
630 void w_timeoutms_to_abs_timespec(int timeoutms, struct timespec *deadline);
631 
632 json_t *w_string_to_json(w_string_t *str);
633 w_string_t *w_string_new(const char *str);
634 #ifdef _WIN32
635 w_string_t *w_string_new_wchar(WCHAR *str, int len);
636 #endif
637 w_string_t *w_string_make_printf(const char *format, ...);
638 w_string_t *w_string_new_lower(const char *str);
639 w_string_t *w_string_dup_lower(w_string_t *str);
640 w_string_t *w_string_suffix(w_string_t *str);
641 bool w_string_suffix_match(w_string_t *str, w_string_t *suffix);
642 w_string_t *w_string_slice(w_string_t *str, uint32_t start, uint32_t len);
643 char *w_string_dup_buf(const w_string_t *str);
644 void w_string_addref(w_string_t *str);
645 void w_string_delref(w_string_t *str);
646 int w_string_compare(const w_string_t *a, const w_string_t *b);
647 bool w_string_equal(const w_string_t *a, const w_string_t *b);
648 bool w_string_equal_cstring(const w_string_t *a, const char *b);
649 bool w_string_equal_caseless(const w_string_t *a, const w_string_t *b);
650 w_string_t *w_string_dirname(w_string_t *str);
651 w_string_t *w_string_basename(w_string_t *str);
652 w_string_t *w_string_new_basename(const char *path);
653 w_string_t *w_string_canon_path(w_string_t *str);
654 void w_string_in_place_normalize_separators(w_string_t **str, char target_sep);
655 w_string_t *w_string_normalize_separators(w_string_t *str, char target_sep);
656 w_string_t *w_string_path_cat(w_string_t *parent, w_string_t *rhs);
657 w_string_t *w_string_path_cat_cstr(w_string_t *parent, const char *rhs);
658 bool w_string_startswith(w_string_t *str, w_string_t *prefix);
659 bool w_string_startswith_caseless(w_string_t *str, w_string_t *prefix);
660 w_string_t *w_string_shell_escape(const w_string_t *str);
661 w_string_t *w_string_implode(json_t *arr, const char *delim);
662 
663 // Returns the name of the filesystem for the specified path
664 w_string_t *w_fstype(const char *path);
665 
666 void w_root_crawl_recursive(w_root_t *root, w_string_t *dir_name, time_t now);
667 w_root_t *w_root_resolve(const char *path, bool auto_watch, char **errmsg);
668 w_root_t *w_root_resolve_for_client_mode(const char *filename, char **errmsg);
669 char *w_find_enclosing_root(const char *filename, char **relpath);
670 struct watchman_file *w_root_resolve_file(w_root_t *root,
671     struct watchman_dir *dir, w_string_t *file_name,
672     struct timeval now);
673 
674 void w_root_perform_age_out(w_root_t *root, int min_age);
675 void w_root_free_watched_roots(void);
676 void w_root_schedule_recrawl(w_root_t *root, const char *why);
677 bool w_root_cancel(w_root_t *root);
678 bool w_root_stop_watch(w_root_t *root);
679 json_t *w_root_stop_watch_all(void);
680 void w_root_mark_deleted(w_root_t *root, struct watchman_dir *dir,
681     struct timeval now, bool recursive);
682 void w_root_reap(void);
683 void w_root_delref(w_root_t *root);
684 void w_root_addref(w_root_t *root);
685 void w_root_set_warning(w_root_t *root, w_string_t *str);
686 
687 struct watchman_dir *w_root_resolve_dir(w_root_t *root,
688     w_string_t *dir_name, bool create);
689 void w_root_process_path(w_root_t *root,
690     struct watchman_pending_collection *coll, w_string_t *full_path,
691     struct timeval now, int flags,
692     struct watchman_dir_ent *pre_stat);
693 bool w_root_process_pending(w_root_t *root,
694     struct watchman_pending_collection *coll,
695     bool pull_from_root);
696 
697 void w_root_mark_file_changed(w_root_t *root, struct watchman_file *file,
698     struct timeval now);
699 
700 bool w_root_sync_to_now(w_root_t *root, int timeoutms);
701 
702 void w_root_lock(w_root_t *root);
703 void w_root_unlock(w_root_t *root);
704 
705 /* Bob Jenkins' lookup3.c hash function */
706 uint32_t w_hash_bytes(const void *key, size_t length, uint32_t initval);
707 
708 struct watchman_rule_match {
709   uint32_t root_number;
710   w_string_t *relname;
711   bool is_new;
712   struct watchman_file *file;
713 };
714 
715 enum w_clockspec_tag {
716   w_cs_timestamp,
717   w_cs_clock,
718   w_cs_named_cursor
719 };
720 
721 struct w_clockspec {
722   enum w_clockspec_tag tag;
723   union {
724     struct timeval timestamp;
725     struct {
726       uint64_t start_time;
727       int pid;
728       uint32_t root_number;
729       uint32_t ticks;
730     } clock;
731     struct {
732       w_string_t *cursor;
733     } named_cursor;
734   };
735 };
736 
737 struct w_query_since {
738   bool is_timestamp;
739   union {
740     struct timeval timestamp;
741     struct {
742       bool is_fresh_instance;
743       uint32_t ticks;
744     } clock;
745   };
746 };
747 
748 void w_run_subscription_rules(
749     struct watchman_client *client,
750     struct watchman_client_subscription *sub,
751     w_root_t *root);
752 
753 void w_match_results_free(uint32_t num_matches,
754     struct watchman_rule_match *matches);
755 
next_power_2(uint32_t n)756 static inline uint32_t next_power_2(uint32_t n)
757 {
758   n |= (n >> 16);
759   n |= (n >> 8);
760   n |= (n >> 4);
761   n |= (n >> 2);
762   n |= (n >> 1);
763   return n + 1;
764 }
765 
766 /* compare two timevals and return -1 if a is < b, 0 if a == b,
767  * or 1 if b > a */
w_timeval_compare(struct timeval a,struct timeval b)768 static inline int w_timeval_compare(struct timeval a, struct timeval b)
769 {
770   if (a.tv_sec < b.tv_sec) {
771     return -1;
772   }
773   if (a.tv_sec > b.tv_sec) {
774     return 1;
775   }
776   if (a.tv_usec < b.tv_usec) {
777     return -1;
778   }
779   if (a.tv_usec > b.tv_usec) {
780     return 1;
781   }
782   return 0;
783 }
784 
785 #define WATCHMAN_USEC_IN_SEC 1000000
786 #define WATCHMAN_NSEC_IN_USEC 1000
787 #define WATCHMAN_NSEC_IN_SEC (1000 * 1000 * 1000)
788 #define WATCHMAN_NSEC_IN_MSEC 1000000
789 
790 #if defined(__APPLE__) || defined(__FreeBSD__) \
791  || (defined(__NetBSD__) && (__NetBSD_Version__ < 6099000000))
792 /* BSD-style subsecond timespec */
793 #define WATCHMAN_ST_TIMESPEC(type) st_##type##timespec
794 #else
795 /* POSIX standard timespec */
796 #define WATCHMAN_ST_TIMESPEC(type) st_##type##tim
797 #endif
798 
w_timeval_add(const struct timeval a,const struct timeval b,struct timeval * result)799 static inline void w_timeval_add(const struct timeval a,
800     const struct timeval b, struct timeval *result)
801 {
802   result->tv_sec = a.tv_sec + b.tv_sec;
803   result->tv_usec = a.tv_usec + b.tv_usec;
804 
805   if (result->tv_usec > WATCHMAN_USEC_IN_SEC) {
806     result->tv_sec++;
807     result->tv_usec -= WATCHMAN_USEC_IN_SEC;
808   }
809 }
810 
w_timeval_sub(const struct timeval a,const struct timeval b,struct timeval * result)811 static inline void w_timeval_sub(const struct timeval a,
812     const struct timeval b, struct timeval *result)
813 {
814   result->tv_sec = a.tv_sec - b.tv_sec;
815   result->tv_usec = a.tv_usec - b.tv_usec;
816 
817   if (result->tv_usec < 0) {
818     result->tv_sec--;
819     result->tv_usec += WATCHMAN_USEC_IN_SEC;
820   }
821 }
822 
w_timeval_to_timespec(const struct timeval a,struct timespec * ts)823 static inline void w_timeval_to_timespec(
824     const struct timeval a, struct timespec *ts)
825 {
826   ts->tv_sec = a.tv_sec;
827   ts->tv_nsec = a.tv_usec * WATCHMAN_NSEC_IN_USEC;
828 }
829 
w_timeval_diff(struct timeval start,struct timeval end)830 static inline double w_timeval_diff(struct timeval start, struct timeval end)
831 {
832   double s = start.tv_sec + ((double)start.tv_usec)/WATCHMAN_USEC_IN_SEC;
833   double e = end.tv_sec + ((double)end.tv_usec)/WATCHMAN_USEC_IN_SEC;
834 
835   return e - s;
836 }
837 
838 extern const char *watchman_tmp_dir;
839 extern char *watchman_state_file;
840 extern int dont_save_state;
841 bool w_state_save(void);
842 bool w_state_load(void);
843 bool w_root_save_state(json_t *state);
844 bool w_root_load_state(json_t *state);
845 json_t *w_root_trigger_list_to_json(w_root_t *root);
846 json_t *w_root_watch_list_to_json(void);
847 
848 bool w_start_listener(const char *socket_path);
849 void w_check_my_sock(void);
850 char **w_argv_copy_from_json(json_t *arr, int skip);
851 
852 w_ht_t *w_envp_make_ht(void);
853 char **w_envp_make_from_ht(w_ht_t *ht, uint32_t *env_size);
854 void w_envp_set_cstring(w_ht_t *envht, const char *key, const char *val);
855 void w_envp_set(w_ht_t *envht, const char *key, w_string_t *val);
856 void w_envp_set_list(w_ht_t *envht, const char *key, json_t *arr);
857 void w_envp_set_bool(w_ht_t *envht, const char *key, bool val);
858 void w_envp_unset(w_ht_t *envht, const char *key);
859 
860 struct watchman_getopt {
861   /* name of long option: --optname */
862   const char *optname;
863   /* if non-zero, short option character */
864   int shortopt;
865   /* help text shown in the usage information */
866   const char *helptext;
867   /* whether we accept an argument */
868   enum {
869     OPT_NONE,
870     REQ_STRING,
871     REQ_INT,
872   } argtype;
873   /* if an argument was provided, *val will be set to
874    * point to the option value.
875    * Because we only update the option if one was provided
876    * by the user, you can safely pre-initialize the val
877    * pointer to your choice of default.
878    * */
879   void *val;
880 
881   /* if argtype != OPT_NONE, this is the label used to
882    * refer to the argument in the help text.  If left
883    * blank, we'll use the string "ARG" as a generic
884    * alternative */
885   const char *arglabel;
886 
887   // Whether this option should be passed to the child
888   // when running under the gimli monitor
889   int is_daemon;
890 #define IS_DAEMON 1
891 #define NOT_DAEMON 0
892 };
893 
894 #ifndef MIN
895 # define MIN(a, b)  (a) < (b) ? (a) : (b)
896 #endif
897 #ifndef MAX
898 # define MAX(a, b)  (a) > (b) ? (a) : (b)
899 #endif
900 
901 bool w_getopt(struct watchman_getopt *opts, int *argcp, char ***argvp,
902     char ***daemon_argv);
903 void usage(struct watchman_getopt *opts, FILE *where);
904 void print_command_list_for_help(FILE *where);
905 
906 struct w_clockspec *w_clockspec_new_clock(uint32_t root_number, uint32_t ticks);
907 struct w_clockspec *w_clockspec_parse(json_t *value);
908 void w_clockspec_eval(w_root_t *root,
909     const struct w_clockspec *spec,
910     struct w_query_since *since);
911 void w_clockspec_free(struct w_clockspec *spec);
912 
913 const char *get_sock_name(void);
914 
915 // Helps write shorter lines
set_prop(json_t * obj,const char * key,json_t * val)916 static inline void set_prop(json_t *obj, const char *key, json_t *val)
917 {
918   json_object_set_new_nocheck(obj, key, val);
919 }
920 
921 void cfg_shutdown(void);
922 void cfg_set_arg(const char *name, json_t *val);
923 void cfg_load_global_config_file(void);
924 json_t *cfg_get_json(w_root_t *root, const char *name);
925 const char *cfg_get_string(w_root_t *root, const char *name,
926     const char *defval);
927 json_int_t cfg_get_int(w_root_t *root, const char *name,
928     json_int_t defval);
929 bool cfg_get_bool(w_root_t *root, const char *name, bool defval);
930 double cfg_get_double(w_root_t *root, const char *name, double defval);
931 const char *cfg_get_trouble_url(void);
932 json_t *cfg_compute_root_files(bool *enforcing);
933 
934 #include "watchman_query.h"
935 #include "watchman_cmd.h"
936 struct watchman_client_subscription {
937   w_root_t *root;
938   w_string_t *name;
939   w_query *query;
940   bool vcs_defer;
941   uint32_t last_sub_tick;
942   struct w_query_field_list field_list;
943   // map of statename => bool.  If true, policy is drop, else defer
944   w_ht_t *drop_or_defer;
945 };
946 
947 struct watchman_trigger_command {
948   w_string_t *triggername;
949   w_query *query;
950   json_t *definition;
951   json_t *command;
952   w_ht_t *envht;
953 
954   struct w_query_field_list field_list;
955   int append_files;
956   enum {
957     input_dev_null,
958     input_json,
959     input_name_list
960   } stdin_style;
961   uint32_t max_files_stdin;
962 
963   int stdout_flags;
964   int stderr_flags;
965   const char *stdout_name;
966   const char *stderr_name;
967 
968   /* While we are running, this holds the pid
969    * of the running process */
970   pid_t current_proc;
971 };
972 
973 void w_trigger_command_free(struct watchman_trigger_command *cmd);
974 void w_assess_trigger(w_root_t *root, struct watchman_trigger_command *cmd);
975 struct watchman_trigger_command *w_build_trigger_from_def(
976   w_root_t *root, json_t *trig, char **errmsg);
977 
978 void set_poison_state(w_root_t *root, w_string_t *dir,
979     struct timeval now, const char *syscall, int err,
980     const char *reason);
981 
982 void watchman_watcher_init(void);
983 void watchman_watcher_dtor(void);
984 void handle_open_errno(w_root_t *root, struct watchman_dir *dir,
985     struct timeval now, const char *syscall, int err,
986     const char *reason);
987 void stop_watching_dir(w_root_t *root, struct watchman_dir *dir);
988 uint32_t u32_strlen(const char *str);
989 int w_lstat(const char *path, struct stat *st, bool case_sensitive);
990 
991 extern struct watchman_ops fsevents_watcher;
992 extern struct watchman_ops kqueue_watcher;
993 extern struct watchman_ops inotify_watcher;
994 extern struct watchman_ops portfs_watcher;
995 extern struct watchman_ops win32_watcher;
996 
997 void w_ioprio_set_low(void);
998 void w_ioprio_set_normal(void);
999 
1000 struct flag_map {
1001   uint32_t value;
1002   const char *label;
1003 };
1004 void w_expand_flags(const struct flag_map *fmap, uint32_t flags,
1005     char *buf, size_t len);
1006 
1007 #ifdef __cplusplus
1008 }
1009 #endif
1010 
1011 #endif
1012 
1013 /* vim:ts=2:sw=2:et:
1014  */
1015