Mercurial > dropbear
comparison svr-chansession.c @ 419:b2f81110c80b channel-fix
propagate from branch 'au.asn.ucc.matt.dropbear' (head 924b731b50d4147eed8e9382c98a2573259a6cad)
to branch 'au.asn.ucc.matt.dropbear.channel-fix' (head e73ee8f7ae404a9355685c30828a0ad4524031bc)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 11 Feb 2007 09:55:00 +0000 |
parents | a01c0c8e543a |
children | b2b67cfcd66e |
comparison
equal
deleted
inserted
replaced
418:ab57ba0cb667 | 419:b2f81110c80b |
---|---|
57 static void send_exitsignalstatus(struct Channel *channel); | 57 static void send_exitsignalstatus(struct Channel *channel); |
58 static void send_msg_chansess_exitstatus(struct Channel * channel, | 58 static void send_msg_chansess_exitstatus(struct Channel * channel, |
59 struct ChanSess * chansess); | 59 struct ChanSess * chansess); |
60 static void send_msg_chansess_exitsignal(struct Channel * channel, | 60 static void send_msg_chansess_exitsignal(struct Channel * channel, |
61 struct ChanSess * chansess); | 61 struct ChanSess * chansess); |
62 static int sesscheckclose(struct Channel *channel); | |
63 static void get_termmodes(struct ChanSess *chansess); | 62 static void get_termmodes(struct ChanSess *chansess); |
64 | 63 |
65 | 64 |
66 /* required to clear environment */ | 65 /* required to clear environment */ |
67 extern char** environ; | 66 extern char** environ; |
68 | 67 |
69 static int sesscheckclose(struct Channel *channel) { | 68 static int sesscheckclose(struct Channel *channel) { |
70 struct ChanSess *chansess = (struct ChanSess*)channel->typedata; | 69 struct ChanSess *chansess = (struct ChanSess*)channel->typedata; |
71 return chansess->exit.exitpid >= 0; | 70 return chansess->exit.exitpid != -1; |
72 } | 71 } |
73 | 72 |
74 /* Handler for childs exiting, store the state for return to the client */ | 73 /* Handler for childs exiting, store the state for return to the client */ |
75 | 74 |
76 /* There's a particular race we have to watch out for: if the forked child | 75 /* There's a particular race we have to watch out for: if the forked child |
119 #endif | 118 #endif |
120 } else { | 119 } else { |
121 /* we use this to determine how pid exited */ | 120 /* we use this to determine how pid exited */ |
122 exit->exitsignal = -1; | 121 exit->exitsignal = -1; |
123 } | 122 } |
124 } | 123 |
125 | 124 /* Make sure that the main select() loop wakes up */ |
126 | 125 while (1) { |
126 /* EAGAIN means the pipe's full, so don't need to write anything */ | |
127 /* isserver is just a random byte to write */ | |
128 if (write(ses.signal_pipe[1], &ses.isserver, 1) == 1 || errno == EAGAIN) { | |
129 break; | |
130 } | |
131 if (errno == EINTR) { | |
132 continue; | |
133 } | |
134 dropbear_exit("error writing signal pipe"); | |
135 } | |
136 } | |
137 | |
127 sa_chld.sa_handler = sesssigchild_handler; | 138 sa_chld.sa_handler = sesssigchild_handler; |
128 sa_chld.sa_flags = SA_NOCLDSTOP; | 139 sa_chld.sa_flags = SA_NOCLDSTOP; |
129 sigaction(SIGCHLD, &sa_chld, NULL); | 140 sigaction(SIGCHLD, &sa_chld, NULL); |
130 TRACE(("leave sigchld handler")) | 141 TRACE(("leave sigchld handler")) |
131 } | 142 } |
243 | 254 |
244 struct ChanSess *chansess; | 255 struct ChanSess *chansess; |
245 unsigned int i; | 256 unsigned int i; |
246 struct logininfo *li; | 257 struct logininfo *li; |
247 | 258 |
259 TRACE(("enter closechansess")) | |
260 | |
248 chansess = (struct ChanSess*)channel->typedata; | 261 chansess = (struct ChanSess*)channel->typedata; |
249 | 262 |
250 send_exitsignalstatus(channel); | |
251 | |
252 TRACE(("enter closechansess")) | |
253 if (chansess == NULL) { | 263 if (chansess == NULL) { |
254 TRACE(("leave closechansess: chansess == NULL")) | 264 TRACE(("leave closechansess: chansess == NULL")) |
255 return; | 265 return; |
256 } | 266 } |
267 | |
268 send_exitsignalstatus(channel); | |
257 | 269 |
258 m_free(chansess->cmd); | 270 m_free(chansess->cmd); |
259 m_free(chansess->term); | 271 m_free(chansess->term); |
260 | 272 |
261 if (chansess->tty) { | 273 if (chansess->tty) { |