Diff for /libaitio/src/sock.c between versions 1.5 and 1.14

version 1.5, 2013/11/22 13:49:14 version 1.14, 2014/02/08 22:06:17
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013Copyright 2004 - 2014
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 51  io_closeClient(sched_task_t *task) Line 51  io_closeClient(sched_task_t *task)
 {  {
         sock_cli_t *cli = (sock_cli_t*) TASK_ARG(task);          sock_cli_t *cli = (sock_cli_t*) TASK_ARG(task);
         sock_t *s = (sock_t*) cli->cli_parent;          sock_t *s = (sock_t*) cli->cli_parent;
        int stat, sock = (int) TASK_DATLEN(task);        int stat;
   
         pthread_mutex_lock(&s->sock_mtx);          pthread_mutex_lock(&s->sock_mtx);
         TAILQ_REMOVE(&s->sock_cli, cli, cli_node);          TAILQ_REMOVE(&s->sock_cli, cli, cli_node);
Line 59  io_closeClient(sched_task_t *task) Line 59  io_closeClient(sched_task_t *task)
   
         schedCancelby(s->sock_root, taskMAX, CRITERIA_ARG, cli, NULL);          schedCancelby(s->sock_root, taskMAX, CRITERIA_ARG, cli, NULL);
   
           if (*cli->cli_name)
                   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) {          if (s->sock_type == SOCK_STREAM) {
                shutdown(sock, SHUT_RDWR);                shutdown(cli->cli_fd, SHUT_RDWR);
                close(sock);                close(cli->cli_fd);
         }          }
         AIT_FREE_VAL(&cli->cli_buf[1]);          AIT_FREE_VAL(&cli->cli_buf[1]);
         AIT_FREE_VAL(&cli->cli_buf[0]);          AIT_FREE_VAL(&cli->cli_buf[0]);
   
         if (cli->cli_pid > 0) {          if (cli->cli_pid > 0) {
                kill(cli->cli_pid, SIGTERM);                kill(cli->cli_pid, SIGKILL);
                 while (waitpid(cli->cli_pid, &stat, WNOHANG) > 0) {                  while (waitpid(cli->cli_pid, &stat, WNOHANG) > 0) {
                         usleep(1000);                          usleep(1000);
                        kill(cli->cli_pid, SIGTERM);                        kill(cli->cli_pid, SIGKILL);
                 }                  }
         }          }
   
Line 123  io_acceptClient(sched_task_t *task) Line 134  io_acceptClient(sched_task_t *task)
         AIT_SET_BUFSIZ(&cli->cli_buf[1], 0, AIT_LEN(&s->sock_buf));          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);          schedRead(TASK_ROOT(task), cli->cli_func, cli, cli->cli_fd, TASK_ARG(task), 0);
        ioUpdTimerSocket(cli, NULL);        ioUpdTimerSocket(cli);
 end:  end:
         schedReadSelf(task);          schedReadSelf(task);
         taskExit(task, NULL);          taskExit(task, NULL);
Line 132  end: Line 143  end:
 static void *  static void *
 io_txNet(sched_task_t *task)  io_txNet(sched_task_t *task)
 {  {
        int wlen;        int wlen, ret, len = TASK_DATLEN(task);
         sock_cli_t *cli = TASK_ARG(task);          sock_cli_t *cli = TASK_ARG(task);
         sock_t *s = (sock_t*) cli->cli_parent;          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)                if ((ret = poll(pfd, 1, s->sock_timeout.tv_sec * 1000)) < 1 || 
                wlen = send(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task), 0);                                pfd->revents & (POLLNVAL | POLLERR | POLLHUP)) {
        else#if 0
                wlen = sendto(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task), 0,                         if (!ret)
                                &cli->cli_addr.sa, cli->cli_addr.sa.sa_len);                                continue;
        if (wlen < 1)#endif
                schedEvent(TASK_ROOT(task), io_closeClient, cli, 0,                         schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0);
                                (void*) cli->cli_func, cli->cli_fd);                        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);          taskExit(task, NULL);
 }  }
   
Line 156  io_txPty(sched_task_t *task) Line 185  io_txPty(sched_task_t *task)
         int wlen;          int wlen;
         sock_cli_t *cli = TASK_ARG(task);          sock_cli_t *cli = TASK_ARG(task);
   
        ioUpdTimerSocket(cli, NULL);        ioUpdTimerSocket(cli);
   
         wlen = write(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task));          wlen = write(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task));
         if (wlen < 1)          if (wlen < 1)
                schedEvent(TASK_ROOT(task), io_closeClient, cli, 0,                 schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0);
                                (void*) cli->cli_func, cli->cli_fd); 
   
         taskExit(task, NULL);          taskExit(task, NULL);
 }  }
Line 175  io_rxNet(sched_task_t *task) Line 203  io_rxNet(sched_task_t *task)
         sockaddr_t sa;          sockaddr_t sa;
         socklen_t salen = sizeof sa.ss;          socklen_t salen = sizeof sa.ss;
   
        ioUpdTimerSocket(cli, NULL);        ioUpdTimerSocket(cli);
   
         if (s->sock_type == SOCK_STREAM)          if (s->sock_type == SOCK_STREAM)
                 rlen = recv(TASK_FD(task), AIT_GET_BUF(&cli->cli_buf[0]),                   rlen = recv(TASK_FD(task), AIT_GET_BUF(&cli->cli_buf[0]), 
Line 187  io_rxNet(sched_task_t *task) Line 215  io_rxNet(sched_task_t *task)
                         goto end;                          goto end;
         }          }
         if (rlen < 1)          if (rlen < 1)
                schedEvent(TASK_ROOT(task), io_closeClient, cli, 0,                 schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0);
                                (void*) cli->cli_func, cli->cli_fd); 
         else          else
                 schedEvent(TASK_ROOT(task), io_txPty, cli, cli->cli_pty,                   schedEvent(TASK_ROOT(task), io_txPty, cli, cli->cli_pty, 
                                 AIT_GET_BUF(&cli->cli_buf[0]), rlen);                                  AIT_GET_BUF(&cli->cli_buf[0]), rlen);
Line 203  io_rxPty(sched_task_t *task) Line 230  io_rxPty(sched_task_t *task)
         int rlen;          int rlen;
         sock_cli_t *cli = TASK_ARG(task);          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]));          rlen = read(TASK_FD(task), AIT_GET_BUF(&cli->cli_buf[1]), AIT_LEN(&cli->cli_buf[1]));
         if (rlen < 1)          if (rlen < 1)
                schedEvent(TASK_ROOT(task), io_closeClient, cli, 0,                 schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0);
                                (void*) cli->cli_func, cli->cli_fd); 
         else          else
                 schedEvent(TASK_ROOT(task), io_txNet, cli, cli->cli_fd,                   schedEvent(TASK_ROOT(task), io_txNet, cli, cli->cli_fd, 
                                 AIT_GET_BUF(&cli->cli_buf[1]), rlen);                                  AIT_GET_BUF(&cli->cli_buf[1]), rlen);
Line 220  io_rxPty(sched_task_t *task) Line 246  io_rxPty(sched_task_t *task)
 static void *  static void *
 io_bridgeClient(sched_task_t *task)  io_bridgeClient(sched_task_t *task)
 {  {
        int c, rlen;        int c, rlen, pty;
         pid_t pid;          pid_t pid;
         sockaddr_t sa;          sockaddr_t sa;
         socklen_t salen = sizeof sa.ss;          socklen_t salen = sizeof sa.ss;
Line 264  io_bridgeClient(sched_task_t *task) Line 290  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[0], 0, AIT_LEN(&s->sock_buf));
         AIT_SET_BUFSIZ(&cli->cli_buf[1], 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))) {                                  NULL, NULL, NULL))) {
                 case -1:                  case -1:
                         ELIBERR(io);                          ELIBERR(io);
                         break;                          break;
                 case 0:                  case 0:
                           cli->cli_pty = pty;
   
                         array_Args(cli->cli_cmdline, 0, " \t", &args);                          array_Args(cli->cli_cmdline, 0, " \t", &args);
                         argv = array_To(args);                          argv = array_To(args);
                         array_Destroy(&args);                          array_Destroy(&args);
   
   #if 0
                         printf("Console %s\n", cli->cli_name);                          printf("Console %s\n", cli->cli_name);
                        execv(*argv, argv);#endif
                         rlen = execv(*argv, argv);
                         _exit(rlen);
                         break;                          break;
                 default:                  default:
                           cli->cli_pty = pty;
                         cli->cli_pid = pid;                          cli->cli_pid = pid;
   
                         schedRead(TASK_ROOT(task), io_rxPty, cli, cli->cli_pty,                           schedRead(TASK_ROOT(task), io_rxPty, cli, cli->cli_pty, 
                                         TASK_ARG(task), 0);                                          TASK_ARG(task), 0);
                         schedRead(TASK_ROOT(task), io_rxNet, cli, cli->cli_fd,                           schedRead(TASK_ROOT(task), io_rxNet, cli, cli->cli_fd, 
                                         TASK_ARG(task), 0);                                          TASK_ARG(task), 0);
                        ioUpdTimerSocket(cli, NULL);                        ioUpdTimerSocket(cli);
                         break;                          break;
         }          }
 end:  end:
Line 292  end: Line 324  end:
         taskExit(task, NULL);          taskExit(task, NULL);
 }  }
   
   static void *
   io_bridgeClient2Pool(sched_task_t *task)
   {
           int c, rlen;
           sockaddr_t sa;
           socklen_t salen = sizeof sa.ss;
           sock_cli_t *cli = NULL;
           sock_t *s = (sock_t*) TASK_ARG(task);
   
           if (s->sock_type == SOCK_STREAM) {
                   if ((c = accept(TASK_FD(task), &sa.sa, &salen)) == -1) {
                           LOGERR;
                           goto end;
                   }
           } else {
                   if ((rlen = recvfrom(TASK_FD(task), 
                                                   AIT_GET_BUF(&s->sock_buf), AIT_LEN(&s->sock_buf), 
                                                   MSG_PEEK, &sa.sa, &salen)) == -1) {
                           LOGERR;
                           goto end;
                   } else
                           c = TASK_FD(task);
           }
   
           cli = e_malloc(sizeof(sock_cli_t));
           if (!cli) {
                   io_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                   if (s->sock_type == SOCK_STREAM)
                           close(c);
                   goto end;
           } else {
                   memset(cli, 0, sizeof(sock_cli_t));
                   pthread_mutex_lock(&s->sock_mtx);
                   TAILQ_INSERT_TAIL(&s->sock_cli, cli, cli_node);
                   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);
           strlcpy(cli->cli_cmdline, TASK_DATA(task), sizeof cli->cli_cmdline);
           memcpy(&cli->cli_addr, &sa, sizeof cli->cli_addr);
           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));
   
           schedRead(TASK_ROOT(task), io_rxPty, cli, cli->cli_pty, TASK_ARG(task), 0);
           schedRead(TASK_ROOT(task), io_rxNet, cli, cli->cli_fd, TASK_ARG(task), 0);
           ioUpdTimerSocket(cli);
   end:
           schedReadSelf(task);
           taskExit(task, NULL);
   }
   
   
 /*  /*
  * ioInitSocket() - Init socket and allocate resources   * ioInitSocket() - Init socket and allocate resources
  *   *
Line 406  ioCloseSocket(sock_t ** __restrict s) Line 493  ioCloseSocket(sock_t ** __restrict s)
                         AIT_FREE_VAL(&cli->cli_buf[0]);                          AIT_FREE_VAL(&cli->cli_buf[0]);
   
                         if (cli->cli_pid > 0) {                          if (cli->cli_pid > 0) {
                                kill(cli->cli_pid, SIGTERM);                                kill(cli->cli_pid, SIGKILL);
                                 while (waitpid(cli->cli_pid, &stat, WNOHANG) > 0) {                                  while (waitpid(cli->cli_pid, &stat, WNOHANG) > 0) {
                                         usleep(1000);                                          usleep(1000);
                                        kill(cli->cli_pid, SIGTERM);                                        kill(cli->cli_pid, SIGKILL);
                                 }                                  }
                         }                          }
   
Line 486  ioUpSocket(sock_t * __restrict s, void *arg, int timeo Line 573  ioUpSocket(sock_t * __restrict s, void *arg, int timeo
  * ioUpdTimerSocket() - Update timeout of socket   * ioUpdTimerSocket() - Update timeout of socket
  *   *
  * @c = Client socket   * @c = Client socket
  * @arg = Optional data argument  
  * return:  none   * return:  none
  */   */
 void  void
ioUpdTimerSocket(sock_cli_t * __restrict c, void *arg)ioUpdTimerSocket(sock_cli_t * __restrict c)
 {  {
         sock_t *s;          sock_t *s;
   
Line 499  ioUpdTimerSocket(sock_cli_t * __restrict c, void *arg) Line 585  ioUpdTimerSocket(sock_cli_t * __restrict c, void *arg)
         else          else
                 s = c->cli_parent;                  s = c->cli_parent;
   
        schedCancelby(s->sock_root, taskTIMER, CRITERIA_DATLEN, (void*) c->cli_fd, NULL);        if (s->sock_prog)
        schedTimer(s->sock_root, io_closeClient, c, s->sock_timeout, arg, c->cli_fd);                io_progCheck(s->sock_prog, 42);
 
         schedCancelby(s->sock_root, taskTIMER, CRITERIA_ARG, c, NULL);
         schedTimer(s->sock_root, io_closeClient, c, s->sock_timeout, NULL, 0);
 }  }
   
 /*  /*
Line 519  ioCloseClient(sock_cli_t * __restrict c) Line 608  ioCloseClient(sock_cli_t * __restrict c)
         else          else
                 s = c->cli_parent;                  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);
 }  }
   
 /*  /*
Line 539  ioLoopSocket(sock_t * __restrict s, sched_task_func_t  Line 628  ioLoopSocket(sock_t * __restrict s, sched_task_func_t 
         return schedRun(s->sock_root, &s->sock_kill);          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   * ioBridgeProg2Socket() - Start socket scheduler and bridge program to socket
  *   *
Line 552  ioBridgeProg2Socket(sock_t * __restrict s, const char  Line 653  ioBridgeProg2Socket(sock_t * __restrict s, const char 
         if (!s || !prgname || s->sock_kill)          if (!s || !prgname || s->sock_kill)
                 return -1;                  return -1;
   
        schedRead(s->sock_root, 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);          return schedRun(s->sock_root, &s->sock_kill);
   }
   
   /*
    * ioSetupProg2Socket() - Setup program pool to socket server
    *
    * @s = Socket
    * @p = Program pool
    * return: -1 error or 0 ok
    */
   int
   ioSetupProg2Socket(sock_t * __restrict s, prog_t * __restrict p)
   {
           if (!s)
                   return -1;
   
           s->sock_prog = p;
           return 0;
 }  }

Removed from v.1.5  
changed lines
  Added in v.1.14


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>