--- libaitio/src/sock.c 2013/11/22 13:49:14 1.5 +++ libaitio/src/sock.c 2013/11/25 18:50:51 1.10 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: sock.c,v 1.5 2013/11/22 13:49:14 misho Exp $ +* $Id: sock.c,v 1.10 2013/11/25 18:50:51 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -51,7 +51,7 @@ io_closeClient(sched_task_t *task) { sock_cli_t *cli = (sock_cli_t*) TASK_ARG(task); sock_t *s = (sock_t*) cli->cli_parent; - int stat, sock = (int) TASK_DATLEN(task); + int stat; pthread_mutex_lock(&s->sock_mtx); TAILQ_REMOVE(&s->sock_cli, cli, cli_node); @@ -59,18 +59,21 @@ io_closeClient(sched_task_t *task) schedCancelby(s->sock_root, taskMAX, CRITERIA_ARG, cli, NULL); + if (*cli->cli_name) + ioFreePTY(cli->cli_pty, cli->cli_name); + if (s->sock_type == SOCK_STREAM) { - shutdown(sock, SHUT_RDWR); - close(sock); + shutdown(cli->cli_fd, SHUT_RDWR); + close(cli->cli_fd); } AIT_FREE_VAL(&cli->cli_buf[1]); AIT_FREE_VAL(&cli->cli_buf[0]); if (cli->cli_pid > 0) { - kill(cli->cli_pid, SIGTERM); + kill(cli->cli_pid, SIGKILL); while (waitpid(cli->cli_pid, &stat, WNOHANG) > 0) { usleep(1000); - kill(cli->cli_pid, SIGTERM); + kill(cli->cli_pid, SIGKILL); } } @@ -123,7 +126,7 @@ io_acceptClient(sched_task_t *task) AIT_SET_BUFSIZ(&cli->cli_buf[1], 0, AIT_LEN(&s->sock_buf)); schedRead(TASK_ROOT(task), cli->cli_func, cli, cli->cli_fd, TASK_ARG(task), 0); - ioUpdTimerSocket(cli, NULL); + ioUpdTimerSocket(cli); end: schedReadSelf(task); taskExit(task, NULL); @@ -132,21 +135,37 @@ end: static void * io_txNet(sched_task_t *task) { - int wlen; + int wlen, ret, len = TASK_DATLEN(task); sock_cli_t *cli = TASK_ARG(task); sock_t *s = (sock_t*) cli->cli_parent; + u_char *buf = TASK_DATA(task); + struct pollfd pfd[1]; - ioUpdTimerSocket(cli, NULL); + pfd->fd = TASK_FD(task); + pfd->events = POLLOUT; + pfd->revents = 0; + for(; len > 0; len -= wlen, buf += wlen) { + ioUpdTimerSocket(cli); - if (s->sock_type == SOCK_STREAM) - wlen = send(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task), 0); - else - wlen = sendto(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task), 0, - &cli->cli_addr.sa, cli->cli_addr.sa.sa_len); - if (wlen < 1) - schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, - (void*) cli->cli_func, cli->cli_fd); + if ((ret = poll(pfd, 1, s->sock_timeout.tv_sec * 1000)) < 1 || + pfd->revents & (POLLNVAL | POLLERR | POLLHUP)) { + if (!ret) + continue; + schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0); + break; + } + if (s->sock_type == SOCK_STREAM) + wlen = send(TASK_FD(task), buf, len, 0); + else + wlen = sendto(TASK_FD(task), buf, len, 0, + &cli->cli_addr.sa, cli->cli_addr.sa.sa_len); + if (wlen < 1) { + schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0); + break; + } + } + taskExit(task, NULL); } @@ -156,12 +175,11 @@ io_txPty(sched_task_t *task) int wlen; sock_cli_t *cli = TASK_ARG(task); - ioUpdTimerSocket(cli, NULL); + ioUpdTimerSocket(cli); wlen = write(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task)); if (wlen < 1) - schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, - (void*) cli->cli_func, cli->cli_fd); + schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0); taskExit(task, NULL); } @@ -175,7 +193,7 @@ io_rxNet(sched_task_t *task) sockaddr_t sa; socklen_t salen = sizeof sa.ss; - ioUpdTimerSocket(cli, NULL); + ioUpdTimerSocket(cli); if (s->sock_type == SOCK_STREAM) rlen = recv(TASK_FD(task), AIT_GET_BUF(&cli->cli_buf[0]), @@ -187,8 +205,7 @@ io_rxNet(sched_task_t *task) goto end; } if (rlen < 1) - schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, - (void*) cli->cli_func, cli->cli_fd); + schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0); else schedEvent(TASK_ROOT(task), io_txPty, cli, cli->cli_pty, AIT_GET_BUF(&cli->cli_buf[0]), rlen); @@ -203,12 +220,11 @@ io_rxPty(sched_task_t *task) int rlen; sock_cli_t *cli = TASK_ARG(task); - ioUpdTimerSocket(cli, NULL); + ioUpdTimerSocket(cli); 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, - (void*) cli->cli_func, cli->cli_fd); + schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0); else schedEvent(TASK_ROOT(task), io_txNet, cli, cli->cli_fd, AIT_GET_BUF(&cli->cli_buf[1]), rlen); @@ -275,7 +291,8 @@ io_bridgeClient(sched_task_t *task) array_Destroy(&args); printf("Console %s\n", cli->cli_name); - execv(*argv, argv); + rlen = execv(*argv, argv); + _exit(rlen); break; default: cli->cli_pid = pid; @@ -284,7 +301,7 @@ io_bridgeClient(sched_task_t *task) TASK_ARG(task), 0); schedRead(TASK_ROOT(task), io_rxNet, cli, cli->cli_fd, TASK_ARG(task), 0); - ioUpdTimerSocket(cli, NULL); + ioUpdTimerSocket(cli); break; } end: @@ -406,10 +423,10 @@ ioCloseSocket(sock_t ** __restrict s) AIT_FREE_VAL(&cli->cli_buf[0]); if (cli->cli_pid > 0) { - kill(cli->cli_pid, SIGTERM); + kill(cli->cli_pid, SIGKILL); while (waitpid(cli->cli_pid, &stat, WNOHANG) > 0) { usleep(1000); - kill(cli->cli_pid, SIGTERM); + kill(cli->cli_pid, SIGKILL); } } @@ -486,11 +503,10 @@ ioUpSocket(sock_t * __restrict s, void *arg, int timeo * ioUpdTimerSocket() - Update timeout of socket * * @c = Client socket - * @arg = Optional data argument * return: none */ void -ioUpdTimerSocket(sock_cli_t * __restrict c, void *arg) +ioUpdTimerSocket(sock_cli_t * __restrict c) { sock_t *s; @@ -499,8 +515,8 @@ ioUpdTimerSocket(sock_cli_t * __restrict c, void *arg) else s = c->cli_parent; - schedCancelby(s->sock_root, taskTIMER, CRITERIA_DATLEN, (void*) c->cli_fd, NULL); - schedTimer(s->sock_root, io_closeClient, c, s->sock_timeout, arg, c->cli_fd); + schedCancelby(s->sock_root, taskTIMER, CRITERIA_ARG, c, NULL); + schedTimer(s->sock_root, io_closeClient, c, s->sock_timeout, NULL, 0); } /* @@ -519,7 +535,7 @@ ioCloseClient(sock_cli_t * __restrict c) else s = c->cli_parent; - return !schedEvent(s->sock_root, io_closeClient, c, 0, NULL, c->cli_fd); + return !schedEvent(s->sock_root, io_closeClient, c, 0, NULL, 0); } /*