Coverage Report

Created: 2026-10-17 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tmux/control.c
Line
Count
Source
1
/* $OpenBSD: control.c,v 1.68 2026/09/09 08:30:05 nicm Exp $ */
2
3
/*
4
 * Copyright (c) 2012 Nicholas Marriott <nicholas.marriott@gmail.com>
5
 * Copyright (c) 2012 George Nachman <tmux@georgester.com>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
22
#include <errno.h>
23
#include <event.h>
24
#include <poll.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <time.h>
28
#include <unistd.h>
29
30
#include "tmux.h"
31
32
/*
33
 * Block of data to output. Each client has one "all" queue of blocks and
34
 * another queue for each pane (in struct client_offset). %output blocks are
35
 * added to both queues and other output lines (notifications) added only to
36
 * the client queue.
37
 *
38
 * When a client becomes writeable, data from blocks on the pane queue are sent
39
 * up to the maximum size (CLIENT_BUFFER_HIGH). If a block is entirely written,
40
 * it is removed from both pane and client queues and if this means non-%output
41
 * blocks are now at the head of the client queue, they are written.
42
 *
43
 * This means a %output block holds up any subsequent non-%output blocks until
44
 * it is written which enforces ordering even if the client cannot accept the
45
 * entire block in one go.
46
 */
47
struct control_block {
48
  size_t         size;
49
  char        *line;
50
  uint64_t       t;
51
52
  TAILQ_ENTRY(control_block)   entry;
53
  TAILQ_ENTRY(control_block)   all_entry;
54
};
55
56
/*
57
 * A notification line deferred because it was generated while a command's
58
 * %begin/%end guard block was open. Notifications must never appear inside a
59
 * guard block, so they are held here and flushed once the block closes.
60
 */
61
struct control_line {
62
  char        *line;
63
64
  TAILQ_ENTRY(control_line)  entry;
65
};
66
67
/* Control client pane. */
68
struct control_pane {
69
  u_int        pane;
70
71
  /*
72
   * Offsets into the pane data. The first (offset) is the data we have
73
   * written; the second (queued) the data we have queued (pointed to by
74
   * a block).
75
   */
76
  struct window_pane_offset  offset;
77
  struct window_pane_offset  queued;
78
79
  int        flags;
80
0
#define CONTROL_PANE_OFF 0x1
81
0
#define CONTROL_PANE_PAUSED 0x2
82
83
  int        pending_flag;
84
  TAILQ_ENTRY(control_pane)  pending_entry;
85
86
  TAILQ_HEAD(, control_block)  blocks;
87
88
  RB_ENTRY(control_pane)     entry;
89
};
90
RB_HEAD(control_panes, control_pane);
91
92
/* Control client window size. */
93
struct control_window {
94
  u_int        window;
95
  u_int        sx;
96
  u_int        sy;
97
98
  RB_ENTRY(control_window)   entry;
99
};
100
RB_HEAD(control_windows, control_window);
101
102
/* Control client state. */
103
struct control_state {
104
  struct control_panes     panes;
105
  struct control_windows     windows;
106
107
  TAILQ_HEAD(, control_pane)   pending_list;
108
  u_int        pending_count;
109
110
  TAILQ_HEAD(, control_block)  all_blocks;
111
  size_t         queued_reply_bytes;
112
113
  struct bufferevent    *read_event;
114
  struct bufferevent    *write_event;
115
116
  struct monitor_set    *subs;
117
118
  /*
119
   * Depth of open %begin/%end guard blocks and notifications deferred
120
   * until the outermost block closes.
121
   */
122
  int        guard_depth;
123
  TAILQ_HEAD(, control_line)   deferred;
124
};
125
126
/* Low and high watermarks. */
127
0
#define CONTROL_BUFFER_LOW 512
128
0
#define CONTROL_BUFFER_HIGH 8192
129
130
/* Minimum to write to each client. */
131
0
#define CONTROL_WRITE_MINIMUM 32
132
133
/* Maximum age for clients that are not using pause mode. */
134
0
#define CONTROL_MAXIMUM_AGE 300000
135
136
/* Maximum buffered command replies for a client that is not reading. */
137
0
#define CONTROL_MAXIMUM_REPLY_BUFFER (64 * 1024 * 1024)
138
139
/* Flags to ignore client. */
140
#define CONTROL_IGNORE_FLAGS \
141
0
  (CLIENT_CONTROL_NOOUTPUT| \
142
0
   CLIENT_UNATTACHEDFLAGS)
143
144
/* Compare client panes. */
145
static int
146
control_pane_cmp(struct control_pane *cp1, struct control_pane *cp2)
147
0
{
148
0
  if (cp1->pane < cp2->pane)
149
0
    return (-1);
150
0
  if (cp1->pane > cp2->pane)
151
0
    return (1);
152
0
  return (0);
153
0
}
154
0
RB_GENERATE_STATIC(control_panes, control_pane, entry, control_pane_cmp);
Unexecuted instantiation: control.c:control_panes_RB_MINMAX
Unexecuted instantiation: control.c:control_panes_RB_REMOVE
Unexecuted instantiation: control.c:control_panes_RB_REMOVE_COLOR
Unexecuted instantiation: control.c:control_panes_RB_FIND
Unexecuted instantiation: control.c:control_panes_RB_INSERT
155
0
156
0
/* Compare control windows. */
157
0
static int
158
0
control_window_cmp(struct control_window *cw1, struct control_window *cw2)
159
0
{
160
0
  if (cw1->window < cw2->window)
161
0
    return (-1);
162
0
  if (cw1->window > cw2->window)
163
0
    return (1);
164
0
  return (0);
165
0
}
166
0
RB_GENERATE_STATIC(control_windows, control_window, entry, control_window_cmp);
Unexecuted instantiation: control.c:control_windows_RB_FIND
Unexecuted instantiation: control.c:control_windows_RB_INSERT
Unexecuted instantiation: control.c:control_windows_RB_REMOVE
Unexecuted instantiation: control.c:control_windows_RB_REMOVE_COLOR
Unexecuted instantiation: control.c:control_windows_RB_MINMAX
167
0
168
0
/* Free a block. */
169
0
static void
170
0
control_free_block(struct control_state *cs, struct control_block *cb)
171
0
{
172
0
  size_t   size;
173
174
0
  if (cb->size == 0 && cb->line != NULL) {
175
0
    size = strlen(cb->line) + 1;
176
0
    if (cs->queued_reply_bytes > size)
177
0
      cs->queued_reply_bytes -= size;
178
0
    else
179
0
      cs->queued_reply_bytes = 0;
180
0
  }
181
0
  free(cb->line);
182
0
  TAILQ_REMOVE(&cs->all_blocks, cb, all_entry);
183
0
  free(cb);
184
0
}
185
186
/* Get pane offsets for this client. */
187
static struct control_pane *
188
control_get_pane(struct client *c, struct window_pane *wp)
189
0
{
190
0
  struct control_state  *cs = c->control_state;
191
0
  struct control_pane  cp = { .pane = wp->id };
192
193
0
  return (RB_FIND(control_panes, &cs->panes, &cp));
194
0
}
195
196
/* Add pane offsets for this client. */
197
static struct control_pane *
198
control_add_pane(struct client *c, struct window_pane *wp)
199
0
{
200
0
  struct control_state  *cs = c->control_state;
201
0
  struct control_pane *cp;
202
203
0
  cp = control_get_pane(c, wp);
204
0
  if (cp != NULL)
205
0
    return (cp);
206
207
0
  cp = xcalloc(1, sizeof *cp);
208
0
  cp->pane = wp->id;
209
0
  RB_INSERT(control_panes, &cs->panes, cp);
210
211
0
  memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
212
0
  memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
213
0
  TAILQ_INIT(&cp->blocks);
214
215
0
  return (cp);
216
0
}
217
218
/* Get window for this client. */
219
static struct control_window *
220
control_get_window(struct client *c, u_int window)
221
0
{
222
0
  struct control_state  *cs = c->control_state;
223
0
  struct control_window  cw = { .window = window };
224
225
0
  if (cs == NULL)
226
0
    return (NULL);
227
0
  return (RB_FIND(control_windows, &cs->windows, &cw));
228
0
}
229
230
/* Set window size for this client. */
231
void
232
control_set_window_size(struct client *c, u_int window, u_int sx, u_int sy)
233
0
{
234
0
  struct control_state  *cs = c->control_state;
235
0
  struct control_window *cw;
236
237
0
  if (cs == NULL)
238
0
    return;
239
0
  cw = control_get_window(c, window);
240
0
  if (cw == NULL) {
241
0
    cw = xcalloc(1, sizeof *cw);
242
0
    cw->window = window;
243
0
    RB_INSERT(control_windows, &cs->windows, cw);
244
0
  }
245
0
  cw->sx = sx;
246
0
  cw->sy = sy;
247
0
}
248
249
/* Get window size for this client. */
250
int
251
control_get_window_size(struct client *c, u_int window, u_int *sx, u_int *sy)
252
0
{
253
0
  struct control_window *cw;
254
255
0
  if ((cw = control_get_window(c, window)) == NULL)
256
0
    return (0);
257
0
  *sx = cw->sx;
258
0
  *sy = cw->sy;
259
0
  return (1);
260
0
}
261
262
/* Clear window size for this client. */
263
void
264
control_clear_window_size(struct client *c, u_int window)
265
0
{
266
0
  struct control_state  *cs = c->control_state;
267
0
  struct control_window *cw;
268
269
0
  if (cs == NULL)
270
0
    return;
271
0
  cw = control_get_window(c, window);
272
0
  if (cw != NULL) {
273
0
    RB_REMOVE(control_windows, &cs->windows, cw);
274
0
    free(cw);
275
0
  }
276
0
}
277
278
/* Discard output for a pane. */
279
static void
280
control_discard_pane(struct client *c, struct control_pane *cp)
281
0
{
282
0
  struct control_state  *cs = c->control_state;
283
0
  struct control_block  *cb, *cb1;
284
285
0
  TAILQ_FOREACH_SAFE(cb, &cp->blocks, entry, cb1) {
286
0
    TAILQ_REMOVE(&cp->blocks, cb, entry);
287
0
    control_free_block(cs, cb);
288
0
  }
289
0
}
290
291
/* Get actual pane for this client. */
292
static struct window_pane *
293
control_window_pane(struct client *c, u_int pane)
294
0
{
295
0
  struct window_pane  *wp;
296
297
0
  if (c->session == NULL)
298
0
    return (NULL);
299
0
  if ((wp = window_pane_find_by_id(pane)) == NULL)
300
0
    return (NULL);
301
0
  if (winlink_find_by_window(&c->session->windows, wp->window) == NULL)
302
0
    return (NULL);
303
0
  return (wp);
304
0
}
305
306
/* Reset control offsets. */
307
void
308
control_reset_offsets(struct client *c)
309
0
{
310
0
  struct control_state  *cs = c->control_state;
311
0
  struct control_pane *cp, *cp1;
312
313
0
  RB_FOREACH_SAFE(cp, control_panes, &cs->panes, cp1) {
314
0
    control_discard_pane(c, cp);
315
0
    RB_REMOVE(control_panes, &cs->panes, cp);
316
0
    free(cp);
317
0
  }
318
319
0
  TAILQ_INIT(&cs->pending_list);
320
0
  cs->pending_count = 0;
321
0
}
322
323
/* Get offsets for client. */
324
struct window_pane_offset *
325
control_pane_offset(struct client *c, struct window_pane *wp, int *off)
326
0
{
327
0
  struct control_state  *cs = c->control_state;
328
0
  struct control_pane *cp;
329
330
0
  if (c->flags & CLIENT_CONTROL_NOOUTPUT) {
331
0
    *off = 0;
332
0
    return (NULL);
333
0
  }
334
335
0
  cp = control_get_pane(c, wp);
336
0
  if (cp == NULL || (cp->flags & CONTROL_PANE_PAUSED)) {
337
0
    *off = 0;
338
0
    return (NULL);
339
0
  }
340
0
  if (cp->flags & CONTROL_PANE_OFF) {
341
0
    *off = 1;
342
0
    return (NULL);
343
0
  }
344
0
  *off = (EVBUFFER_LENGTH(cs->write_event->output) >= CONTROL_BUFFER_LOW);
345
0
  return (&cp->offset);
346
0
}
347
348
/* Set pane as on. */
349
void
350
control_set_pane_on(struct client *c, struct window_pane *wp)
351
0
{
352
0
  struct control_pane *cp;
353
354
0
  cp = control_get_pane(c, wp);
355
0
  if (cp != NULL && (cp->flags & CONTROL_PANE_OFF)) {
356
0
    cp->flags &= ~CONTROL_PANE_OFF;
357
0
    memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
358
0
    memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
359
0
  }
360
0
}
361
362
/* Set pane as off. */
363
void
364
control_set_pane_off(struct client *c, struct window_pane *wp)
365
0
{
366
0
  struct control_pane *cp;
367
368
0
  cp = control_add_pane(c, wp);
369
0
  control_discard_pane(c, cp);
370
0
  memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
371
0
  memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
372
0
  cp->flags |= CONTROL_PANE_OFF;
373
0
}
374
375
/* Continue a paused pane. */
376
void
377
control_continue_pane(struct client *c, struct window_pane *wp)
378
0
{
379
0
  struct control_pane *cp;
380
381
0
  cp = control_get_pane(c, wp);
382
0
  if (cp != NULL && (cp->flags & CONTROL_PANE_PAUSED)) {
383
0
    cp->flags &= ~CONTROL_PANE_PAUSED;
384
0
    memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
385
0
    memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
386
0
    control_notify_write(c, "%%continue %%%u", wp->id);
387
0
  }
388
0
}
389
390
/* Pause a pane. */
391
void
392
control_pause_pane(struct client *c, struct window_pane *wp)
393
0
{
394
0
  struct control_pane *cp;
395
396
0
  cp = control_add_pane(c, wp);
397
0
  if (~cp->flags & CONTROL_PANE_PAUSED) {
398
0
    cp->flags |= CONTROL_PANE_PAUSED;
399
0
    control_discard_pane(c, cp);
400
0
    control_notify_write(c, "%%pause %%%u", wp->id);
401
0
  }
402
0
}
403
404
/*
405
 * Reset a pane after its buffer has been replaced: drop any output still
406
 * queued from the old buffer and start again from the pane's own offset.
407
 */
408
void
409
control_reset_pane(struct client *c, struct window_pane *wp)
410
0
{
411
0
  struct control_pane *cp;
412
413
0
  if (c->control_state == NULL)
414
0
    return;
415
0
  cp = control_get_pane(c, wp);
416
0
  if (cp == NULL)
417
0
    return;
418
0
  control_discard_pane(c, cp);
419
0
  memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
420
0
  memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
421
0
}
422
423
/*
424
 * Check if the replies buffered for a client, including one about to be
425
 * added, have grown too large and kill it if so. Returns 1 if further output
426
 * for the client should be dropped.
427
 */
428
static int
429
control_check_reply_buffer(struct client *c, size_t added)
430
0
{
431
0
  struct control_state  *cs = c->control_state;
432
0
  size_t       size;
433
434
0
  if (c->flags & CLIENT_CONTROL_DISCARD)
435
0
    return (1);
436
0
  size = EVBUFFER_LENGTH(cs->write_event->output);
437
0
  size += cs->queued_reply_bytes;
438
0
  size += added;
439
0
  if (size < CONTROL_MAXIMUM_REPLY_BUFFER)
440
0
    return (0);
441
442
0
  log_debug("%s: %s: %zu bytes of replies buffered", __func__, c->name,
443
0
      size);
444
0
  if (~c->flags & CLIENT_EXIT) {
445
0
    c->exit_message = xstrdup("too far behind");
446
0
    c->flags |= CLIENT_EXIT;
447
0
    control_discard(c);
448
0
  }
449
0
  c->flags |= CLIENT_CONTROL_DISCARD;
450
0
  return (1);
451
0
}
452
453
/* Write an already-formatted line, queueing it behind %output if needed. */
454
static void
455
control_write_line(struct client *c, char *line)
456
0
{
457
0
  struct control_state  *cs = c->control_state;
458
0
  struct control_block  *cb;
459
0
  size_t       size = strlen(line) + 1;
460
461
0
  if (control_check_reply_buffer(c, size)) {
462
0
    free(line);
463
0
    return;
464
0
  }
465
466
0
  if (TAILQ_EMPTY(&cs->all_blocks)) {
467
0
    log_debug("%s: %s: writing line: %s", __func__, c->name, line);
468
0
    bufferevent_write(cs->write_event, line, size - 1);
469
0
    bufferevent_write(cs->write_event, "\n", 1);
470
0
    bufferevent_enable(cs->write_event, EV_WRITE);
471
0
    free(line);
472
0
    return;
473
0
  }
474
475
0
  cb = xcalloc(1, sizeof *cb);
476
0
  cb->line = line;
477
0
  TAILQ_INSERT_TAIL(&cs->all_blocks, cb, all_entry);
478
0
  cs->queued_reply_bytes += size;
479
0
  cb->t = get_timer();
480
481
0
  log_debug("%s: %s: storing line: %s", __func__, c->name, cb->line);
482
0
  bufferevent_enable(cs->write_event, EV_WRITE);
483
0
}
484
485
/* Flush notifications that were deferred while a guard block was open. */
486
static void
487
control_flush_deferred(struct client *c)
488
0
{
489
0
  struct control_state  *cs = c->control_state;
490
0
  struct control_line *cl, *cl1;
491
492
0
  TAILQ_FOREACH_SAFE(cl, &cs->deferred, entry, cl1) {
493
0
    TAILQ_REMOVE(&cs->deferred, cl, entry);
494
0
    control_write_line(c, cl->line);
495
0
    free(cl);
496
0
  }
497
0
}
498
499
/*
500
 * Write a line of command output or error text. This is a sink for arbitrary
501
 * user-controlled text (command output, capture-pane, error messages), so it
502
 * must never try to interpret the content: guard tracking is done only in
503
 * control_write_guard.
504
 */
505
void
506
control_write(struct client *c, const char *fmt, ...)
507
0
{
508
0
  struct control_state  *cs = c->control_state;
509
0
  char      *line;
510
0
  va_list      ap;
511
512
0
  if (cs == NULL)
513
0
    return;
514
515
0
  va_start(ap, fmt);
516
0
  xvasprintf(&line, fmt, ap);
517
0
  va_end(ap);
518
519
0
  control_write_line(c, line);
520
0
}
521
522
/*
523
 * Write a %begin, %end or %error guard around a command's output. This is the
524
 * only place guard lines are produced, so the block depth is maintained here;
525
 * when the outermost block closes any deferred notifications are flushed after
526
 * it. "guard" is always one of the fixed strings from cmdq_guard, never user
527
 * text.
528
 */
529
void
530
control_write_guard(struct client *c, const char *guard, long t, u_int number,
531
    int flags)
532
0
{
533
0
  struct control_state  *cs = c->control_state;
534
0
  char      *line;
535
536
0
  if (cs == NULL)
537
0
    return;
538
539
0
  if (strcmp(guard, "begin") == 0)
540
0
    cs->guard_depth++;
541
542
0
  xasprintf(&line, "%%%s %ld %u %d", guard, t, number, flags);
543
0
  control_write_line(c, line);
544
545
0
  if (strcmp(guard, "begin") != 0 && cs->guard_depth > 0 &&
546
0
      --cs->guard_depth == 0)
547
0
    control_flush_deferred(c);
548
0
}
549
550
/*
551
 * Write a notification line. Notifications must never appear inside a command's
552
 * %begin/%end guard block, so if one is open the line is deferred until it
553
 * closes.
554
 */
555
void
556
control_notify_write(struct client *c, const char *fmt, ...)
557
0
{
558
0
  struct control_state  *cs = c->control_state;
559
0
  struct control_line *cl;
560
0
  va_list      ap;
561
0
  char      *line;
562
563
0
  if (cs == NULL)
564
0
    return;
565
566
0
  va_start(ap, fmt);
567
0
  xvasprintf(&line, fmt, ap);
568
0
  va_end(ap);
569
570
0
  if (cs->guard_depth == 0) {
571
0
    control_write_line(c, line);
572
0
    return;
573
0
  }
574
575
0
  log_debug("%s: %s: deferring notification: %s", __func__, c->name,
576
0
      line);
577
0
  cl = xcalloc(1, sizeof *cl);
578
0
  cl->line = line;
579
0
  TAILQ_INSERT_TAIL(&cs->deferred, cl, entry);
580
0
}
581
582
/* Check age for this pane. */
583
static int
584
control_check_age(struct client *c, struct window_pane *wp,
585
    struct control_pane *cp)
586
0
{
587
0
  struct control_block  *cb;
588
0
  uint64_t     t, age;
589
590
0
  cb = TAILQ_FIRST(&cp->blocks);
591
0
  if (cb == NULL)
592
0
    return (0);
593
0
  t = get_timer();
594
0
  if (cb->t >= t)
595
0
    return (0);
596
597
0
  age = t - cb->t;
598
0
  log_debug("%s: %s: %%%u is %llu behind", __func__, c->name, wp->id,
599
0
      (unsigned long long)age);
600
601
0
  if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
602
0
    if (age < c->pause_age)
603
0
      return (0);
604
0
    cp->flags |= CONTROL_PANE_PAUSED;
605
0
    control_discard_pane(c, cp);
606
0
    control_notify_write(c, "%%pause %%%u", wp->id);
607
0
  } else {
608
0
    if (age < CONTROL_MAXIMUM_AGE)
609
0
      return (0);
610
0
    c->exit_message = xstrdup("too far behind");
611
0
    c->flags |= CLIENT_EXIT;
612
0
    control_discard(c);
613
0
  }
614
0
  return (1);
615
0
}
616
617
/* Write output from a pane. */
618
void
619
control_write_output(struct client *c, struct window_pane *wp)
620
0
{
621
0
  struct control_state  *cs = c->control_state;
622
0
  struct control_pane *cp;
623
0
  struct control_block  *cb;
624
0
  size_t       new_size;
625
626
0
  if (winlink_find_by_window(&c->session->windows, wp->window) == NULL)
627
0
    return;
628
629
0
  if (c->flags & (CONTROL_IGNORE_FLAGS|CLIENT_EXIT)) {
630
0
    cp = control_get_pane(c, wp);
631
0
    if (cp != NULL)
632
0
      goto ignore;
633
0
    return;
634
0
  }
635
0
  cp = control_add_pane(c, wp);
636
0
  if (cp->flags & (CONTROL_PANE_OFF|CONTROL_PANE_PAUSED))
637
0
    goto ignore;
638
0
  if (control_check_age(c, wp, cp))
639
0
    return;
640
641
0
  window_pane_get_new_data(wp, &cp->queued, &new_size);
642
0
  if (new_size == 0)
643
0
    return;
644
0
  window_pane_update_used_data(wp, &cp->queued, new_size);
645
646
0
  cb = xcalloc(1, sizeof *cb);
647
0
  cb->size = new_size;
648
0
  TAILQ_INSERT_TAIL(&cs->all_blocks, cb, all_entry);
649
0
  cb->t = get_timer();
650
651
0
  TAILQ_INSERT_TAIL(&cp->blocks, cb, entry);
652
0
  log_debug("%s: %s: new output block of %zu for %%%u", __func__, c->name,
653
0
      cb->size, wp->id);
654
655
0
  if (!cp->pending_flag) {
656
0
    log_debug("%s: %s: %%%u now pending", __func__, c->name,
657
0
        wp->id);
658
0
    TAILQ_INSERT_TAIL(&cs->pending_list, cp, pending_entry);
659
0
    cp->pending_flag = 1;
660
0
    cs->pending_count++;
661
0
  }
662
0
  bufferevent_enable(cs->write_event, EV_WRITE);
663
0
  return;
664
665
0
ignore:
666
0
  log_debug("%s: %s: ignoring pane %%%u", __func__, c->name, wp->id);
667
0
  window_pane_update_used_data(wp, &cp->offset, SIZE_MAX);
668
0
  window_pane_update_used_data(wp, &cp->queued, SIZE_MAX);
669
0
}
670
671
/* Control client error callback. */
672
static enum cmd_retval
673
control_error(struct cmdq_item *item, void *data)
674
0
{
675
0
  struct client *c = cmdq_get_client(item);
676
0
  char    *error = data;
677
678
0
  cmdq_guard(item, "begin", 1);
679
0
  control_write(c, "parse error: %s", error);
680
0
  cmdq_guard(item, "error", 1);
681
682
0
  free(error);
683
0
  return (CMD_RETURN_NORMAL);
684
0
}
685
686
/* Control client error callback. */
687
static void
688
control_error_callback(__unused struct bufferevent *bufev,
689
    __unused short what, void *data)
690
0
{
691
0
  struct client *c = data;
692
693
0
  c->flags |= CLIENT_EXIT;
694
0
}
695
696
/* Control client input callback. Read lines and fire commands. */
697
static void
698
control_read_callback(__unused struct bufferevent *bufev, void *data)
699
0
{
700
0
  struct client   *c = data;
701
0
  struct control_state  *cs = c->control_state;
702
0
  struct evbuffer   *buffer = cs->read_event->input;
703
0
  char      *line, *error;
704
0
  struct cmdq_state *state;
705
0
  enum cmd_parse_status  status;
706
707
0
  for (;;) {
708
0
    line = evbuffer_readln(buffer, NULL, EVBUFFER_EOL_LF);
709
0
    if (line == NULL)
710
0
      break;
711
0
    log_debug("%s: %s: %s", __func__, c->name, line);
712
0
    if (*line == '\0') { /* empty line detach */
713
0
      free(line);
714
0
      c->flags |= CLIENT_EXIT;
715
0
      break;
716
0
    }
717
718
0
    state = cmdq_new_state(NULL, NULL, CMDQ_STATE_CONTROL);
719
0
    status = cmd_parse_and_append(line, NULL, c, state, &error);
720
0
    if (status == CMD_PARSE_ERROR)
721
0
      cmdq_append(c, cmdq_get_callback(control_error, error));
722
0
    cmdq_free_state(state);
723
724
0
    free(line);
725
0
  }
726
0
}
727
728
/* Does this control client have outstanding data to write? */
729
int
730
control_all_done(struct client *c)
731
0
{
732
0
  struct control_state  *cs = c->control_state;
733
734
0
  if (!TAILQ_EMPTY(&cs->all_blocks))
735
0
    return (0);
736
0
  return (EVBUFFER_LENGTH(cs->write_event->output) == 0);
737
0
}
738
739
/*
740
 * Wait for the terminal to send an empty line or close, used by a control
741
 * client after printing %exit so a wrapping terminal (such as iTerm2) can
742
 * finish reading.
743
 */
744
void
745
control_wait_exit(int fd)
746
0
{
747
0
  struct pollfd  pfd;
748
0
  struct evbuffer *evb;
749
0
  char    *line;
750
0
  int    n;
751
752
0
  evb = evbuffer_new();
753
0
  if (evb == NULL)
754
0
    fatalx("out of memory");
755
756
0
  for (;;) {
757
0
    line = evbuffer_readln(evb, NULL, EVBUFFER_EOL_LF);
758
0
    if (line != NULL) {
759
0
      if (*line == '\0') { /* empty line, stop */
760
0
        free(line);
761
0
        break;
762
0
      }
763
0
      free(line);
764
0
      continue; /* drain buffered lines first */
765
0
    }
766
767
0
    memset(&pfd, 0, sizeof pfd);
768
0
    pfd.fd = fd;
769
0
    pfd.events = POLLIN;
770
0
    if (poll(&pfd, 1, INFTIM) == -1) {
771
0
      if (errno == EINTR)
772
0
        continue;
773
0
      break;
774
0
    }
775
776
0
    n = evbuffer_read(evb, fd, -1);
777
0
    if (n == 0)
778
0
      break;
779
0
    if (n == -1 && errno != EAGAIN && errno != EINTR)
780
0
      break;
781
0
  }
782
783
0
  evbuffer_free(evb);
784
0
}
785
786
/* Flush all blocks until output. */
787
static void
788
control_flush_all_blocks(struct client *c)
789
0
{
790
0
  struct control_state  *cs = c->control_state;
791
0
  struct control_block  *cb, *cb1;
792
793
0
  TAILQ_FOREACH_SAFE(cb, &cs->all_blocks, all_entry, cb1) {
794
0
    if (cb->size != 0)
795
0
      break;
796
0
    log_debug("%s: %s: flushing line: %s", __func__, c->name,
797
0
        cb->line);
798
799
0
    bufferevent_write(cs->write_event, cb->line, strlen(cb->line));
800
0
    bufferevent_write(cs->write_event, "\n", 1);
801
0
    control_free_block(cs, cb);
802
0
  }
803
0
}
804
805
/* Append data to buffer. */
806
static struct evbuffer *
807
control_append_data(struct client *c, struct control_pane *cp, uint64_t age,
808
    struct evbuffer *message, struct window_pane *wp, size_t size)
809
0
{
810
0
  u_char  *new_data;
811
0
  size_t   new_size, start;
812
0
  u_int  i;
813
814
0
  if (message == NULL) {
815
0
    message = evbuffer_new();
816
0
    if (message == NULL)
817
0
      fatalx("out of memory");
818
0
    if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
819
0
      evbuffer_add_printf(message,
820
0
          "%%extended-output %%%u %llu : ", wp->id,
821
0
          (unsigned long long)age);
822
0
    } else
823
0
      evbuffer_add_printf(message, "%%output %%%u ", wp->id);
824
0
  }
825
826
0
  new_data = window_pane_get_new_data(wp, &cp->offset, &new_size);
827
0
  if (new_size < size)
828
0
    fatalx("not enough data: %zu < %zu", new_size, size);
829
0
  for (i = 0; i < size; i++) {
830
0
    if (new_data[i] < ' ' || new_data[i] == '\\') {
831
0
      evbuffer_add_printf(message, "\\%03o", new_data[i]);
832
0
    } else {
833
0
      start = i;
834
0
      while (i + 1 < size &&
835
0
          new_data[i + 1] >= ' ' &&
836
0
          new_data[i + 1] != '\\')
837
0
        i++;
838
0
      evbuffer_add(message, new_data + start, i - start + 1);
839
0
    }
840
0
  }
841
0
  window_pane_update_used_data(wp, &cp->offset, size);
842
0
  return (message);
843
0
}
844
845
/* Write buffer. */
846
static void
847
control_write_data(struct client *c, struct evbuffer *message)
848
0
{
849
0
  struct control_state  *cs = c->control_state;
850
851
0
  log_debug("%s: %s: %.*s", __func__, c->name,
852
0
      (int)EVBUFFER_LENGTH(message), EVBUFFER_DATA(message));
853
854
0
  evbuffer_add(message, "\n", 1);
855
0
  bufferevent_write_buffer(cs->write_event, message);
856
0
  evbuffer_free(message);
857
0
}
858
859
/* Write output to client. */
860
static int
861
control_write_pending(struct client *c, struct control_pane *cp, size_t limit)
862
0
{
863
0
  struct control_state  *cs = c->control_state;
864
0
  struct window_pane  *wp = NULL;
865
0
  struct evbuffer   *message = NULL;
866
0
  size_t       used = 0, size;
867
0
  struct control_block  *cb, *cb1;
868
0
  uint64_t     age, t = get_timer();
869
870
0
  wp = control_window_pane(c, cp->pane);
871
0
  if (wp == NULL || wp->fd == -1) {
872
0
    TAILQ_FOREACH_SAFE(cb, &cp->blocks, entry, cb1) {
873
0
      TAILQ_REMOVE(&cp->blocks, cb, entry);
874
0
      control_free_block(cs, cb);
875
0
    }
876
0
    control_flush_all_blocks(c);
877
0
    return (0);
878
0
  }
879
880
0
  while (used != limit && !TAILQ_EMPTY(&cp->blocks)) {
881
0
    if (control_check_age(c, wp, cp)) {
882
0
      if (message != NULL)
883
0
        evbuffer_free(message);
884
0
      message = NULL;
885
0
      break;
886
0
    }
887
888
0
    cb = TAILQ_FIRST(&cp->blocks);
889
0
    if (cb->t < t)
890
0
      age = t - cb->t;
891
0
    else
892
0
      age = 0;
893
0
    log_debug("%s: %s: output block %zu (age %llu) for %%%u "
894
0
        "(used %zu/%zu)", __func__, c->name, cb->size,
895
0
        (unsigned long long)age, cp->pane, used, limit);
896
897
0
    size = cb->size;
898
0
    if (size > limit - used)
899
0
      size = limit - used;
900
0
    used += size;
901
902
0
    message = control_append_data(c, cp, age, message, wp, size);
903
904
0
    cb->size -= size;
905
0
    if (cb->size == 0) {
906
0
      TAILQ_REMOVE(&cp->blocks, cb, entry);
907
0
      control_free_block(cs, cb);
908
909
0
      cb = TAILQ_FIRST(&cs->all_blocks);
910
0
      if (cb != NULL && cb->size == 0) {
911
0
        if (wp != NULL && message != NULL) {
912
0
          control_write_data(c, message);
913
0
          message = NULL;
914
0
        }
915
0
        control_flush_all_blocks(c);
916
0
      }
917
0
    }
918
0
  }
919
0
  if (message != NULL)
920
0
    control_write_data(c, message);
921
0
  return (!TAILQ_EMPTY(&cp->blocks));
922
0
}
923
924
/* Control client write callback. */
925
static void
926
control_write_callback(__unused struct bufferevent *bufev, void *data)
927
0
{
928
0
  struct client   *c = data;
929
0
  struct control_state  *cs = c->control_state;
930
0
  struct control_pane *cp, *cp1;
931
0
  struct evbuffer   *evb = cs->write_event->output;
932
0
  size_t       space, limit;
933
934
0
  control_flush_all_blocks(c);
935
936
0
  while (EVBUFFER_LENGTH(evb) < CONTROL_BUFFER_HIGH) {
937
0
    if (cs->pending_count == 0)
938
0
      break;
939
0
    space = CONTROL_BUFFER_HIGH - EVBUFFER_LENGTH(evb);
940
0
    log_debug("%s: %s: %zu bytes available, %u panes", __func__,
941
0
        c->name, space, cs->pending_count);
942
943
0
    limit = (space / cs->pending_count / 3); /* 3 bytes for \xxx */
944
0
    if (limit < CONTROL_WRITE_MINIMUM)
945
0
      limit = CONTROL_WRITE_MINIMUM;
946
947
0
    TAILQ_FOREACH_SAFE(cp, &cs->pending_list, pending_entry, cp1) {
948
0
      if (EVBUFFER_LENGTH(evb) >= CONTROL_BUFFER_HIGH)
949
0
        break;
950
0
      if (control_write_pending(c, cp, limit))
951
0
        continue;
952
0
      TAILQ_REMOVE(&cs->pending_list, cp, pending_entry);
953
0
      cp->pending_flag = 0;
954
0
      cs->pending_count--;
955
0
    }
956
0
  }
957
0
  if (EVBUFFER_LENGTH(evb) == 0)
958
0
    bufferevent_disable(cs->write_event, EV_WRITE);
959
0
}
960
961
/* Write a subscription change. */
962
static void
963
control_sub_change(struct monitor_change *change, __unused void *data)
964
0
{
965
0
  struct client   *c = change->c;
966
0
  struct session    *s = change->s;
967
0
  struct winlink    *wl = change->wl;
968
0
  struct window_pane  *wp = change->wp;
969
0
  struct window   *w;
970
971
0
  if (wp != NULL) {
972
0
    w = wp->window;
973
0
    control_notify_write(c,
974
0
        "%%subscription-changed %s $%u @%u %u %%%u : %s",
975
0
        change->name, s->id, w->id, wl->idx, wp->id, change->value);
976
0
  } else if (wl != NULL) {
977
0
    w = wl->window;
978
0
    control_notify_write(c,
979
0
        "%%subscription-changed %s $%u @%u %u - : %s",
980
0
        change->name, s->id, w->id, wl->idx, change->value);
981
0
  } else {
982
0
    control_notify_write(c,
983
0
        "%%subscription-changed %s $%u - - - : %s",
984
0
        change->name, s->id, change->value);
985
0
  }
986
0
}
987
988
/* Initialize for control mode. */
989
void
990
control_start(struct client *c)
991
0
{
992
0
  struct control_state  *cs;
993
994
0
  if (c->flags & CLIENT_CONTROLCONTROL) {
995
0
    close(c->out_fd);
996
0
    c->out_fd = -1;
997
0
  } else
998
0
    setblocking(c->out_fd, 0);
999
0
  setblocking(c->fd, 0);
1000
1001
0
  cs = c->control_state = xcalloc(1, sizeof *cs);
1002
0
  RB_INIT(&cs->panes);
1003
0
  RB_INIT(&cs->windows);
1004
0
  TAILQ_INIT(&cs->pending_list);
1005
0
  TAILQ_INIT(&cs->all_blocks);
1006
0
  TAILQ_INIT(&cs->deferred);
1007
0
  cs->subs = monitor_create_client(c, control_sub_change, NULL);
1008
1009
0
  cs->read_event = bufferevent_new(c->fd, control_read_callback,
1010
0
      control_write_callback, control_error_callback, c);
1011
0
  if (cs->read_event == NULL)
1012
0
    fatalx("out of memory");
1013
1014
0
  if (c->flags & CLIENT_CONTROLCONTROL)
1015
0
    cs->write_event = cs->read_event;
1016
0
  else {
1017
0
    cs->write_event = bufferevent_new(c->out_fd, NULL,
1018
0
        control_write_callback, control_error_callback, c);
1019
0
    if (cs->write_event == NULL)
1020
0
      fatalx("out of memory");
1021
0
  }
1022
0
  bufferevent_setwatermark(cs->write_event, EV_WRITE, CONTROL_BUFFER_LOW,
1023
0
      0);
1024
1025
0
  if (c->flags & CLIENT_CONTROLCONTROL) {
1026
0
    bufferevent_write(cs->write_event, "\033P1000p", 7);
1027
0
    bufferevent_enable(cs->write_event, EV_WRITE);
1028
0
  }
1029
0
}
1030
1031
/* Control client ready. */
1032
void
1033
control_ready(struct client *c)
1034
0
{
1035
0
  bufferevent_enable(c->control_state->read_event, EV_READ);
1036
0
}
1037
1038
/* Discard all output for a client. */
1039
void
1040
control_discard(struct client *c)
1041
0
{
1042
0
  struct control_state  *cs = c->control_state;
1043
0
  struct control_pane *cp;
1044
1045
0
  RB_FOREACH(cp, control_panes, &cs->panes)
1046
0
    control_discard_pane(c, cp);
1047
0
  bufferevent_disable(cs->read_event, EV_READ);
1048
0
}
1049
1050
/* Discard all tmux-owned queued control blocks and stop writing. */
1051
void
1052
control_discard_all(struct client *c)
1053
0
{
1054
0
  struct control_state  *cs = c->control_state;
1055
0
  struct control_block  *cb, *cb1;
1056
1057
0
  control_discard(c);
1058
0
  TAILQ_FOREACH_SAFE(cb, &cs->all_blocks, all_entry, cb1)
1059
0
    control_free_block(cs, cb);
1060
0
  cs->queued_reply_bytes = 0;
1061
0
  bufferevent_disable(cs->write_event, EV_WRITE);
1062
0
}
1063
1064
/* Stop control mode. */
1065
void
1066
control_stop(struct client *c)
1067
0
{
1068
0
  struct control_state  *cs = c->control_state;
1069
0
  struct control_block  *cb, *cb1;
1070
0
  struct control_window *cw, *cw1;
1071
0
  struct control_line *cl, *cl1;
1072
1073
0
  if (cs == NULL)
1074
0
    return;
1075
1076
0
  monitor_destroy(cs->subs);
1077
1078
0
  TAILQ_FOREACH_SAFE(cl, &cs->deferred, entry, cl1) {
1079
0
    TAILQ_REMOVE(&cs->deferred, cl, entry);
1080
0
    free(cl->line);
1081
0
    free(cl);
1082
0
  }
1083
1084
0
  if (~c->flags & CLIENT_CONTROLCONTROL)
1085
0
    bufferevent_free(cs->write_event);
1086
0
  bufferevent_free(cs->read_event);
1087
1088
0
  control_reset_offsets(c);
1089
0
  RB_FOREACH_SAFE(cw, control_windows, &cs->windows, cw1) {
1090
0
    RB_REMOVE(control_windows, &cs->windows, cw);
1091
0
    free(cw);
1092
0
  }
1093
0
  TAILQ_FOREACH_SAFE(cb, &cs->all_blocks, all_entry, cb1)
1094
0
    control_free_block(cs, cb);
1095
1096
0
  c->control_state = NULL;
1097
0
  free(cs);
1098
0
}
1099
1100
/* Add a subscription. */
1101
void
1102
control_add_sub(struct client *c, const char *name, enum monitor_type type,
1103
    int id, const char *format)
1104
0
{
1105
0
  struct control_state  *cs = c->control_state;
1106
1107
0
  monitor_add(cs->subs, name, type, id, format, MONITOR_NOTIFY_INITIAL);
1108
0
}
1109
1110
/* Remove a subscription. */
1111
void
1112
control_remove_sub(struct client *c, const char *name)
1113
0
{
1114
0
  struct control_state  *cs = c->control_state;
1115
1116
0
  monitor_remove(cs->subs, name);
1117
0
}