diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | channels.c | 79 | ||||
-rw-r--r-- | channels.h | 5 | ||||
-rw-r--r-- | clientloop.c | 11 | ||||
-rw-r--r-- | nchan.c | 8 | ||||
-rw-r--r-- | serverloop.c | 27 |
6 files changed, 81 insertions, 55 deletions
@@ -15,6 +15,10 @@ | |||
15 | - markus@cvs.openbsd.org 2001/07/17 20:48:42 | 15 | - markus@cvs.openbsd.org 2001/07/17 20:48:42 |
16 | [ssh-agent.c] | 16 | [ssh-agent.c] |
17 | update maxfd if maxfd is closed; report from jmcelroy@dtgnet.com | 17 | update maxfd if maxfd is closed; report from jmcelroy@dtgnet.com |
18 | - markus@cvs.openbsd.org 2001/07/17 21:04:58 | ||
19 | [channels.c channels.h clientloop.c nchan.c serverloop.c] | ||
20 | keep track of both maxfd and the size of the malloc'ed fdsets. | ||
21 | update maxfd if maxfd gets closed. | ||
18 | 22 | ||
19 | 20010715 | 23 | 20010715 |
20 | - (bal) Set "BROKEN_GETADDRINFO" for darwin platform. Reported by | 24 | - (bal) Set "BROKEN_GETADDRINFO" for darwin platform. Reported by |
@@ -6054,4 +6058,4 @@ | |||
6054 | - Wrote replacements for strlcpy and mkdtemp | 6058 | - Wrote replacements for strlcpy and mkdtemp |
6055 | - Released 1.0pre1 | 6059 | - Released 1.0pre1 |
6056 | 6060 | ||
6057 | $Id: ChangeLog,v 1.1408 2001/07/18 15:58:08 mouring Exp $ | 6061 | $Id: ChangeLog,v 1.1409 2001/07/18 16:01:46 mouring Exp $ |
diff --git a/channels.c b/channels.c index 35edff6dc..7bf127d91 100644 --- a/channels.c +++ b/channels.c | |||
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: channels.c,v 1.131 2001/07/02 22:52:56 markus Exp $"); | 42 | RCSID("$OpenBSD: channels.c,v 1.132 2001/07/17 21:04:56 markus Exp $"); |
43 | 43 | ||
44 | #include "ssh.h" | 44 | #include "ssh.h" |
45 | #include "ssh1.h" | 45 | #include "ssh1.h" |
@@ -266,6 +266,37 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, | |||
266 | return c; | 266 | return c; |
267 | } | 267 | } |
268 | 268 | ||
269 | static int | ||
270 | channel_find_maxfd(void) | ||
271 | { | ||
272 | int i, max = 0; | ||
273 | Channel *c; | ||
274 | |||
275 | for (i = 0; i < channels_alloc; i++) { | ||
276 | c = channels[i]; | ||
277 | if (c != NULL) { | ||
278 | max = MAX(max, c->rfd); | ||
279 | max = MAX(max, c->wfd); | ||
280 | max = MAX(max, c->efd); | ||
281 | } | ||
282 | } | ||
283 | return max; | ||
284 | } | ||
285 | |||
286 | int | ||
287 | channel_close_fd(int *fdp) | ||
288 | { | ||
289 | int ret = 0, fd = *fdp; | ||
290 | |||
291 | if (fd != -1) { | ||
292 | ret = close(fd); | ||
293 | *fdp = -1; | ||
294 | if (fd == channel_max_fd) | ||
295 | channel_max_fd = channel_find_maxfd(); | ||
296 | } | ||
297 | return ret; | ||
298 | } | ||
299 | |||
269 | /* Close all channel fd/socket. */ | 300 | /* Close all channel fd/socket. */ |
270 | 301 | ||
271 | static void | 302 | static void |
@@ -274,22 +305,10 @@ channel_close_fds(Channel *c) | |||
274 | debug3("channel_close_fds: channel %d: r %d w %d e %d", | 305 | debug3("channel_close_fds: channel %d: r %d w %d e %d", |
275 | c->self, c->rfd, c->wfd, c->efd); | 306 | c->self, c->rfd, c->wfd, c->efd); |
276 | 307 | ||
277 | if (c->sock != -1) { | 308 | channel_close_fd(&c->sock); |
278 | close(c->sock); | 309 | channel_close_fd(&c->rfd); |
279 | c->sock = -1; | 310 | channel_close_fd(&c->wfd); |
280 | } | 311 | channel_close_fd(&c->efd); |
281 | if (c->rfd != -1) { | ||
282 | close(c->rfd); | ||
283 | c->rfd = -1; | ||
284 | } | ||
285 | if (c->wfd != -1) { | ||
286 | close(c->wfd); | ||
287 | c->wfd = -1; | ||
288 | } | ||
289 | if (c->efd != -1) { | ||
290 | close(c->efd); | ||
291 | c->efd = -1; | ||
292 | } | ||
293 | } | 312 | } |
294 | 313 | ||
295 | /* Free the channel and close its fd/socket. */ | 314 | /* Free the channel and close its fd/socket. */ |
@@ -387,7 +406,7 @@ channel_stop_listening(void) | |||
387 | case SSH_CHANNEL_PORT_LISTENER: | 406 | case SSH_CHANNEL_PORT_LISTENER: |
388 | case SSH_CHANNEL_RPORT_LISTENER: | 407 | case SSH_CHANNEL_RPORT_LISTENER: |
389 | case SSH_CHANNEL_X11_LISTENER: | 408 | case SSH_CHANNEL_X11_LISTENER: |
390 | close(c->sock); | 409 | channel_close_fd(&c->sock); |
391 | channel_free(c); | 410 | channel_free(c); |
392 | break; | 411 | break; |
393 | } | 412 | } |
@@ -842,7 +861,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) | |||
842 | log("X11 connection rejected because of wrong authentication."); | 861 | log("X11 connection rejected because of wrong authentication."); |
843 | buffer_clear(&c->input); | 862 | buffer_clear(&c->input); |
844 | buffer_clear(&c->output); | 863 | buffer_clear(&c->output); |
845 | close(c->sock); | 864 | channel_close_fd(&c->sock); |
846 | c->sock = -1; | 865 | c->sock = -1; |
847 | c->type = SSH_CHANNEL_CLOSED; | 866 | c->type = SSH_CHANNEL_CLOSED; |
848 | packet_start(SSH_MSG_CHANNEL_CLOSE); | 867 | packet_start(SSH_MSG_CHANNEL_CLOSE); |
@@ -1333,8 +1352,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) | |||
1333 | if (len <= 0) { | 1352 | if (len <= 0) { |
1334 | debug2("channel %d: closing write-efd %d", | 1353 | debug2("channel %d: closing write-efd %d", |
1335 | c->self, c->efd); | 1354 | c->self, c->efd); |
1336 | close(c->efd); | 1355 | channel_close_fd(&c->efd); |
1337 | c->efd = -1; | ||
1338 | } else { | 1356 | } else { |
1339 | buffer_consume(&c->extended, len); | 1357 | buffer_consume(&c->extended, len); |
1340 | c->local_consumed += len; | 1358 | c->local_consumed += len; |
@@ -1349,8 +1367,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) | |||
1349 | if (len <= 0) { | 1367 | if (len <= 0) { |
1350 | debug2("channel %d: closing read-efd %d", | 1368 | debug2("channel %d: closing read-efd %d", |
1351 | c->self, c->efd); | 1369 | c->self, c->efd); |
1352 | close(c->efd); | 1370 | channel_close_fd(&c->efd); |
1353 | c->efd = -1; | ||
1354 | } else { | 1371 | } else { |
1355 | buffer_append(&c->extended, buf, len); | 1372 | buffer_append(&c->extended, buf, len); |
1356 | } | 1373 | } |
@@ -1532,7 +1549,7 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) | |||
1532 | */ | 1549 | */ |
1533 | void | 1550 | void |
1534 | channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, | 1551 | channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, |
1535 | int rekeying) | 1552 | int *nallocp, int rekeying) |
1536 | { | 1553 | { |
1537 | int n; | 1554 | int n; |
1538 | u_int sz; | 1555 | u_int sz; |
@@ -1540,15 +1557,13 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, | |||
1540 | n = MAX(*maxfdp, channel_max_fd); | 1557 | n = MAX(*maxfdp, channel_max_fd); |
1541 | 1558 | ||
1542 | sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); | 1559 | sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); |
1543 | if (*readsetp == NULL || n > *maxfdp) { | 1560 | /* perhaps check sz < nalloc/2 and shrink? */ |
1544 | if (*readsetp) | 1561 | if (*readsetp == NULL || sz > *nallocp) { |
1545 | xfree(*readsetp); | 1562 | *readsetp = xrealloc(*readsetp, sz); |
1546 | if (*writesetp) | 1563 | *writesetp = xrealloc(*writesetp, sz); |
1547 | xfree(*writesetp); | 1564 | *nallocp = sz; |
1548 | *readsetp = xmalloc(sz); | ||
1549 | *writesetp = xmalloc(sz); | ||
1550 | *maxfdp = n; | ||
1551 | } | 1565 | } |
1566 | *maxfdp = n; | ||
1552 | memset(*readsetp, 0, sz); | 1567 | memset(*readsetp, 0, sz); |
1553 | memset(*writesetp, 0, sz); | 1568 | memset(*writesetp, 0, sz); |
1554 | 1569 | ||
diff --git a/channels.h b/channels.h index e4146b593..2ee1496c7 100644 --- a/channels.h +++ b/channels.h | |||
@@ -32,7 +32,7 @@ | |||
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | */ | 34 | */ |
35 | /* RCSID("$OpenBSD: channels.h,v 1.44 2001/07/02 22:52:57 markus Exp $"); */ | 35 | /* RCSID("$OpenBSD: channels.h,v 1.45 2001/07/17 21:04:57 markus Exp $"); */ |
36 | 36 | ||
37 | #ifndef CHANNEL_H | 37 | #ifndef CHANNEL_H |
38 | #define CHANNEL_H | 38 | #define CHANNEL_H |
@@ -152,6 +152,7 @@ void channel_register_callback(int, int mtype, channel_callback_fn *, void *); | |||
152 | void channel_register_cleanup(int, channel_callback_fn *); | 152 | void channel_register_cleanup(int, channel_callback_fn *); |
153 | void channel_register_filter(int, channel_filter_fn *); | 153 | void channel_register_filter(int, channel_filter_fn *); |
154 | void channel_cancel_cleanup(int); | 154 | void channel_cancel_cleanup(int); |
155 | int channel_close_fd(int *); | ||
155 | 156 | ||
156 | /* protocol handler */ | 157 | /* protocol handler */ |
157 | 158 | ||
@@ -169,7 +170,7 @@ void channel_input_window_adjust(int, int, void *); | |||
169 | 170 | ||
170 | /* file descriptor handling (read/write) */ | 171 | /* file descriptor handling (read/write) */ |
171 | 172 | ||
172 | void channel_prepare_select(fd_set **, fd_set **, int *, int); | 173 | void channel_prepare_select(fd_set **, fd_set **, int *, int*, int); |
173 | void channel_after_select(fd_set *, fd_set *); | 174 | void channel_after_select(fd_set *, fd_set *); |
174 | void channel_output_poll(void); | 175 | void channel_output_poll(void); |
175 | 176 | ||
diff --git a/clientloop.c b/clientloop.c index 83b2d4d8e..41aff8354 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -59,7 +59,7 @@ | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include "includes.h" | 61 | #include "includes.h" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.80 2001/06/30 18:08:40 stevesk Exp $"); | 62 | RCSID("$OpenBSD: clientloop.c,v 1.81 2001/07/17 21:04:57 markus Exp $"); |
63 | 63 | ||
64 | #include "ssh.h" | 64 | #include "ssh.h" |
65 | #include "ssh1.h" | 65 | #include "ssh1.h" |
@@ -318,10 +318,10 @@ client_check_window_change(void) | |||
318 | 318 | ||
319 | static void | 319 | static void |
320 | client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | 320 | client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, |
321 | int *maxfdp, int rekeying) | 321 | int *maxfdp, int *nallocp, int rekeying) |
322 | { | 322 | { |
323 | /* Add any selections by the channel mechanism. */ | 323 | /* Add any selections by the channel mechanism. */ |
324 | channel_prepare_select(readsetp, writesetp, maxfdp, rekeying); | 324 | channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); |
325 | 325 | ||
326 | if (!compat20) { | 326 | if (!compat20) { |
327 | /* Read from the connection, unless our buffers are full. */ | 327 | /* Read from the connection, unless our buffers are full. */ |
@@ -770,7 +770,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
770 | { | 770 | { |
771 | fd_set *readset = NULL, *writeset = NULL; | 771 | fd_set *readset = NULL, *writeset = NULL; |
772 | double start_time, total_time; | 772 | double start_time, total_time; |
773 | int max_fd = 0, len, rekeying = 0; | 773 | int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; |
774 | char buf[100]; | 774 | char buf[100]; |
775 | 775 | ||
776 | debug("Entering interactive session."); | 776 | debug("Entering interactive session."); |
@@ -877,8 +877,9 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
877 | * Wait until we have something to do (something becomes | 877 | * Wait until we have something to do (something becomes |
878 | * available on one of the descriptors). | 878 | * available on one of the descriptors). |
879 | */ | 879 | */ |
880 | max_fd2 = max_fd; | ||
880 | client_wait_until_can_do_something(&readset, &writeset, | 881 | client_wait_until_can_do_something(&readset, &writeset, |
881 | &max_fd, rekeying); | 882 | &max_fd2, &nalloc, rekeying); |
882 | 883 | ||
883 | if (quit_pending) | 884 | if (quit_pending) |
884 | break; | 885 | break; |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: nchan.c,v 1.30 2001/06/25 08:25:38 markus Exp $"); | 26 | RCSID("$OpenBSD: nchan.c,v 1.31 2001/07/17 21:04:57 markus Exp $"); |
27 | 27 | ||
28 | #include "ssh1.h" | 28 | #include "ssh1.h" |
29 | #include "ssh2.h" | 29 | #include "ssh2.h" |
@@ -518,11 +518,10 @@ chan_shutdown_write(Channel *c) | |||
518 | "shutdown() failed for fd%d: %.100s", | 518 | "shutdown() failed for fd%d: %.100s", |
519 | c->self, c->sock, strerror(errno)); | 519 | c->self, c->sock, strerror(errno)); |
520 | } else { | 520 | } else { |
521 | if (close(c->wfd) < 0) | 521 | if (channel_close_fd(&c->wfd) < 0) |
522 | log("channel %d: chan_shutdown_write: " | 522 | log("channel %d: chan_shutdown_write: " |
523 | "close() failed for fd%d: %.100s", | 523 | "close() failed for fd%d: %.100s", |
524 | c->self, c->wfd, strerror(errno)); | 524 | c->self, c->wfd, strerror(errno)); |
525 | c->wfd = -1; | ||
526 | } | 525 | } |
527 | } | 526 | } |
528 | static void | 527 | static void |
@@ -544,10 +543,9 @@ chan_shutdown_read(Channel *c) | |||
544 | c->self, c->sock, c->istate, c->ostate, | 543 | c->self, c->sock, c->istate, c->ostate, |
545 | strerror(errno)); | 544 | strerror(errno)); |
546 | } else { | 545 | } else { |
547 | if (close(c->rfd) < 0) | 546 | if (channel_close_fd(&c->rfd) < 0) |
548 | log("channel %d: chan_shutdown_read: " | 547 | log("channel %d: chan_shutdown_read: " |
549 | "close() failed for fd%d: %.100s", | 548 | "close() failed for fd%d: %.100s", |
550 | c->self, c->rfd, strerror(errno)); | 549 | c->self, c->rfd, strerror(errno)); |
551 | c->rfd = -1; | ||
552 | } | 550 | } |
553 | } | 551 | } |
diff --git a/serverloop.c b/serverloop.c index f826c6cb2..d9791274c 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "includes.h" | 37 | #include "includes.h" |
38 | RCSID("$OpenBSD: serverloop.c,v 1.75 2001/07/15 16:17:08 markus Exp $"); | 38 | RCSID("$OpenBSD: serverloop.c,v 1.76 2001/07/17 21:04:58 markus Exp $"); |
39 | 39 | ||
40 | #include "xmalloc.h" | 40 | #include "xmalloc.h" |
41 | #include "packet.h" | 41 | #include "packet.h" |
@@ -169,7 +169,7 @@ make_packets_from_stdout_data(void) | |||
169 | */ | 169 | */ |
170 | static void | 170 | static void |
171 | wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, | 171 | wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, |
172 | u_int max_time_milliseconds) | 172 | int *nallocp, u_int max_time_milliseconds) |
173 | { | 173 | { |
174 | struct timeval tv, *tvp; | 174 | struct timeval tv, *tvp; |
175 | int ret; | 175 | int ret; |
@@ -193,7 +193,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, | |||
193 | retry_select: | 193 | retry_select: |
194 | 194 | ||
195 | /* Allocate and update select() masks for channel descriptors. */ | 195 | /* Allocate and update select() masks for channel descriptors. */ |
196 | channel_prepare_select(readsetp, writesetp, maxfdp, 0); | 196 | channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 0); |
197 | 197 | ||
198 | if (compat20) { | 198 | if (compat20) { |
199 | /* wrong: bad condition XXX */ | 199 | /* wrong: bad condition XXX */ |
@@ -435,7 +435,7 @@ void | |||
435 | server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) | 435 | server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) |
436 | { | 436 | { |
437 | fd_set *readset = NULL, *writeset = NULL; | 437 | fd_set *readset = NULL, *writeset = NULL; |
438 | int max_fd; | 438 | int max_fd = 0, nalloc = 0; |
439 | int wait_status; /* Status returned by wait(). */ | 439 | int wait_status; /* Status returned by wait(). */ |
440 | pid_t wait_pid; /* pid returned by wait(). */ | 440 | pid_t wait_pid; /* pid returned by wait(). */ |
441 | int waiting_termination = 0; /* Have displayed waiting close message. */ | 441 | int waiting_termination = 0; /* Have displayed waiting close message. */ |
@@ -476,12 +476,14 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) | |||
476 | else | 476 | else |
477 | buffer_high = 64 * 1024; | 477 | buffer_high = 64 * 1024; |
478 | 478 | ||
479 | #if 0 | ||
479 | /* Initialize max_fd to the maximum of the known file descriptors. */ | 480 | /* Initialize max_fd to the maximum of the known file descriptors. */ |
480 | max_fd = MAX(fdin, fdout); | 481 | max_fd = MAX(connection_in, connection_out); |
482 | max_fd = MAX(max_fd, fdin); | ||
483 | max_fd = MAX(max_fd, fdout); | ||
481 | if (fderr != -1) | 484 | if (fderr != -1) |
482 | max_fd = MAX(max_fd, fderr); | 485 | max_fd = MAX(max_fd, fderr); |
483 | max_fd = MAX(max_fd, connection_in); | 486 | #endif |
484 | max_fd = MAX(max_fd, connection_out); | ||
485 | 487 | ||
486 | /* Initialize Initialize buffers. */ | 488 | /* Initialize Initialize buffers. */ |
487 | buffer_init(&stdin_buffer); | 489 | buffer_init(&stdin_buffer); |
@@ -567,9 +569,14 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) | |||
567 | xfree(cp); | 569 | xfree(cp); |
568 | } | 570 | } |
569 | } | 571 | } |
572 | max_fd = MAX(connection_in, connection_out); | ||
573 | max_fd = MAX(max_fd, fdin); | ||
574 | max_fd = MAX(max_fd, fdout); | ||
575 | max_fd = MAX(max_fd, fderr); | ||
576 | |||
570 | /* Sleep in select() until we can do something. */ | 577 | /* Sleep in select() until we can do something. */ |
571 | wait_until_can_do_something(&readset, &writeset, &max_fd, | 578 | wait_until_can_do_something(&readset, &writeset, &max_fd, |
572 | max_time_milliseconds); | 579 | &nalloc, max_time_milliseconds); |
573 | 580 | ||
574 | /* Process any channel events. */ | 581 | /* Process any channel events. */ |
575 | channel_after_select(readset, writeset); | 582 | channel_after_select(readset, writeset); |
@@ -662,7 +669,7 @@ void | |||
662 | server_loop2(Authctxt *authctxt) | 669 | server_loop2(Authctxt *authctxt) |
663 | { | 670 | { |
664 | fd_set *readset = NULL, *writeset = NULL; | 671 | fd_set *readset = NULL, *writeset = NULL; |
665 | int rekeying = 0, max_fd, status; | 672 | int rekeying = 0, max_fd, status, nalloc = 0; |
666 | pid_t pid; | 673 | pid_t pid; |
667 | 674 | ||
668 | debug("Entering interactive session for SSH2."); | 675 | debug("Entering interactive session for SSH2."); |
@@ -685,7 +692,7 @@ server_loop2(Authctxt *authctxt) | |||
685 | if (!rekeying && packet_not_very_much_data_to_write()) | 692 | if (!rekeying && packet_not_very_much_data_to_write()) |
686 | channel_output_poll(); | 693 | channel_output_poll(); |
687 | wait_until_can_do_something(&readset, &writeset, &max_fd, | 694 | wait_until_can_do_something(&readset, &writeset, &max_fd, |
688 | rekeying); | 695 | &nalloc, 0); |
689 | if (child_terminated) { | 696 | if (child_terminated) { |
690 | while ((pid = waitpid(-1, &status, WNOHANG)) > 0) | 697 | while ((pid = waitpid(-1, &status, WNOHANG)) > 0) |
691 | session_close_by_pid(pid, status); | 698 | session_close_by_pid(pid, status); |