New upstream release.
Debian Janitor
2 years ago
0 | 0 | PREFIX ?= /usr/local |
1 | 1 | MANPREFIX ?= ${PREFIX}/man |
2 | RELEASE = 4.8 | |
2 | RELEASE = 5.0 | |
3 | 3 | CPPFLAGS += -DRELEASE=\"${RELEASE}\" |
4 | 4 | |
5 | 5 | all: versioncheck entr |
16 | 16 | @./system_test.sh |
17 | 17 | |
18 | 18 | entr: entr.c ${EXTRA_SRC} |
19 | ${CC} ${CFLAGS} ${CPPFLAGS} ${EXTRA_SRC} entr.c -o $@ ${LDFLAGS} | |
19 | ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} ${EXTRA_SRC} entr.c -o $@ | |
20 | 20 | |
21 | 21 | entr_spec: entr_spec.c entr.c ${EXTRA_SRC} |
22 | ${CC} ${CFLAGS} ${CPPFLAGS} ${EXTRA_SRC} entr_spec.c -o $@ ${LDFLAGS} | |
22 | ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} ${EXTRA_SRC} entr_spec.c -o $@ | |
23 | 23 | |
24 | 24 | clean: |
25 | 25 | rm -f entr entr_spec *.o |
0 | 0 | = Release History |
1 | ||
2 | == 5.0: July 2, 2021 | |
3 | ||
4 | - Add missing call to getrlimit(3) on MacOS | |
5 | - Eliminate memory management warnings on Linux | |
6 | - EV_TRACE prints file mode and file name | |
7 | - Ignore asynchronous attribute changes on MacOS 11 | |
8 | ||
9 | == 4.9: May 3, 2021 | |
10 | ||
11 | - EV_TRACE also prints file/notify descriptor limit | |
12 | - Don't raise rlim_cur on MacOS | |
13 | - Set 2^16 watches if inotify limits cannot be read | |
14 | - Raise an error and suggest '-n' if terminal attributes cannot be read | |
1 | 15 | |
2 | 16 | == 4.8: February 26, 2021 |
3 | 17 | |
27 | 41 | |
28 | 42 | - Use a single inotify queue on Linux, limited by |
29 | 43 | /proc/sys/fs/inotify/max_user_watches |
30 | - Set the environment variable `ENTR_INOTIFY_WORKAROUND` to enable a | |
44 | - Set the environment variable 'ENTR_INOTIFY_WORKAROUND' to enable a | |
31 | 45 | compatibility mode for platforms with deformed inotify support |
32 | 46 | |
33 | 47 | == 4.3: September 25, 2019 |
108 | 122 | - Relocated 'reload-browser' to http://entrproject.org/scripts/reload-browser |
109 | 123 | - Drop FIFO support to further simply code and documentation. FIFO mode was |
110 | 124 | conceptually good, but EXEC mode is intelligent hand easily handles the vast |
111 | majority of use cases. | |
125 | majority of use cases | |
112 | 126 | - Remove kFreeBSD as a target platform |
113 | 127 | |
114 | 128 | == 3.1: March 4, 2015 |
131 | 145 | |
132 | 146 | == 2.9: June 10, 2014 |
133 | 147 | |
134 | - RPM package by @funollet | |
135 | 148 | - Moved alternate Makefiles to contrib/ |
136 | 149 | - Trigger actions when a file is truncated on BSD |
137 | 150 | - Improved format of DEBUG messages |
139 | 152 | - No longer register NOTE_EXTEND; this event is not always merged with |
140 | 153 | NOTE_WRITE on MacOS |
141 | 154 | - New directory-watch option ('-d'). In this mode a shell while-loop can be |
142 | used to track the addition of new files. | |
155 | used to track the addition of new files | |
143 | 156 | |
144 | 157 | |
145 | 158 | == 2.8: March 15, 2014 |
147 | 160 | - Iteratively check for new file system events using a 1ms timeout after a file |
148 | 161 | has been renamed or removed in order to prevent the utility from being |
149 | 162 | executed before successive changes from a version control system have |
150 | completed. | |
151 | - Regression tests are now system tests that depend on and use Vim and | |
152 | Mercurial | |
163 | completed | |
164 | - Regression tests use Vim and Mercurial | |
153 | 165 | - Timing on regression tests has been tightened to only support real hardware; |
154 | they are not expected to pass in emulated environments. | |
166 | they are not expected to pass in emulated environments | |
155 | 167 | - More correctly identify the first file to trigger a file change notification |
156 | - Regression tests no longer require ksh | |
157 | - Renamed regress.sh to system_test.sh | |
168 | - Renamed regress.sh to system_test.sh, and drop dependency on ksh | |
158 | 169 | |
159 | 170 | == 2.7: February 12, 2014 |
160 | 171 | |
161 | 172 | - Changed function pointer prefixes from '_' to 'x' to avoid runtime symbol |
162 | 173 | collisions in libc. Required to build on DragonFlyBSD |
163 | - Added this NEWS file to provide detailed release history for port maintainers | |
174 | - Add this NEWS file to provide detailed release history for port maintainers | |
164 | 175 | - Subsitute '/_' argument with the first file that changed |
165 | 176 | - Man page formatted with more semantically correct markup |
166 | 177 | - Multiple events on the same file are merged on Linux to prevent duplicate |
176 | 187 | - Raise ARG_MAX from 4K to 2MB on Linux, since _SC_ARG_MAX returns an incorrect |
177 | 188 | value on Linux |
178 | 189 | - Handle RENAME events that are not followed by DELETE. This enables us to cope |
179 | with the backup option in Vim. | |
190 | with the backup option in Vim | |
180 | 191 | |
181 | 192 | == 2.5: December 30, 2013 |
182 | 193 | |
183 | 194 | - Restore full 50ms period for consolidating events on Linux. Required for the |
184 | 195 | Geany editor |
185 | - Remove use of setproctitle(3), no plans to implement this on Linux and MacOS. | |
196 | - Remove use of setproctitle(3), no plans to implement this on Linux and MacOS | |
186 | 197 | This also eliminates use of the 3-clause license |
187 | 198 | - New feature: the first occurrence of '{}' on the command line will be |
188 | 199 | replaced with the name of the first file under watch |
215 | 226 | - Exit non-zero if list of regular files exceeds the hard limit set by the |
216 | 227 | current login class |
217 | 228 | - Ignore directories and special files; exit with error code 1 if no regular |
218 | files are provided as input. | |
229 | files are provided as input | |
219 | 230 | |
220 | 231 | == 2.1: July 01, 2013 |
221 | 232 | |
237 | 248 | |
238 | 249 | == 1.9: April 13, 2013 |
239 | 250 | |
240 | - New auto-reload option ('-r'). Thanks for Kevin Cox for the idea | |
251 | - New auto-reload option ('-r') | |
241 | 252 | - Add a simple configure script, BSD is the default |
242 | 253 | - Do not install directories...they should already exist |
243 | 254 | - Man page installation path can be set with MANPATH. MacOS expects it to be |
272 | 283 | |
273 | 284 | == 1.3: May 17, 2012 |
274 | 285 | |
275 | - Added FIFO support. Thanks to James K. Lowden for the idea | |
276 | - Use min(OPEN_MAX, rl.rlim_max) to be more compatible of Mac OS. | |
286 | - Added FIFO support | |
287 | - Use min(OPEN_MAX, rl.rlim_max) to be more compatible of Mac OS | |
277 | 288 | - More correct use of fgets(3) when reading STDIN |
278 | 289 | |
279 | 290 | == 1.2: April 26, 2012 |
35 | 35 | |
36 | 36 | Launch and auto-reload a node.js server: |
37 | 37 | |
38 | $ find . -name '*.js' | entr -r node app.js | |
38 | $ ls *.js | entr -r node app.js | |
39 | 39 | |
40 | 40 | Clear the screen and run a query after the SQL script is updated: |
41 | 41 | |
42 | $ echo my.sql | entr -p psql -f /_ | |
42 | $ echo my.sql | entr -cp psql -f /_ | |
43 | 43 | |
44 | 44 | Rebuild project if a source file is modified or added to the src/ directory: |
45 | 45 | |
46 | $ while sleep 0.1; do find src -name '*.rb' | entr -d make; done | |
46 | $ while sleep 0.1; do ls src/*.rb | entr -d make; done | |
47 | 47 | |
48 | Self-terminate after a file is updated | |
48 | Auto-reload a web server, or terminate if the server exits | |
49 | 49 | |
50 | $ find . -type f | entr -p 'kill $PPID' | |
50 | $ ls * | entr -rz ./httpd | |
51 | 51 | |
52 | 52 | News |
53 | 53 | ---- |
0 | entr (5.0-1) UNRELEASED; urgency=low | |
1 | ||
2 | * New upstream release. | |
3 | ||
4 | -- Debian Janitor <janitor@jelmer.uk> Mon, 09 Aug 2021 11:47:54 -0000 | |
5 | ||
0 | 6 | entr (4.8-1) unstable; urgency=medium |
1 | 7 | |
2 | 8 | [ Yuri D'Elia ] |
12 | 12 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
13 | 13 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
14 | 14 | .\" |
15 | .Dd February 18, 2021 | |
15 | .Dd July 2, 2021 | |
16 | 16 | .Dt ENTR 1 |
17 | 17 | .Os |
18 | 18 | .Sh NAME |
123 | 123 | .Aq Cm control-C . |
124 | 124 | .El |
125 | 125 | .Sh ENVIRONMENT |
126 | If | |
127 | .Ev PAGER | |
128 | is undefined, | |
129 | .Nm | |
130 | will assign | |
126 | .Bl -tag -width "ENTR_ENVIRON" | |
127 | .It Ev PAGER | |
128 | Set to | |
131 | 129 | .Pa /bin/cat |
130 | by default | |
132 | 131 | to prevent interactive utilities from waiting for keyboard input if output does |
133 | 132 | not fit on the screen. |
134 | .Pp | |
135 | If | |
136 | .Ev SHELL | |
137 | is undefined, | |
138 | .Nm entr | |
139 | will use | |
133 | .It Ev SHELL | |
134 | Specify the shell to use with the | |
135 | .Fl s | |
136 | flag. | |
137 | The default is | |
140 | 138 | .Pa /bin/sh . |
139 | .It Ev EV_TRACE | |
140 | Print file system event messages. | |
141 | .El | |
141 | 142 | .Sh EXIT STATUS |
142 | 143 | If the |
143 | 144 | .Fl z |
105 | 105 | int |
106 | 106 | main(int argc, char *argv[]) { |
107 | 107 | struct rlimit rl; |
108 | rlim_t max_watches; | |
109 | 108 | int kq; |
110 | 109 | struct sigaction act; |
111 | 110 | int ttyfd; |
113 | 112 | int n_files; |
114 | 113 | int i; |
115 | 114 | struct kevent evSet; |
116 | long open_max; | |
115 | unsigned open_max; | |
117 | 116 | |
118 | 117 | if ((*test_runner_main)) |
119 | 118 | return(test_runner_main(argc, argv)); |
158 | 157 | if (sigaction(SIGCHLD, &act, NULL) != 0) |
159 | 158 | err(1, "Failed to set SIGCHLD handler"); |
160 | 159 | |
161 | getrlimit(RLIMIT_NOFILE, &rl); | |
162 | ||
163 | 160 | #if defined(_LINUX_PORT) |
164 | max_watches = (rlim_t)fs_sysctl(INOTIFY_MAX_USER_WATCHES); | |
165 | if(max_watches > 0) { | |
166 | rl.rlim_cur = max_watches; | |
167 | open_max = max_watches; | |
168 | goto rlim_set; | |
169 | } | |
170 | #endif | |
171 | /* raise soft limit */ | |
172 | open_max = min(sysconf(_SC_OPEN_MAX), (long)rl.rlim_max); | |
173 | if (open_max == -1) | |
174 | err(1, "_SC_OPEN_MAX"); | |
175 | ||
176 | open_max = min(524288, open_max); /* guard against unrealistic replies */ | |
177 | ||
161 | /* attempt to read inotify limits */ | |
162 | open_max = (unsigned)fs_sysctl(INOTIFY_MAX_USER_WATCHES); | |
163 | if (open_max == 0) | |
164 | open_max = 65536; | |
165 | #elif defined(_MACOS_PORT) | |
166 | if (getrlimit(RLIMIT_NOFILE, &rl) == -1) | |
167 | err(1, "getrlimit"); | |
168 | /* guard against unrealistic replies */ | |
169 | open_max = min(65536, (unsigned)rl.rlim_cur); | |
170 | if (open_max == 0) | |
171 | open_max = 65536; | |
172 | #else /* BSD */ | |
173 | if (getrlimit(RLIMIT_NOFILE, &rl) == -1) | |
174 | err(1, "getrlimit"); | |
175 | open_max = (unsigned)rl.rlim_max; | |
178 | 176 | rl.rlim_cur = (rlim_t)open_max; |
179 | 177 | if (setrlimit(RLIMIT_NOFILE, &rl) != 0) |
180 | err(1, "setrlimit cannot set rlim_cur to %ld", open_max); | |
181 | ||
182 | rlim_set: | |
178 | err(1, "setrlimit cannot set rlim_cur to %u", open_max); | |
179 | #endif | |
180 | ||
181 | if (getenv("EV_TRACE")) | |
182 | fprintf(stderr, "open_max: %d\n", open_max); | |
183 | 183 | |
184 | 184 | /* prevent interactive utilities from paging output */ |
185 | 185 | setenv("PAGER", "/bin/cat", 0); |
203 | 203 | errx(1, "No regular files to watch"); |
204 | 204 | if (n_files == -1) |
205 | 205 | errx(1, "Too many files listed; the hard limit for your login" |
206 | " class is %ld. Please consult" | |
206 | " class is %u. Please consult" | |
207 | 207 | " http://eradman.com/entrproject/limits.html", open_max); |
208 | 208 | for (i=0; i<n_files; i++) |
209 | 209 | watch_file(kq, files[i]); |
218 | 218 | } |
219 | 219 | |
220 | 220 | /* remember terminal settings */ |
221 | tcgetattr(STDIN_FILENO, &canonical_tty); | |
221 | if (tcgetattr(STDIN_FILENO, &canonical_tty) == -1) | |
222 | errx(1, "unable to get terminal attributes, use '-n' to run non-interactively"); | |
222 | 223 | |
223 | 224 | /* Use keyboard input as a trigger */ |
224 | 225 | EV_SET(&evSet, STDIN_FILENO, EVFILT_READ, EV_ADD, NOTE_LOWAT, 1, NULL); |
260 | 261 | void |
261 | 262 | handle_exit(int sig) { |
262 | 263 | if (!noninteractive_opt) |
263 | xtcsetattr(0, TCSADRAIN, &canonical_tty); | |
264 | xtcsetattr(STDIN_FILENO, TCSADRAIN, &canonical_tty); | |
264 | 265 | terminate_utility(); |
265 | 266 | if ((sig == SIGINT || sig == SIGHUP)) |
266 | 267 | exit(0); |
416 | 417 | char **new_argv; |
417 | 418 | char *p, *arg_buf; |
418 | 419 | int argc; |
419 | int stdin_pipe[2]; | |
420 | int stdin_pipe[2] = {0, 0}; | |
420 | 421 | |
421 | 422 | if (restart_opt == 1) { |
422 | 423 | terminate_utility(); |
586 | 587 | struct stat sb; |
587 | 588 | char c; |
588 | 589 | struct termios character_tty; |
589 | char *trace_message; | |
590 | 590 | |
591 | 591 | leading_edge = files[0]; /* default */ |
592 | 592 | if (postpone_opt == 0) |
600 | 600 | |
601 | 601 | main: |
602 | 602 | if (!noninteractive_opt) |
603 | xtcsetattr(0, TCSADRAIN, &character_tty); | |
603 | xtcsetattr(STDIN_FILENO, TCSADRAIN, &character_tty); | |
604 | 604 | if ((reopen_only == 1) || (collate_only == 1)) { |
605 | 605 | nev = xkevent(kq, NULL, 0, evList, 32, &evTimeout); |
606 | 606 | } |
639 | 639 | dir_modified += compare_dir_contents(file); |
640 | 640 | } |
641 | 641 | if (!noninteractive_opt) |
642 | xtcsetattr(0, TCSADRAIN, &canonical_tty); | |
642 | xtcsetattr(STDIN_FILENO, TCSADRAIN, &canonical_tty); | |
643 | 643 | |
644 | 644 | collate_only = 0; |
645 | 645 | for (i=0; i<nev; i++) { |
667 | 667 | } |
668 | 668 | |
669 | 669 | for (i=0; i<nev && reopen_only == 0; i++) { |
670 | trace_message = ""; | |
671 | 670 | |
672 | 671 | if (evList[i].filter != EVFILT_VNODE) |
673 | 672 | continue; |
689 | 688 | if (file->mode != sb.st_mode) { |
690 | 689 | do_exec = 1; |
691 | 690 | file->mode = sb.st_mode; |
692 | trace_message = "mode changed"; | |
693 | 691 | } |
694 | 692 | /* Possible on Linux when a running binary is unlinked */ |
695 | 693 | if (file->ino != sb.st_ino) { |
696 | 694 | do_exec = 1; |
697 | 695 | file->ino = sb.st_ino; |
698 | trace_message = "inode changed"; | |
699 | 696 | } |
700 | 697 | } |
701 | 698 | else if (evList[i].fflags & NOTE_ATTRIB) |
702 | 699 | continue; |
703 | 700 | |
704 | if ((file->is_dir == 0) && (leading_edge_set == 0)) { | |
701 | if ((leading_edge_set == 0) && | |
702 | (file->is_dir == 0) && | |
703 | (do_exec == 1)) { | |
705 | 704 | leading_edge = file; |
706 | 705 | leading_edge_set = 1; |
707 | 706 | } |
708 | 707 | |
709 | 708 | if (getenv("EV_TRACE")) { |
710 | fprintf(stderr, "EVFILT_VNODE: %d/%d: " | |
711 | "fflags: 0x%x %s\n", i, nev, evList[i].fflags, | |
712 | trace_message); | |
709 | fprintf(stderr, "%d/%d: fflags: 0x%x %s %o %s\n", | |
710 | i, nev, | |
711 | evList[i].fflags, | |
712 | file->is_dir ? "d" : "r", | |
713 | file->mode, | |
714 | file->fn); | |
713 | 715 | } |
714 | 716 | } |
715 | 717 |
56 | 56 | fs_sysctl(const int name) { |
57 | 57 | FILE *file; |
58 | 58 | char line[8]; |
59 | int value; | |
59 | int value = 0; | |
60 | 60 | |
61 | 61 | switch(name) { |
62 | 62 | case INOTIFY_MAX_USER_WATCHES: |
113 | 113 | struct inotify_event *iev; |
114 | 114 | u_int fflags; |
115 | 115 | const struct kevent *kev; |
116 | int ignored; | |
117 | struct pollfd *pfd; | |
118 | 116 | int nfds; |
119 | 117 | |
120 | pfd = calloc(2, sizeof(struct pollfd)); | |
118 | int ignored = 0; | |
119 | struct pollfd pfd[2]; | |
120 | ||
121 | 121 | pfd[0].fd = kq; |
122 | 122 | pfd[0].events = POLLIN; |
123 | 123 | pfd[1].fd = STDIN_FILENO; |
124 | 124 | pfd[1].events = POLLIN; |
125 | 125 | |
126 | 126 | if (nchanges > 0) { |
127 | ignored = 0; | |
128 | 127 | for (n=0; n<nchanges; n++) { |
129 | 128 | kev = changelist + (sizeof(struct kevent)*n); |
130 | 129 | file = (WatchFile *)kev->udata; |
229 | 228 | } |
230 | 229 | while ((poll(pfd, nfds, 50) > 0)); |
231 | 230 | |
232 | free(pfd); | |
233 | 231 | return n; |
234 | 232 | } |
220 | 220 | fi |
221 | 221 | |
222 | 222 | try "exec single utility when an entire stash of files is reverted" |
223 | setup | |
224 | cp /usr/include/*.h $tmp/ | |
225 | cd $tmp | |
226 | git init -q | |
227 | git add *.h | |
228 | git commit -m "initial checkin" -q | |
229 | for f in `ls *.h | head`; do | |
230 | chmod 644 $f | |
231 | echo "" >> $f | |
232 | done | |
233 | cd - > /dev/null ; zz | |
234 | ls $tmp/*.h | ./entr -p echo "changed" > $tmp/exec.out & | |
235 | bgpid=$! ; zz | |
236 | cd $tmp | |
237 | git checkout *.h -q | |
238 | cd - > /dev/null ; zz | |
239 | kill -INT $bgpid | |
240 | wait $bgpid || assert "$?" "130" | |
241 | assert "$(cat $tmp/exec.out)" "changed" | |
223 | if [ ! -d /usr/include ]; then | |
224 | skip "Operating system does not include files in a standard location" | |
225 | else | |
226 | setup | |
227 | cp /usr/include/*.h $tmp/ | |
228 | cd $tmp | |
229 | git init -q | |
230 | git add *.h | |
231 | git commit -m "initial checkin" -q | |
232 | for f in `ls *.h | head`; do | |
233 | chmod 644 $f | |
234 | echo "" >> $f | |
235 | done | |
236 | cd - > /dev/null ; zz | |
237 | ls $tmp/*.h | ./entr -p echo "changed" > $tmp/exec.out & | |
238 | bgpid=$! ; zz | |
239 | cd $tmp | |
240 | git checkout *.h -q | |
241 | cd - > /dev/null ; zz | |
242 | kill -INT $bgpid | |
243 | wait $bgpid || assert "$?" "130" | |
244 | assert "$(cat $tmp/exec.out)" "changed" | |
245 | fi | |
242 | 246 | |
243 | 247 | try "exec utility when a file is written by Vim" |
244 | 248 | setup |