Skip to content

Commit bed16c4

Browse files
committed
Add '-w' option to tigger based on window is resize signals
Response is similar to <space> keyboard input, except it cannot not be combined with the '-r' flag.
1 parent 832e3e5 commit bed16c4

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

entr.1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1414
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1515
.\"
16-
.Dd February 6, 2025
16+
.Dd June 25, 2025
1717
.Dt ENTR 1
1818
.Os
1919
.Sh NAME
@@ -86,6 +86,10 @@ Control of the TTY is not transferred to the child process.
8686
Evaluate the first argument using the interpreter specified by the
8787
.Ev SHELL
8888
environment variable.
89+
.It Fl w
90+
Execute the
91+
.Ar utility
92+
if the terminal is resized.
8993
.It Fl x
9094
Format custom exit status messages using a persistent
9195
.Xr awk 1

entr.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ int oneshot_opt;
7171
int postpone_opt;
7272
int restart_opt;
7373
int shell_opt;
74+
int winch_opt;
7475
int status_filter_opt;
7576

7677
int termios_set;
@@ -84,6 +85,7 @@ static char *argv0, *argv0_base;
8485
static void usage();
8586
static void terminate_utility();
8687
static void handle_exit(int sig);
88+
static void handle_winch(int sig);
8789
static void proc_exit(int sig);
8890
static void print_child_status(int status);
8991
static int process_input(FILE *, WatchFile *[], int);
@@ -230,7 +232,7 @@ main(int argc, char *argv[]) {
230232
void
231233
usage() {
232234
fprintf(stderr, "release: %s\n", RELEASE);
233-
fprintf(stderr, "usage: entr [-acdnprsxz] utility [argument [/_] ...] < filenames\n");
235+
fprintf(stderr, "usage: entr [-acdnprswxz] utility [argument [/_] ...] < filenames\n");
234236
exit(1);
235237
}
236238

@@ -267,6 +269,11 @@ handle_exit(int sig) {
267269
raise(sig);
268270
}
269271

272+
void
273+
handle_winch(int sig) {
274+
return;
275+
}
276+
270277
void
271278
proc_exit(int sig) {
272279
int status;
@@ -411,7 +418,7 @@ set_options(char *argv[]) {
411418
/* read arguments until we reach a command */
412419
for (argc = 1; argv[argc] != 0 && argv[argc][0] == '-'; argc++)
413420
;
414-
while ((ch = getopt(argc, argv, "acdnprsxz")) != -1) {
421+
while ((ch = getopt(argc, argv, "acdnprswxz")) != -1) {
415422
switch (ch) {
416423
case 'a':
417424
aggressive_opt = 1;
@@ -434,6 +441,9 @@ set_options(char *argv[]) {
434441
case 's':
435442
shell_opt = 1;
436443
break;
444+
case 'w':
445+
winch_opt = 1;
446+
break;
437447
case 'x':
438448
status_filter_opt = status_filter_opt ? 2 : 1;
439449
break;
@@ -450,6 +460,9 @@ set_options(char *argv[]) {
450460
if (status_filter_opt && restart_opt)
451461
errx(1, "-r and -x may not be combined");
452462

463+
if (winch_opt && restart_opt)
464+
errx(1, "-r and -w may not be combined");
465+
453466
if ((shell_opt == 1) && (argv[optind + 1] != 0))
454467
errx(1, "-s requires commands to be formatted as a single argument");
455468
return optind;
@@ -624,6 +637,7 @@ watch_loop(int kq, char *argv[]) {
624637
int nev;
625638
WatchFile *file;
626639
int i;
640+
struct sigaction act;
627641
struct timespec evTimeout = { 0, 1000000 };
628642
int reopen_only = !aggressive_opt;
629643
int collate_only = 0;
@@ -634,7 +648,9 @@ watch_loop(int kq, char *argv[]) {
634648
char c;
635649
struct termios character_tty;
636650

651+
sigemptyset(&act.sa_mask);
637652
leading_edge = files[0]; /* default */
653+
638654
if (postpone_opt == 0)
639655
run_utility(argv);
640656

@@ -653,12 +669,26 @@ watch_loop(int kq, char *argv[]) {
653669
if ((reopen_only == 1) || (collate_only == 1)) {
654670
nev = kevent(kq, NULL, 0, evList, 32, &evTimeout);
655671
} else {
672+
/* interrupt kevent if terminal resized */
673+
if (winch_opt == 1) {
674+
act.sa_flags = SA_RESETHAND;
675+
act.sa_handler = handle_winch;
676+
if (sigaction(SIGWINCH, &act, NULL) != 0)
677+
err(1, "Failed to set SIGWINCH handler");
678+
}
679+
680+
/* wait for events */
656681
nev = kevent(kq, NULL, 0, evList, 32, NULL);
657682
dir_modified = 0;
658683
}
659684

660-
if ((nev == -1) && (errno != EINTR))
661-
warn("kevent failed");
685+
if (nev == -1) {
686+
if (errno == EINTR) {
687+
if (winch_opt == 1)
688+
do_exec = 1;
689+
} else
690+
warn("kevent");
691+
}
662692

663693
for (i = 0; i < nev; i++) {
664694
if (!noninteractive_opt && evList[i].filter == EVFILT_READ) {

system_test.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,18 @@ try "spacebar triggers utility"
178178
tmux send-keys -t $tsession:0 "q" ; zz
179179
tmux kill-session -t $tsession
180180

181+
# signal tests
182+
183+
try "exec utility when the terminal is resized"
184+
setup
185+
ls $tmp/file* | entr -pws 'printf ping' > $tmp/exec.out &
186+
bgpid=$! ; zz
187+
kill -WINCH $bgpid ; zz
188+
echo "123" > $tmp/file1 ; zz
189+
kill -INT $bgpid
190+
wait $bgpid; assert "$?" "0"
191+
assert "$(cat $tmp/exec.out)" "pingping"
192+
181193
# file system tests
182194

183195
try "exec a command using one-shot option"

0 commit comments

Comments
 (0)