1 /* ide-pty-intercept.h
2 *
3 * Copyright 2018-2019 Christian Hergert <chergert@redhat.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21 #pragma once
22
23 #if !defined (IDE_IO_INSIDE) && !defined (IDE_IO_COMPILATION)
24 # error "Only <libide-io.h> can be included directly."
25 #endif
26
27 #include <libide-core.h>
28 #include <unistd.h>
29
30 G_BEGIN_DECLS
31
32 #define IDE_PTY_FD_INVALID (-1)
33 #define IDE_PTY_INTERCEPT_MAGIC (0x81723647)
34 #define IDE_IS_PTY_INTERCEPT(s) ((s) != NULL && (s)->magic == IDE_PTY_INTERCEPT_MAGIC)
35
36 typedef int IdePtyFd;
37 typedef struct _IdePtyIntercept IdePtyIntercept;
38 typedef struct _IdePtyInterceptSide IdePtyInterceptSide;
39 typedef void (*IdePtyInterceptCallback) (const IdePtyIntercept *intercept,
40 const IdePtyInterceptSide *side,
41 const guint8 *data,
42 gsize len,
43 gpointer user_data);
44
45 struct _IdePtyInterceptSide
46 {
47 GIOChannel *channel;
48 guint in_watch;
49 guint out_watch;
50 gint read_prio;
51 gint write_prio;
52 GBytes *out_bytes;
53 IdePtyInterceptCallback callback;
54 gpointer callback_data;
55 };
56
57 struct _IdePtyIntercept
58 {
59 gsize magic;
60 IdePtyInterceptSide master;
61 IdePtyInterceptSide slave;
62 };
63
64 static inline IdePtyFd
pty_fd_steal(IdePtyFd * fd)65 pty_fd_steal (IdePtyFd *fd)
66 {
67 IdePtyFd ret = *fd;
68 *fd = -1;
69 return ret;
70 }
71
72 static void
pty_fd_clear(IdePtyFd * fd)73 pty_fd_clear (IdePtyFd *fd)
74 {
75 if (fd != NULL && *fd != -1)
76 {
77 int rfd = *fd;
78 *fd = -1;
79 close (rfd);
80 }
81 }
82
83 G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (IdePtyFd, pty_fd_clear)
84
85 IDE_AVAILABLE_IN_3_32
86 IdePtyFd ide_pty_intercept_create_master (void);
87 IDE_AVAILABLE_IN_3_32
88 IdePtyFd ide_pty_intercept_create_slave (IdePtyFd master_fd,
89 gboolean blocking);
90 IDE_AVAILABLE_IN_3_32
91 gboolean ide_pty_intercept_init (IdePtyIntercept *self,
92 IdePtyFd fd,
93 GMainContext *main_context);
94 IDE_AVAILABLE_IN_3_32
95 IdePtyFd ide_pty_intercept_get_fd (IdePtyIntercept *self);
96 IDE_AVAILABLE_IN_3_32
97 gboolean ide_pty_intercept_set_size (IdePtyIntercept *self,
98 guint rows,
99 guint columns);
100 IDE_AVAILABLE_IN_3_32
101 void ide_pty_intercept_clear (IdePtyIntercept *self);
102 IDE_AVAILABLE_IN_3_32
103 void ide_pty_intercept_set_callback (IdePtyIntercept *self,
104 IdePtyInterceptSide *side,
105 IdePtyInterceptCallback callback,
106 gpointer user_data);
107
108 G_END_DECLS
109