blob: a108d7e7c291e2c4792a0377b62113e06f2318e2 [file] [log] [blame]
Bram Moolenaare0874f82016-01-24 20:36:41 +01001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 */
8
9/*
10 * Implements communication through a socket or any file handle.
11 */
12
13#include "vim.h"
14
15#if defined(FEAT_CHANNEL) || defined(PROTO)
16
17typedef struct {
18 sock_T ch_fd;
19 int ch_idx;
20} channel_T;
21
22static channel_T *channels = NULL;
23static int channel_count = 0;
24
25/*
26 * Add a new channel slot, return the index.
27 * Returns -1 if out of space.
28 */
29 static int
30add_channel(void)
31{
32 int idx;
33 channel_T *new_channels;
34
35 if (channels != NULL)
36 for (idx = 0; idx < channel_count; ++idx)
37 if (channels[idx].ch_fd < 0)
38 /* re-use a closed channel slot */
39 return idx;
40 if (channel_count == MAX_OPEN_CHANNELS)
41 return -1;
42 new_channels = (channel_T *)alloc(sizeof(channel_T) * channel_count + 1);
43 if (new_channels == NULL)
44 return -1;
45 if (channels != NULL)
46 mch_memmove(new_channels, channels, sizeof(channel_T) * channel_count);
47 channels = new_channels;
48 channels[channel_count].ch_fd = (sock_T)-1;
49
50 return channel_count++;
51}
52
53#if defined(FEAT_NETBEANS_INTG) || defined(PROTO)
54static int netbeans_channel = -1;
55
56/*
57 * Add the netbeans socket to the channels.
58 * Return the channel index.
59 */
60 int
61channel_add_netbeans(sock_T fd)
62{
63 int idx = add_channel();
64
65 if (idx >= 0)
66 {
67 channels[idx].ch_fd = fd;
68 netbeans_channel = idx;
69 }
70 return idx;
71}
72
73 void
74channel_remove_netbeans()
75{
76 channels[netbeans_channel].ch_fd = (sock_T)-1;
77 netbeans_channel = -1;
78}
79#endif
80
81 static void
82channel_read(int idx)
83{
84# ifdef FEAT_NETBEANS_INTG
85 if (idx == netbeans_channel)
86 netbeans_read();
87 else
88# endif
89 {
90 ; /* TODO: read */
91 }
92}
93
94#if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
95/*
96 * Add open channels to the poll struct.
97 * Return the adjusted struct index.
98 * The type of "fds" is hidden to avoid problems with the function proto.
99 */
100 int
101channel_poll_setup(int nfd_in, void *fds_in)
102{
103 int nfd = nfd_in;
104 int i;
105 struct pollfd *fds = fds_in;
106
107 for (i = 0; i < channel_count; ++i)
108 if (channels[i].ch_fd >= 0)
109 {
110 channels[i].ch_idx = nfd;
111 fds[nfd].fd = channels[i].ch_fd;
112 fds[nfd].events = POLLIN;
113 nfd++;
114 }
115 else
116 channels[i].ch_idx = -1;
117
118 return nfd;
119}
120
121/*
122 * The type of "fds" is hidden to avoid problems with the function proto.
123 */
124 int
125channel_poll_check(int ret_in, void *fds_in)
126{
127 int ret = ret_in;
128 int i;
129 struct pollfd *fds = fds_in;
130
131 for (i = 0; i < channel_count; ++i)
132 if (ret > 0 && channels[i].ch_idx != -1
133 && fds[channels[i].ch_idx].revents & POLLIN)
134 {
135 channel_read(i);
136 --ret;
137 }
138
139 return ret;
140}
141#endif /* UNIX && !HAVE_SELECT */
142
143#if (defined(UNIX) && defined(HAVE_SELECT)) || defined(PROTO)
144/*
145 * The type of "rfds" is hidden to avoid problems with the function proto.
146 */
147 int
148channel_select_setup(int maxfd_in, void *rfds_in)
149{
150 int maxfd = maxfd_in;
151 int i;
152 fd_set *rfds = rfds_in;
153
154 for (i = 0; i < channel_count; ++i)
155 if (channels[i].ch_fd >= 0)
156 {
157 FD_SET(channels[i].ch_fd, rfds);
158 if (maxfd < channels[i].ch_fd)
159 maxfd = channels[i].ch_fd;
160 }
161
162 return maxfd;
163}
164
165/*
166 * The type of "rfds" is hidden to avoid problems with the function proto.
167 */
168 int
169channel_select_check(int ret_in, void *rfds_in)
170{
171 int ret = ret_in;
172 int i;
173 fd_set *rfds = rfds_in;
174
175 for (i = 0; i < channel_count; ++i)
176 if (ret > 0 && channels[i].ch_fd >= 0
177 && FD_ISSET(channels[i].ch_fd, rfds))
178 {
179 channel_read(i);
180 --ret;
181 }
182
183 return ret;
184}
185#endif /* UNIX && HAVE_SELECT */
186
187#endif /* FEAT_CHANNEL */