comparison common-session.c @ 1495:0c16b4ccbd54

make signal flags volatile, simplify handling
author Matt Johnston <matt@ucc.asn.au>
date Wed, 14 Feb 2018 23:06:01 +0800
parents 2c9dac2d6707
children 5916af64acd4 fa733a314bee
comparison
equal deleted inserted replaced
1494:da095983a60b 1495:0c16b4ccbd54
41 static int ident_readln(int fd, char* buf, int count); 41 static int ident_readln(int fd, char* buf, int count);
42 static void read_session_identification(void); 42 static void read_session_identification(void);
43 43
44 struct sshsession ses; /* GLOBAL */ 44 struct sshsession ses; /* GLOBAL */
45 45
46 /* need to know if the session struct has been initialised, this way isn't the
47 * cleanest, but works OK */
48 int sessinitdone = 0; /* GLOBAL */
49
50 /* this is set when we get SIGINT or SIGTERM, the handler is in main.c */
51 int exitflag = 0; /* GLOBAL */
52
53 /* called only at the start of a session, set up initial state */ 46 /* called only at the start of a session, set up initial state */
54 void common_session_init(int sock_in, int sock_out) { 47 void common_session_init(int sock_in, int sock_out) {
55 time_t now; 48 time_t now;
56 49
57 #if DEBUG_TRACE 50 #if DEBUG_TRACE
160 dropbear_assert(ses.payload == NULL); 153 dropbear_assert(ses.payload == NULL);
161 154
162 /* We get woken up when signal handlers write to this pipe. 155 /* We get woken up when signal handlers write to this pipe.
163 SIGCHLD in svr-chansession is the only one currently. */ 156 SIGCHLD in svr-chansession is the only one currently. */
164 FD_SET(ses.signal_pipe[0], &readfd); 157 FD_SET(ses.signal_pipe[0], &readfd);
165 ses.channel_signal_pending = 0;
166 158
167 /* set up for channels which can be read/written */ 159 /* set up for channels which can be read/written */
168 setchannelfds(&readfd, &writefd, writequeue_has_space); 160 setchannelfds(&readfd, &writefd, writequeue_has_space);
169 161
170 /* Pending connections to test */ 162 /* Pending connections to test */
188 FD_SET(ses.sock_out, &writefd); 180 FD_SET(ses.sock_out, &writefd);
189 } 181 }
190 182
191 val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout); 183 val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout);
192 184
193 if (exitflag) { 185 if (ses.exitflag) {
194 dropbear_exit("Terminated by signal"); 186 dropbear_exit("Terminated by signal");
195 } 187 }
196 188
197 if (val < 0 && errno != EINTR) { 189 if (val < 0 && errno != EINTR) {
198 dropbear_exit("Error in select"); 190 dropbear_exit("Error in select");
208 } 200 }
209 201
210 /* We'll just empty out the pipe if required. We don't do 202 /* We'll just empty out the pipe if required. We don't do
211 any thing with the data, since the pipe's purpose is purely to 203 any thing with the data, since the pipe's purpose is purely to
212 wake up the select() above. */ 204 wake up the select() above. */
205 ses.channel_signal_pending = 0;
213 if (FD_ISSET(ses.signal_pipe[0], &readfd)) { 206 if (FD_ISSET(ses.signal_pipe[0], &readfd)) {
214 char x; 207 char x;
215 TRACE(("signal pipe set")) 208 TRACE(("signal pipe set"))
216 while (read(ses.signal_pipe[0], &x, 1) > 0) {} 209 while (read(ses.signal_pipe[0], &x, 1) > 0) {}
217 ses.channel_signal_pending = 1; 210 ses.channel_signal_pending = 1;
242 were being held up during a KEX */ 235 were being held up during a KEX */
243 maybe_flush_reply_queue(); 236 maybe_flush_reply_queue();
244 237
245 handle_connect_fds(&writefd); 238 handle_connect_fds(&writefd);
246 239
240 /* loop handler prior to channelio, in case the server loophandler closes
241 channels on process exit */
242 loophandler();
243
247 /* process pipes etc for the channels, ses.dataallowed == 0 244 /* process pipes etc for the channels, ses.dataallowed == 0
248 * during rekeying ) */ 245 * during rekeying ) */
249 channelio(&readfd, &writefd); 246 channelio(&readfd, &writefd);
250 247
251 /* process session socket's outgoing data */ 248 /* process session socket's outgoing data */
253 if (!isempty(&ses.writequeue)) { 250 if (!isempty(&ses.writequeue)) {
254 write_packet(); 251 write_packet();
255 } 252 }
256 } 253 }
257 254
258
259 if (loophandler) {
260 loophandler();
261 }
262
263 } /* for(;;) */ 255 } /* for(;;) */
264 256
265 /* Not reached */ 257 /* Not reached */
266 } 258 }
267 259
278 void session_cleanup() { 270 void session_cleanup() {
279 271
280 TRACE(("enter session_cleanup")) 272 TRACE(("enter session_cleanup"))
281 273
282 /* we can't cleanup if we don't know the session state */ 274 /* we can't cleanup if we don't know the session state */
283 if (!sessinitdone) { 275 if (!ses.init_done) {
284 TRACE(("leave session_cleanup: !sessinitdone")) 276 TRACE(("leave session_cleanup: !ses.init_done"))
285 return; 277 return;
286 } 278 }
287 279
288 /* BEWARE of changing order of functions here. */ 280 /* BEWARE of changing order of functions here. */
289 281