Coverage Report

Created: 2026-08-31 06:26

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.66 2026/08/18 07:43:44 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
112
  struct bufferevent    *read_event;
113
  struct bufferevent    *write_event;
114
115
  struct monitor_set    *subs;
116
117
  /*
118
   * Depth of open %begin/%end guard blocks and notifications deferred
119
   * until the outermost block closes.
120
   */
121
  int        guard_depth;
122
  TAILQ_HEAD(, control_line)   deferred;
123
};
124
125
/* Low and high watermarks. */
126
0
#define CONTROL_BUFFER_LOW 512
127
0
#define CONTROL_BUFFER_HIGH 8192
128
129
/* Minimum to write to each client. */
130
0
#define CONTROL_WRITE_MINIMUM 32
131
132
/* Maximum age for clients that are not using pause mode. */
133
0
#define CONTROL_MAXIMUM_AGE 300000
134
135
/* Flags to ignore client. */
136
#define CONTROL_IGNORE_FLAGS \
137
0
  (CLIENT_CONTROL_NOOUTPUT| \
138
0
   CLIENT_UNATTACHEDFLAGS)
139
140
/* Compare client panes. */
141
static int
142
control_pane_cmp(struct control_pane *cp1, struct control_pane *cp2)
143
0
{
144
0
  if (cp1->pane < cp2->pane)
145
0
    return (-1);
146
0
  if (cp1->pane > cp2->pane)
147
0
    return (1);
148
0
  return (0);
149
0
}
150
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
151
0
152
0
/* Compare control windows. */
153
0
static int
154
0
control_window_cmp(struct control_window *cw1, struct control_window *cw2)
155
0
{
156
0
  if (cw1->window < cw2->window)
157
0
    return (-1);
158
0
  if (cw1->window > cw2->window)
159
0
    return (1);
160
0
  return (0);
161
0
}
162
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
163
0
164
0
/* Free a block. */
165
0
static void
166
0
control_free_block(struct control_state *cs, struct control_block *cb)
167
0
{
168
0
  free(cb->line);
169
0
  TAILQ_REMOVE(&cs->all_blocks, cb, all_entry);
170
0
  free(cb);
171
0
}
172
173
/* Get pane offsets for this client. */
174
static struct control_pane *
175
control_get_pane(struct client *c, struct window_pane *wp)
176
0
{
177
0
  struct control_state  *cs = c->control_state;
178
0
  struct control_pane  cp = { .pane = wp->id };
179
180
0
  return (RB_FIND(control_panes, &cs->panes, &cp));
181
0
}
182
183
/* Add pane offsets for this client. */
184
static struct control_pane *
185
control_add_pane(struct client *c, struct window_pane *wp)
186
0
{
187
0
  struct control_state  *cs = c->control_state;
188
0
  struct control_pane *cp;
189
190
0
  cp = control_get_pane(c, wp);
191
0
  if (cp != NULL)
192
0
    return (cp);
193
194
0
  cp = xcalloc(1, sizeof *cp);
195
0
  cp->pane = wp->id;
196
0
  RB_INSERT(control_panes, &cs->panes, cp);
197
198
0
  memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
199
0
  memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
200
0
  TAILQ_INIT(&cp->blocks);
201
202
0
  return (cp);
203
0
}
204
205
/* Get window for this client. */
206
static struct control_window *
207
control_get_window(struct client *c, u_int window)
208
0
{
209
0
  struct control_state  *cs = c->control_state;
210
0
  struct control_window  cw = { .window = window };
211
212
0
  if (cs == NULL)
213
0
    return (NULL);
214
0
  return (RB_FIND(control_windows, &cs->windows, &cw));
215
0
}
216
217
/* Set window size for this client. */
218
void
219
control_set_window_size(struct client *c, u_int window, u_int sx, u_int sy)
220
0
{
221
0
  struct control_state  *cs = c->control_state;
222
0
  struct control_window *cw;
223
224
0
  if (cs == NULL)
225
0
    return;
226
0
  cw = control_get_window(c, window);
227
0
  if (cw == NULL) {
228
0
    cw = xcalloc(1, sizeof *cw);
229
0
    cw->window = window;
230
0
    RB_INSERT(control_windows, &cs->windows, cw);
231
0
  }
232
0
  cw->sx = sx;
233
0
  cw->sy = sy;
234
0
}
235
236
/* Get window size for this client. */
237
int
238
control_get_window_size(struct client *c, u_int window, u_int *sx, u_int *sy)
239
0
{
240
0
  struct control_window *cw;
241
242
0
  if ((cw = control_get_window(c, window)) == NULL)
243
0
    return (0);
244
0
  *sx = cw->sx;
245
0
  *sy = cw->sy;
246
0
  return (1);
247
0
}
248
249
/* Clear window size for this client. */
250
void
251
control_clear_window_size(struct client *c, u_int window)
252
0
{
253
0
  struct control_state  *cs = c->control_state;
254
0
  struct control_window *cw;
255
256
0
  if (cs == NULL)
257
0
    return;
258
0
  cw = control_get_window(c, window);
259
0
  if (cw != NULL) {
260
0
    RB_REMOVE(control_windows, &cs->windows, cw);
261
0
    free(cw);
262
0
  }
263
0
}
264
265
/* Discard output for a pane. */
266
static void
267
control_discard_pane(struct client *c, struct control_pane *cp)
268
0
{
269
0
  struct control_state  *cs = c->control_state;
270
0
  struct control_block  *cb, *cb1;
271
272
0
  TAILQ_FOREACH_SAFE(cb, &cp->blocks, entry, cb1) {
273
0
    TAILQ_REMOVE(&cp->blocks, cb, entry);
274
0
    control_free_block(cs, cb);
275
0
  }
276
0
}
277
278
/* Get actual pane for this client. */
279
static struct window_pane *
280
control_window_pane(struct client *c, u_int pane)
281
0
{
282
0
  struct window_pane  *wp;
283
284
0
  if (c->session == NULL)
285
0
    return (NULL);
286
0
  if ((wp = window_pane_find_by_id(pane)) == NULL)
287
0
    return (NULL);
288
0
  if (winlink_find_by_window(&c->session->windows, wp->window) == NULL)
289
0
    return (NULL);
290
0
  return (wp);
291
0
}
292
293
/* Reset control offsets. */
294
void
295
control_reset_offsets(struct client *c)
296
0
{
297
0
  struct control_state  *cs = c->control_state;
298
0
  struct control_pane *cp, *cp1;
299
300
0
  RB_FOREACH_SAFE(cp, control_panes, &cs->panes, cp1) {
301
0
    control_discard_pane(c, cp);
302
0
    RB_REMOVE(control_panes, &cs->panes, cp);
303
0
    free(cp);
304
0
  }
305
306
0
  TAILQ_INIT(&cs->pending_list);
307
0
  cs->pending_count = 0;
308
0
}
309
310
/* Get offsets for client. */
311
struct window_pane_offset *
312
control_pane_offset(struct client *c, struct window_pane *wp, int *off)
313
0
{
314
0
  struct control_state  *cs = c->control_state;
315
0
  struct control_pane *cp;
316
317
0
  if (c->flags & CLIENT_CONTROL_NOOUTPUT) {
318
0
    *off = 0;
319
0
    return (NULL);
320
0
  }
321
322
0
  cp = control_get_pane(c, wp);
323
0
  if (cp == NULL || (cp->flags & CONTROL_PANE_PAUSED)) {
324
0
    *off = 0;
325
0
    return (NULL);
326
0
  }
327
0
  if (cp->flags & CONTROL_PANE_OFF) {
328
0
    *off = 1;
329
0
    return (NULL);
330
0
  }
331
0
  *off = (EVBUFFER_LENGTH(cs->write_event->output) >= CONTROL_BUFFER_LOW);
332
0
  return (&cp->offset);
333
0
}
334
335
/* Set pane as on. */
336
void
337
control_set_pane_on(struct client *c, struct window_pane *wp)
338
0
{
339
0
  struct control_pane *cp;
340
341
0
  cp = control_get_pane(c, wp);
342
0
  if (cp != NULL && (cp->flags & CONTROL_PANE_OFF)) {
343
0
    cp->flags &= ~CONTROL_PANE_OFF;
344
0
    memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
345
0
    memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
346
0
  }
347
0
}
348
349
/* Set pane as off. */
350
void
351
control_set_pane_off(struct client *c, struct window_pane *wp)
352
0
{
353
0
  struct control_pane *cp;
354
355
0
  cp = control_add_pane(c, wp);
356
0
  control_discard_pane(c, cp);
357
0
  memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
358
0
  memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
359
0
  cp->flags |= CONTROL_PANE_OFF;
360
0
}
361
362
/* Continue a paused pane. */
363
void
364
control_continue_pane(struct client *c, struct window_pane *wp)
365
0
{
366
0
  struct control_pane *cp;
367
368
0
  cp = control_get_pane(c, wp);
369
0
  if (cp != NULL && (cp->flags & CONTROL_PANE_PAUSED)) {
370
0
    cp->flags &= ~CONTROL_PANE_PAUSED;
371
0
    memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
372
0
    memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
373
0
    control_notify_write(c, "%%continue %%%u", wp->id);
374
0
  }
375
0
}
376
377
/* Pause a pane. */
378
void
379
control_pause_pane(struct client *c, struct window_pane *wp)
380
0
{
381
0
  struct control_pane *cp;
382
383
0
  cp = control_add_pane(c, wp);
384
0
  if (~cp->flags & CONTROL_PANE_PAUSED) {
385
0
    cp->flags |= CONTROL_PANE_PAUSED;
386
0
    control_discard_pane(c, cp);
387
0
    control_notify_write(c, "%%pause %%%u", wp->id);
388
0
  }
389
0
}
390
391
/*
392
 * Reset a pane after its buffer has been replaced: drop any output still
393
 * queued from the old buffer and start again from the pane's own offset.
394
 */
395
void
396
control_reset_pane(struct client *c, struct window_pane *wp)
397
0
{
398
0
  struct control_pane *cp;
399
400
0
  if (c->control_state == NULL)
401
0
    return;
402
0
  cp = control_get_pane(c, wp);
403
0
  if (cp == NULL)
404
0
    return;
405
0
  control_discard_pane(c, cp);
406
0
  memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
407
0
  memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
408
0
}
409
410
/* Write an already-formatted line, queueing it behind %output if needed. */
411
static void
412
control_write_line(struct client *c, char *line)
413
0
{
414
0
  struct control_state  *cs = c->control_state;
415
0
  struct control_block  *cb;
416
417
0
  if (TAILQ_EMPTY(&cs->all_blocks)) {
418
0
    log_debug("%s: %s: writing line: %s", __func__, c->name, line);
419
0
    bufferevent_write(cs->write_event, line, strlen(line));
420
0
    bufferevent_write(cs->write_event, "\n", 1);
421
0
    bufferevent_enable(cs->write_event, EV_WRITE);
422
0
    free(line);
423
0
    return;
424
0
  }
425
426
0
  cb = xcalloc(1, sizeof *cb);
427
0
  cb->line = line;
428
0
  TAILQ_INSERT_TAIL(&cs->all_blocks, cb, all_entry);
429
0
  cb->t = get_timer();
430
431
0
  log_debug("%s: %s: storing line: %s", __func__, c->name, cb->line);
432
0
  bufferevent_enable(cs->write_event, EV_WRITE);
433
0
}
434
435
/* Flush notifications that were deferred while a guard block was open. */
436
static void
437
control_flush_deferred(struct client *c)
438
0
{
439
0
  struct control_state  *cs = c->control_state;
440
0
  struct control_line *cl, *cl1;
441
442
0
  TAILQ_FOREACH_SAFE(cl, &cs->deferred, entry, cl1) {
443
0
    TAILQ_REMOVE(&cs->deferred, cl, entry);
444
0
    control_write_line(c, cl->line);
445
0
    free(cl);
446
0
  }
447
0
}
448
449
/*
450
 * Write a line of command output or error text. This is a sink for arbitrary
451
 * user-controlled text (command output, capture-pane, error messages), so it
452
 * must never try to interpret the content: guard tracking is done only in
453
 * control_write_guard.
454
 */
455
void
456
control_write(struct client *c, const char *fmt, ...)
457
0
{
458
0
  va_list  ap;
459
0
  char  *line;
460
461
0
  va_start(ap, fmt);
462
0
  xvasprintf(&line, fmt, ap);
463
0
  va_end(ap);
464
465
0
  control_write_line(c, line);
466
0
}
467
468
/*
469
 * Write a %begin, %end or %error guard around a command's output. This is the
470
 * only place guard lines are produced, so the block depth is maintained here;
471
 * when the outermost block closes any deferred notifications are flushed after
472
 * it. "guard" is always one of the fixed strings from cmdq_guard, never user
473
 * text.
474
 */
475
void
476
control_write_guard(struct client *c, const char *guard, long t, u_int number,
477
    int flags)
478
0
{
479
0
  struct control_state  *cs = c->control_state;
480
0
  char      *line;
481
482
0
  if (strcmp(guard, "begin") == 0)
483
0
    cs->guard_depth++;
484
485
0
  xasprintf(&line, "%%%s %ld %u %d", guard, t, number, flags);
486
0
  control_write_line(c, line);
487
488
0
  if (strcmp(guard, "begin") != 0 && cs->guard_depth > 0 &&
489
0
      --cs->guard_depth == 0)
490
0
    control_flush_deferred(c);
491
0
}
492
493
/*
494
 * Write a notification line. Notifications must never appear inside a command's
495
 * %begin/%end guard block, so if one is open the line is deferred until it
496
 * closes.
497
 */
498
void
499
control_notify_write(struct client *c, const char *fmt, ...)
500
0
{
501
0
  struct control_state  *cs = c->control_state;
502
0
  struct control_line *cl;
503
0
  va_list      ap;
504
0
  char      *line;
505
506
0
  va_start(ap, fmt);
507
0
  xvasprintf(&line, fmt, ap);
508
0
  va_end(ap);
509
510
0
  if (cs->guard_depth == 0) {
511
0
    control_write_line(c, line);
512
0
    return;
513
0
  }
514
515
0
  log_debug("%s: %s: deferring notification: %s", __func__, c->name,
516
0
      line);
517
0
  cl = xcalloc(1, sizeof *cl);
518
0
  cl->line = line;
519
0
  TAILQ_INSERT_TAIL(&cs->deferred, cl, entry);
520
0
}
521
522
/* Check age for this pane. */
523
static int
524
control_check_age(struct client *c, struct window_pane *wp,
525
    struct control_pane *cp)
526
0
{
527
0
  struct control_block  *cb;
528
0
  uint64_t     t, age;
529
530
0
  cb = TAILQ_FIRST(&cp->blocks);
531
0
  if (cb == NULL)
532
0
    return (0);
533
0
  t = get_timer();
534
0
  if (cb->t >= t)
535
0
    return (0);
536
537
0
  age = t - cb->t;
538
0
  log_debug("%s: %s: %%%u is %llu behind", __func__, c->name, wp->id,
539
0
      (unsigned long long)age);
540
541
0
  if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
542
0
    if (age < c->pause_age)
543
0
      return (0);
544
0
    cp->flags |= CONTROL_PANE_PAUSED;
545
0
    control_discard_pane(c, cp);
546
0
    control_notify_write(c, "%%pause %%%u", wp->id);
547
0
  } else {
548
0
    if (age < CONTROL_MAXIMUM_AGE)
549
0
      return (0);
550
0
    c->exit_message = xstrdup("too far behind");
551
0
    c->flags |= CLIENT_EXIT;
552
0
    control_discard(c);
553
0
  }
554
0
  return (1);
555
0
}
556
557
/* Write output from a pane. */
558
void
559
control_write_output(struct client *c, struct window_pane *wp)
560
0
{
561
0
  struct control_state  *cs = c->control_state;
562
0
  struct control_pane *cp;
563
0
  struct control_block  *cb;
564
0
  size_t       new_size;
565
566
0
  if (winlink_find_by_window(&c->session->windows, wp->window) == NULL)
567
0
    return;
568
569
0
  if (c->flags & (CONTROL_IGNORE_FLAGS|CLIENT_EXIT)) {
570
0
    cp = control_get_pane(c, wp);
571
0
    if (cp != NULL)
572
0
      goto ignore;
573
0
    return;
574
0
  }
575
0
  cp = control_add_pane(c, wp);
576
0
  if (cp->flags & (CONTROL_PANE_OFF|CONTROL_PANE_PAUSED))
577
0
    goto ignore;
578
0
  if (control_check_age(c, wp, cp))
579
0
    return;
580
581
0
  window_pane_get_new_data(wp, &cp->queued, &new_size);
582
0
  if (new_size == 0)
583
0
    return;
584
0
  window_pane_update_used_data(wp, &cp->queued, new_size);
585
586
0
  cb = xcalloc(1, sizeof *cb);
587
0
  cb->size = new_size;
588
0
  TAILQ_INSERT_TAIL(&cs->all_blocks, cb, all_entry);
589
0
  cb->t = get_timer();
590
591
0
  TAILQ_INSERT_TAIL(&cp->blocks, cb, entry);
592
0
  log_debug("%s: %s: new output block of %zu for %%%u", __func__, c->name,
593
0
      cb->size, wp->id);
594
595
0
  if (!cp->pending_flag) {
596
0
    log_debug("%s: %s: %%%u now pending", __func__, c->name,
597
0
        wp->id);
598
0
    TAILQ_INSERT_TAIL(&cs->pending_list, cp, pending_entry);
599
0
    cp->pending_flag = 1;
600
0
    cs->pending_count++;
601
0
  }
602
0
  bufferevent_enable(cs->write_event, EV_WRITE);
603
0
  return;
604
605
0
ignore:
606
0
  log_debug("%s: %s: ignoring pane %%%u", __func__, c->name, wp->id);
607
0
  window_pane_update_used_data(wp, &cp->offset, SIZE_MAX);
608
0
  window_pane_update_used_data(wp, &cp->queued, SIZE_MAX);
609
0
}
610
611
/* Control client error callback. */
612
static enum cmd_retval
613
control_error(struct cmdq_item *item, void *data)
614
0
{
615
0
  struct client *c = cmdq_get_client(item);
616
0
  char    *error = data;
617
618
0
  cmdq_guard(item, "begin", 1);
619
0
  control_write(c, "parse error: %s", error);
620
0
  cmdq_guard(item, "error", 1);
621
622
0
  free(error);
623
0
  return (CMD_RETURN_NORMAL);
624
0
}
625
626
/* Control client error callback. */
627
static void
628
control_error_callback(__unused struct bufferevent *bufev,
629
    __unused short what, void *data)
630
0
{
631
0
  struct client *c = data;
632
633
0
  c->flags |= CLIENT_EXIT;
634
0
}
635
636
/* Control client input callback. Read lines and fire commands. */
637
static void
638
control_read_callback(__unused struct bufferevent *bufev, void *data)
639
0
{
640
0
  struct client   *c = data;
641
0
  struct control_state  *cs = c->control_state;
642
0
  struct evbuffer   *buffer = cs->read_event->input;
643
0
  char      *line, *error;
644
0
  struct cmdq_state *state;
645
0
  enum cmd_parse_status  status;
646
647
0
  for (;;) {
648
0
    line = evbuffer_readln(buffer, NULL, EVBUFFER_EOL_LF);
649
0
    if (line == NULL)
650
0
      break;
651
0
    log_debug("%s: %s: %s", __func__, c->name, line);
652
0
    if (*line == '\0') { /* empty line detach */
653
0
      free(line);
654
0
      c->flags |= CLIENT_EXIT;
655
0
      break;
656
0
    }
657
658
0
    state = cmdq_new_state(NULL, NULL, CMDQ_STATE_CONTROL);
659
0
    status = cmd_parse_and_append(line, NULL, c, state, &error);
660
0
    if (status == CMD_PARSE_ERROR)
661
0
      cmdq_append(c, cmdq_get_callback(control_error, error));
662
0
    cmdq_free_state(state);
663
664
0
    free(line);
665
0
  }
666
0
}
667
668
/* Does this control client have outstanding data to write? */
669
int
670
control_all_done(struct client *c)
671
0
{
672
0
  struct control_state  *cs = c->control_state;
673
674
0
  if (!TAILQ_EMPTY(&cs->all_blocks))
675
0
    return (0);
676
0
  return (EVBUFFER_LENGTH(cs->write_event->output) == 0);
677
0
}
678
679
/*
680
 * Wait for the terminal to send an empty line or close, used by a control
681
 * client after printing %exit so a wrapping terminal (such as iTerm2) can
682
 * finish reading.
683
 */
684
void
685
control_wait_exit(int fd)
686
0
{
687
0
  struct pollfd  pfd;
688
0
  struct evbuffer *evb;
689
0
  char    *line;
690
0
  int    n;
691
692
0
  evb = evbuffer_new();
693
0
  if (evb == NULL)
694
0
    fatalx("out of memory");
695
696
0
  for (;;) {
697
0
    line = evbuffer_readln(evb, NULL, EVBUFFER_EOL_LF);
698
0
    if (line != NULL) {
699
0
      if (*line == '\0') { /* empty line, stop */
700
0
        free(line);
701
0
        break;
702
0
      }
703
0
      free(line);
704
0
      continue; /* drain buffered lines first */
705
0
    }
706
707
0
    memset(&pfd, 0, sizeof pfd);
708
0
    pfd.fd = fd;
709
0
    pfd.events = POLLIN;
710
0
    if (poll(&pfd, 1, INFTIM) == -1) {
711
0
      if (errno == EINTR)
712
0
        continue;
713
0
      break;
714
0
    }
715
716
0
    n = evbuffer_read(evb, fd, -1);
717
0
    if (n == 0)
718
0
      break;
719
0
    if (n == -1 && errno != EAGAIN && errno != EINTR)
720
0
      break;
721
0
  }
722
723
0
  evbuffer_free(evb);
724
0
}
725
726
/* Flush all blocks until output. */
727
static void
728
control_flush_all_blocks(struct client *c)
729
0
{
730
0
  struct control_state  *cs = c->control_state;
731
0
  struct control_block  *cb, *cb1;
732
733
0
  TAILQ_FOREACH_SAFE(cb, &cs->all_blocks, all_entry, cb1) {
734
0
    if (cb->size != 0)
735
0
      break;
736
0
    log_debug("%s: %s: flushing line: %s", __func__, c->name,
737
0
        cb->line);
738
739
0
    bufferevent_write(cs->write_event, cb->line, strlen(cb->line));
740
0
    bufferevent_write(cs->write_event, "\n", 1);
741
0
    control_free_block(cs, cb);
742
0
  }
743
0
}
744
745
/* Append data to buffer. */
746
static struct evbuffer *
747
control_append_data(struct client *c, struct control_pane *cp, uint64_t age,
748
    struct evbuffer *message, struct window_pane *wp, size_t size)
749
0
{
750
0
  u_char  *new_data;
751
0
  size_t   new_size, start;
752
0
  u_int  i;
753
754
0
  if (message == NULL) {
755
0
    message = evbuffer_new();
756
0
    if (message == NULL)
757
0
      fatalx("out of memory");
758
0
    if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
759
0
      evbuffer_add_printf(message,
760
0
          "%%extended-output %%%u %llu : ", wp->id,
761
0
          (unsigned long long)age);
762
0
    } else
763
0
      evbuffer_add_printf(message, "%%output %%%u ", wp->id);
764
0
  }
765
766
0
  new_data = window_pane_get_new_data(wp, &cp->offset, &new_size);
767
0
  if (new_size < size)
768
0
    fatalx("not enough data: %zu < %zu", new_size, size);
769
0
  for (i = 0; i < size; i++) {
770
0
    if (new_data[i] < ' ' || new_data[i] == '\\') {
771
0
      evbuffer_add_printf(message, "\\%03o", new_data[i]);
772
0
    } else {
773
0
      start = i;
774
0
      while (i + 1 < size &&
775
0
          new_data[i + 1] >= ' ' &&
776
0
          new_data[i + 1] != '\\')
777
0
        i++;
778
0
      evbuffer_add(message, new_data + start, i - start + 1);
779
0
    }
780
0
  }
781
0
  window_pane_update_used_data(wp, &cp->offset, size);
782
0
  return (message);
783
0
}
784
785
/* Write buffer. */
786
static void
787
control_write_data(struct client *c, struct evbuffer *message)
788
0
{
789
0
  struct control_state  *cs = c->control_state;
790
791
0
  log_debug("%s: %s: %.*s", __func__, c->name,
792
0
      (int)EVBUFFER_LENGTH(message), EVBUFFER_DATA(message));
793
794
0
  evbuffer_add(message, "\n", 1);
795
0
  bufferevent_write_buffer(cs->write_event, message);
796
0
  evbuffer_free(message);
797
0
}
798
799
/* Write output to client. */
800
static int
801
control_write_pending(struct client *c, struct control_pane *cp, size_t limit)
802
0
{
803
0
  struct control_state  *cs = c->control_state;
804
0
  struct window_pane  *wp = NULL;
805
0
  struct evbuffer   *message = NULL;
806
0
  size_t       used = 0, size;
807
0
  struct control_block  *cb, *cb1;
808
0
  uint64_t     age, t = get_timer();
809
810
0
  wp = control_window_pane(c, cp->pane);
811
0
  if (wp == NULL || wp->fd == -1) {
812
0
    TAILQ_FOREACH_SAFE(cb, &cp->blocks, entry, cb1) {
813
0
      TAILQ_REMOVE(&cp->blocks, cb, entry);
814
0
      control_free_block(cs, cb);
815
0
    }
816
0
    control_flush_all_blocks(c);
817
0
    return (0);
818
0
  }
819
820
0
  while (used != limit && !TAILQ_EMPTY(&cp->blocks)) {
821
0
    if (control_check_age(c, wp, cp)) {
822
0
      if (message != NULL)
823
0
        evbuffer_free(message);
824
0
      message = NULL;
825
0
      break;
826
0
    }
827
828
0
    cb = TAILQ_FIRST(&cp->blocks);
829
0
    if (cb->t < t)
830
0
      age = t - cb->t;
831
0
    else
832
0
      age = 0;
833
0
    log_debug("%s: %s: output block %zu (age %llu) for %%%u "
834
0
        "(used %zu/%zu)", __func__, c->name, cb->size,
835
0
        (unsigned long long)age, cp->pane, used, limit);
836
837
0
    size = cb->size;
838
0
    if (size > limit - used)
839
0
      size = limit - used;
840
0
    used += size;
841
842
0
    message = control_append_data(c, cp, age, message, wp, size);
843
844
0
    cb->size -= size;
845
0
    if (cb->size == 0) {
846
0
      TAILQ_REMOVE(&cp->blocks, cb, entry);
847
0
      control_free_block(cs, cb);
848
849
0
      cb = TAILQ_FIRST(&cs->all_blocks);
850
0
      if (cb != NULL && cb->size == 0) {
851
0
        if (wp != NULL && message != NULL) {
852
0
          control_write_data(c, message);
853
0
          message = NULL;
854
0
        }
855
0
        control_flush_all_blocks(c);
856
0
      }
857
0
    }
858
0
  }
859
0
  if (message != NULL)
860
0
    control_write_data(c, message);
861
0
  return (!TAILQ_EMPTY(&cp->blocks));
862
0
}
863
864
/* Control client write callback. */
865
static void
866
control_write_callback(__unused struct bufferevent *bufev, void *data)
867
0
{
868
0
  struct client   *c = data;
869
0
  struct control_state  *cs = c->control_state;
870
0
  struct control_pane *cp, *cp1;
871
0
  struct evbuffer   *evb = cs->write_event->output;
872
0
  size_t       space, limit;
873
874
0
  control_flush_all_blocks(c);
875
876
0
  while (EVBUFFER_LENGTH(evb) < CONTROL_BUFFER_HIGH) {
877
0
    if (cs->pending_count == 0)
878
0
      break;
879
0
    space = CONTROL_BUFFER_HIGH - EVBUFFER_LENGTH(evb);
880
0
    log_debug("%s: %s: %zu bytes available, %u panes", __func__,
881
0
        c->name, space, cs->pending_count);
882
883
0
    limit = (space / cs->pending_count / 3); /* 3 bytes for \xxx */
884
0
    if (limit < CONTROL_WRITE_MINIMUM)
885
0
      limit = CONTROL_WRITE_MINIMUM;
886
887
0
    TAILQ_FOREACH_SAFE(cp, &cs->pending_list, pending_entry, cp1) {
888
0
      if (EVBUFFER_LENGTH(evb) >= CONTROL_BUFFER_HIGH)
889
0
        break;
890
0
      if (control_write_pending(c, cp, limit))
891
0
        continue;
892
0
      TAILQ_REMOVE(&cs->pending_list, cp, pending_entry);
893
0
      cp->pending_flag = 0;
894
0
      cs->pending_count--;
895
0
    }
896
0
  }
897
0
  if (EVBUFFER_LENGTH(evb) == 0)
898
0
    bufferevent_disable(cs->write_event, EV_WRITE);
899
0
}
900
901
/* Write a subscription change. */
902
static void
903
control_sub_change(struct monitor_change *change, __unused void *data)
904
0
{
905
0
  struct client   *c = change->c;
906
0
  struct session    *s = change->s;
907
0
  struct winlink    *wl = change->wl;
908
0
  struct window_pane  *wp = change->wp;
909
0
  struct window   *w;
910
911
0
  if (wp != NULL) {
912
0
    w = wp->window;
913
0
    control_notify_write(c,
914
0
        "%%subscription-changed %s $%u @%u %u %%%u : %s",
915
0
        change->name, s->id, w->id, wl->idx, wp->id, change->value);
916
0
  } else if (wl != NULL) {
917
0
    w = wl->window;
918
0
    control_notify_write(c,
919
0
        "%%subscription-changed %s $%u @%u %u - : %s",
920
0
        change->name, s->id, w->id, wl->idx, change->value);
921
0
  } else {
922
0
    control_notify_write(c,
923
0
        "%%subscription-changed %s $%u - - - : %s",
924
0
        change->name, s->id, change->value);
925
0
  }
926
0
}
927
928
/* Initialize for control mode. */
929
void
930
control_start(struct client *c)
931
0
{
932
0
  struct control_state  *cs;
933
934
0
  if (c->flags & CLIENT_CONTROLCONTROL) {
935
0
    close(c->out_fd);
936
0
    c->out_fd = -1;
937
0
  } else
938
0
    setblocking(c->out_fd, 0);
939
0
  setblocking(c->fd, 0);
940
941
0
  cs = c->control_state = xcalloc(1, sizeof *cs);
942
0
  RB_INIT(&cs->panes);
943
0
  RB_INIT(&cs->windows);
944
0
  TAILQ_INIT(&cs->pending_list);
945
0
  TAILQ_INIT(&cs->all_blocks);
946
0
  TAILQ_INIT(&cs->deferred);
947
0
  cs->subs = monitor_create_client(c, control_sub_change, NULL);
948
949
0
  cs->read_event = bufferevent_new(c->fd, control_read_callback,
950
0
      control_write_callback, control_error_callback, c);
951
0
  if (cs->read_event == NULL)
952
0
    fatalx("out of memory");
953
954
0
  if (c->flags & CLIENT_CONTROLCONTROL)
955
0
    cs->write_event = cs->read_event;
956
0
  else {
957
0
    cs->write_event = bufferevent_new(c->out_fd, NULL,
958
0
        control_write_callback, control_error_callback, c);
959
0
    if (cs->write_event == NULL)
960
0
      fatalx("out of memory");
961
0
  }
962
0
  bufferevent_setwatermark(cs->write_event, EV_WRITE, CONTROL_BUFFER_LOW,
963
0
      0);
964
965
0
  if (c->flags & CLIENT_CONTROLCONTROL) {
966
0
    bufferevent_write(cs->write_event, "\033P1000p", 7);
967
0
    bufferevent_enable(cs->write_event, EV_WRITE);
968
0
  }
969
0
}
970
971
/* Control client ready. */
972
void
973
control_ready(struct client *c)
974
0
{
975
0
  bufferevent_enable(c->control_state->read_event, EV_READ);
976
0
}
977
978
/* Discard all output for a client. */
979
void
980
control_discard(struct client *c)
981
0
{
982
0
  struct control_state  *cs = c->control_state;
983
0
  struct control_pane *cp;
984
985
0
  RB_FOREACH(cp, control_panes, &cs->panes)
986
0
    control_discard_pane(c, cp);
987
0
  bufferevent_disable(cs->read_event, EV_READ);
988
0
}
989
990
/* Discard all tmux-owned queued control blocks and stop writing. */
991
void
992
control_discard_all(struct client *c)
993
0
{
994
0
  struct control_state  *cs = c->control_state;
995
0
  struct control_block  *cb, *cb1;
996
997
0
  control_discard(c);
998
0
  TAILQ_FOREACH_SAFE(cb, &cs->all_blocks, all_entry, cb1)
999
0
    control_free_block(cs, cb);
1000
0
  bufferevent_disable(cs->write_event, EV_WRITE);
1001
0
}
1002
1003
/* Stop control mode. */
1004
void
1005
control_stop(struct client *c)
1006
0
{
1007
0
  struct control_state  *cs = c->control_state;
1008
0
  struct control_block  *cb, *cb1;
1009
0
  struct control_window *cw, *cw1;
1010
0
  struct control_line *cl, *cl1;
1011
1012
0
  if (cs == NULL)
1013
0
    return;
1014
1015
0
  monitor_destroy(cs->subs);
1016
1017
0
  TAILQ_FOREACH_SAFE(cl, &cs->deferred, entry, cl1) {
1018
0
    TAILQ_REMOVE(&cs->deferred, cl, entry);
1019
0
    free(cl->line);
1020
0
    free(cl);
1021
0
  }
1022
1023
0
  if (~c->flags & CLIENT_CONTROLCONTROL)
1024
0
    bufferevent_free(cs->write_event);
1025
0
  bufferevent_free(cs->read_event);
1026
1027
0
  control_reset_offsets(c);
1028
0
  RB_FOREACH_SAFE(cw, control_windows, &cs->windows, cw1) {
1029
0
    RB_REMOVE(control_windows, &cs->windows, cw);
1030
0
    free(cw);
1031
0
  }
1032
0
  TAILQ_FOREACH_SAFE(cb, &cs->all_blocks, all_entry, cb1)
1033
0
    control_free_block(cs, cb);
1034
1035
0
  c->control_state = NULL;
1036
0
  free(cs);
1037
0
}
1038
1039
/* Add a subscription. */
1040
void
1041
control_add_sub(struct client *c, const char *name, enum monitor_type type,
1042
    int id, const char *format)
1043
0
{
1044
0
  struct control_state  *cs = c->control_state;
1045
1046
0
  monitor_add(cs->subs, name, type, id, format, MONITOR_NOTIFY_INITIAL);
1047
0
}
1048
1049
/* Remove a subscription. */
1050
void
1051
control_remove_sub(struct client *c, const char *name)
1052
0
{
1053
0
  struct control_state  *cs = c->control_state;
1054
1055
0
  monitor_remove(cs->subs, name);
1056
0
}