Coverage Report

Created: 2026-08-31 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwebsockets/lib/plat/unix/unix-pipe.c
Line
Count
Source
1
/*
2
 * libwebsockets - small server side websockets and web server implementation
3
 *
4
 * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to
8
 * deal in the Software without restriction, including without limitation the
9
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
 * sell copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
 * IN THE SOFTWARE.
23
 */
24
25
#if !defined(_GNU_SOURCE)
26
#define _GNU_SOURCE
27
#endif
28
#include "private-lib-core.h"
29
30
int
31
lws_plat_pipe_create(struct lws *wsi)
32
0
{
33
0
  struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
34
0
  int n;
35
36
0
#if defined(LWS_HAVE_EVENTFD)
37
0
  pt->dummy_pipe_fds[0] = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
38
0
  pt->dummy_pipe_fds[1] = -1;
39
40
0
  n = pt->dummy_pipe_fds[0] < 0 ? -1 : 0;
41
0
  goto set;
42
43
#elif defined(LWS_HAVE_PIPE2)
44
  n = pipe2(pt->dummy_pipe_fds, O_NONBLOCK);
45
#else
46
  n = pipe(pt->dummy_pipe_fds);
47
#endif
48
49
0
#if defined(LWS_HAVE_EVENTFD)
50
0
set:
51
0
#endif
52
0
  if (n >= 0) {
53
0
    if (fcntl(pt->dummy_pipe_fds[0], F_SETFL, O_NONBLOCK) < 0)
54
0
      n = -1;
55
0
    else if (pt->dummy_pipe_fds[1] >= 0) {
56
0
      if (fcntl(pt->dummy_pipe_fds[1], F_SETFL, O_NONBLOCK) < 0)
57
0
        n = -1;
58
0
    }
59
0
  }
60
61
0
  return n;
62
0
}
63
64
int
65
lws_plat_pipe_signal(struct lws_context *ctx, int tsi)
66
0
{
67
0
  struct lws_context_per_thread *pt = &ctx->pt[tsi];
68
0
#if defined(LWS_HAVE_EVENTFD)
69
0
  eventfd_t value = 1;
70
71
0
  return eventfd_write(pt->dummy_pipe_fds[0], value);
72
#else
73
  char buf = 0;
74
  int n;
75
76
  n = (int)write(pt->dummy_pipe_fds[1], &buf, 1);
77
78
  return n != 1;
79
#endif
80
0
}
81
82
void
83
lws_plat_pipe_close(struct lws *wsi)
84
0
{
85
0
  struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
86
87
0
  if (pt->dummy_pipe_fds[0] != LWS_SOCK_INVALID) {
88
0
    if (wsi->desc.sockfd == pt->dummy_pipe_fds[0])
89
0
      wsi->desc.sockfd = LWS_SOCK_INVALID;
90
0
    close(pt->dummy_pipe_fds[0]);
91
0
    pt->dummy_pipe_fds[0] = LWS_SOCK_INVALID;
92
0
  }
93
0
  if (pt->dummy_pipe_fds[1] != LWS_SOCK_INVALID) {
94
0
    if (wsi->desc.sockfd == pt->dummy_pipe_fds[1])
95
0
      wsi->desc.sockfd = LWS_SOCK_INVALID;
96
0
    close(pt->dummy_pipe_fds[1]);
97
0
    pt->dummy_pipe_fds[1] = LWS_SOCK_INVALID;
98
0
  }
99
0
}
100
101
int
102
lws_plat_pipe_is_fd_assocated(struct lws_context *cx, int tsi, lws_sockfd_type fd)
103
0
{
104
0
  struct lws_context_per_thread *pt = &cx->pt[tsi];
105
106
0
  return fd == pt->dummy_pipe_fds[0] || fd == pt->dummy_pipe_fds[1];
107
0
}