Coverage Report

Created: 2025-12-11 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tmux/cmd-load-buffer.c
Line
Count
Source
1
/* $OpenBSD$ */
2
3
/*
4
 * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
21
#include <errno.h>
22
#include <fcntl.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <unistd.h>
27
28
#include "tmux.h"
29
30
/*
31
 * Loads a paste buffer from a file.
32
 */
33
34
static enum cmd_retval  cmd_load_buffer_exec(struct cmd *, struct cmdq_item *);
35
36
const struct cmd_entry cmd_load_buffer_entry = {
37
  .name = "load-buffer",
38
  .alias = "loadb",
39
40
  .args = { "b:t:w", 1, 1, NULL },
41
  .usage = CMD_BUFFER_USAGE " " CMD_TARGET_CLIENT_USAGE " path",
42
43
  .flags = CMD_AFTERHOOK|CMD_CLIENT_TFLAG|CMD_CLIENT_CANFAIL,
44
  .exec = cmd_load_buffer_exec
45
};
46
47
struct cmd_load_buffer_data {
48
  struct client   *client;
49
  struct cmdq_item  *item;
50
  char      *name;
51
};
52
53
static void
54
cmd_load_buffer_done(__unused struct client *c, const char *path, int error,
55
    int closed, struct evbuffer *buffer, void *data)
56
0
{
57
0
  struct cmd_load_buffer_data *cdata = data;
58
0
  struct client     *tc = cdata->client;
59
0
  struct cmdq_item    *item = cdata->item;
60
0
  void        *bdata = EVBUFFER_DATA(buffer);
61
0
  size_t         bsize = EVBUFFER_LENGTH(buffer);
62
0
  void        *copy;
63
0
  char        *cause;
64
65
0
  if (!closed)
66
0
    return;
67
68
0
  if (error != 0)
69
0
    cmdq_error(item, "%s: %s", strerror(error), path);
70
0
  else if (bsize != 0) {
71
0
    copy = xmalloc(bsize);
72
0
    memcpy(copy, bdata, bsize);
73
0
    if (paste_set(copy, bsize, cdata->name, &cause) != 0) {
74
0
      cmdq_error(item, "%s", cause);
75
0
      free(cause);
76
0
      free(copy);
77
0
    } else if (tc != NULL &&
78
0
        tc->session != NULL &&
79
0
        (~tc->flags & CLIENT_DEAD))
80
0
      tty_set_selection(&tc->tty, "", copy, bsize);
81
0
    if (tc != NULL)
82
0
      server_client_unref(tc);
83
0
  }
84
0
  cmdq_continue(item);
85
86
0
  free(cdata->name);
87
0
  free(cdata);
88
0
}
89
90
static enum cmd_retval
91
cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item)
92
0
{
93
0
  struct args     *args = cmd_get_args(self);
94
0
  struct client     *tc = cmdq_get_target_client(item);
95
0
  struct cmd_load_buffer_data *cdata;
96
0
  const char      *bufname = args_get(args, 'b');
97
0
  char        *path;
98
99
0
  cdata = xcalloc(1, sizeof *cdata);
100
0
  cdata->item = item;
101
0
  if (bufname != NULL)
102
0
    cdata->name = xstrdup(bufname);
103
0
  if (args_has(args, 'w') && tc != NULL) {
104
0
    cdata->client = tc;
105
0
    cdata->client->references++;
106
0
  }
107
108
0
  path = format_single_from_target(item, args_string(args, 0));
109
0
  file_read(cmdq_get_client(item), path, cmd_load_buffer_done, cdata);
110
0
  free(path);
111
112
0
  return (CMD_RETURN_WAIT);
113
0
}