--- libaitio/src/sock.c 2013/12/12 21:17:53 1.11.2.3 +++ libaitio/src/sock.c 2014/04/29 01:26:21 1.14.4.1 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: sock.c,v 1.11.2.3 2013/12/12 21:17:53 misho Exp $ +* $Id: sock.c,v 1.14.4.1 2014/04/29 01:26:21 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 +Copyright 2004 - 2014 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -63,7 +63,11 @@ io_closeClient(sched_task_t *task) ioFreePTY(cli->cli_pty, cli->cli_name); if (s->sock_prog) { io_progDetach(s->sock_prog, cli->cli_pty); +#if 0 + io_progCloseAt(s->sock_prog, cli->cli_pty); +#endif cli->cli_pty ^= cli->cli_pty; + io_progCheck(s->sock_prog, 42); } if (s->sock_type == SOCK_STREAM) { @@ -153,8 +157,10 @@ io_txNet(sched_task_t *task) if ((ret = poll(pfd, 1, s->sock_timeout.tv_sec * 1000)) < 1 || pfd->revents & (POLLNVAL | POLLERR | POLLHUP)) { +#if 0 if (!ret) continue; +#endif schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0); break; } @@ -205,16 +211,19 @@ io_rxNet(sched_task_t *task) else { rlen = recvfrom(TASK_FD(task), AIT_GET_BUF(&cli->cli_buf[0]), AIT_LEN(&cli->cli_buf[0]), 0, &sa.sa, &salen); - if (e_addrcmp(&cli->cli_addr, &sa, 42)) - goto end; + if (e_addrcmp(&cli->cli_addr, &sa, 42)) { + schedReadSelf(task); + taskExit(task, NULL); + } } if (rlen < 1) schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0); - else + else { schedEvent(TASK_ROOT(task), io_txPty, cli, cli->cli_pty, AIT_GET_BUF(&cli->cli_buf[0]), rlen); -end: - schedReadSelf(task); + schedReadSelf(task); + } + taskExit(task, NULL); } @@ -229,18 +238,19 @@ io_rxPty(sched_task_t *task) rlen = read(TASK_FD(task), AIT_GET_BUF(&cli->cli_buf[1]), AIT_LEN(&cli->cli_buf[1])); if (rlen < 1) schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0); - else + else { schedEvent(TASK_ROOT(task), io_txNet, cli, cli->cli_fd, AIT_GET_BUF(&cli->cli_buf[1]), rlen); + schedReadSelf(task); + } - schedReadSelf(task); taskExit(task, NULL); } static void * io_bridgeClient(sched_task_t *task) { - int c, rlen; + int c, rlen, pty; pid_t pid; sockaddr_t sa; socklen_t salen = sizeof sa.ss; @@ -284,12 +294,14 @@ io_bridgeClient(sched_task_t *task) AIT_SET_BUFSIZ(&cli->cli_buf[0], 0, AIT_LEN(&s->sock_buf)); AIT_SET_BUFSIZ(&cli->cli_buf[1], 0, AIT_LEN(&s->sock_buf)); - switch ((pid = ioForkPTY(&cli->cli_pty, cli->cli_name, sizeof cli->cli_name, + switch ((pid = ioForkPTY(&pty, cli->cli_name, sizeof cli->cli_name, NULL, NULL, NULL))) { case -1: ELIBERR(io); break; case 0: + cli->cli_pty = pty; + array_Args(cli->cli_cmdline, 0, " \t", &args); argv = array_To(args); array_Destroy(&args); @@ -301,6 +313,7 @@ io_bridgeClient(sched_task_t *task) _exit(rlen); break; default: + cli->cli_pty = pty; cli->cli_pid = pid; schedRead(TASK_ROOT(task), io_rxPty, cli, cli->cli_pty, @@ -352,6 +365,8 @@ io_bridgeClient2Pool(sched_task_t *task) pthread_mutex_unlock(&s->sock_mtx); } + io_progCheck(s->sock_prog, 42); + cli->cli_parent = TASK_ARG(task); cli->cli_fd = c; cli->cli_pty = io_progAttach(s->sock_prog, 42); @@ -617,6 +632,18 @@ ioLoopSocket(sock_t * __restrict s, sched_task_func_t return schedRun(s->sock_root, &s->sock_kill); } +static void * +io_progPurge(sched_task_t *task) +{ + sock_t *s = (sock_t*) TASK_ARG(task); + + io_progVacuum(s->sock_prog, 0); + + schedTimer(TASK_ROOT(task), TASK_FUNC(task), TASK_ARG(task), + s->sock_timeout, TASK_DATA(task), TASK_DATLEN(task)); + taskExit(task, NULL); +} + /* * ioBridgeProg2Socket() - Start socket scheduler and bridge program to socket * @@ -630,8 +657,13 @@ ioBridgeProg2Socket(sock_t * __restrict s, const char if (!s || !prgname || s->sock_kill) return -1; - schedRead(s->sock_root, s->sock_prog ? io_bridgeClient2Pool : io_bridgeClient, - s, s->sock_fd, (void*) prgname, 0); + if (s->sock_prog) { + schedRead(s->sock_root, io_bridgeClient2Pool, + s, s->sock_fd, (void*) prgname, 0); + schedTimer(s->sock_root, io_progPurge, s, s->sock_timeout, NULL, 0); + } else + schedRead(s->sock_root, io_bridgeClient, + s, s->sock_fd, (void*) prgname, 0); return schedRun(s->sock_root, &s->sock_kill); }