root/examples/libsmbclient/smbwrapper/select.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_select
  2. sys_select_intr

   1 /* 
   2    Unix SMB/Netbios implementation.
   3    Version 3.0
   4    Samba select/poll implementation
   5    Copyright (C) Andrew Tridgell 1992-1998
   6    Copyright (C) Derrell Lipman 2003-2005
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 /*
  23  * WHY THIS FILE?
  24  *
  25  * This file implements the two functions in the select() family, as required
  26  * by samba.  The samba native functions, though, implement a pipe to help
  27  * alleviate a deadlock problem, but which creates problems of its own (the
  28  * timeout stops working correctly).  Those functions also require that all
  29  * signal handlers call a function which writes to the pipe -- a task which is
  30  * difficult to do in the smbwrapper environment.
  31  */
  32 
  33 
  34 #include <sys/select.h>
  35 #include <errno.h>
  36 #include <stdio.h>
  37 
  38 int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
     /* [<][>][^][v][top][bottom][index][help] */
  39 {
  40         int ret;
  41         fd_set *readfds2, readfds_buf;
  42 
  43         /* If readfds is NULL we need to provide our own set. */
  44         if (readfds) {
  45                 readfds2 = readfds;
  46         } else {
  47                 readfds2 = &readfds_buf;
  48                 FD_ZERO(readfds2);
  49         }
  50 
  51         errno = 0;
  52         ret = select(maxfd,readfds2,writefds,errorfds,tval);
  53 
  54         if (ret <= 0) {
  55                 FD_ZERO(readfds2);
  56                 if (writefds)
  57                         FD_ZERO(writefds);
  58                 if (errorfds)
  59                         FD_ZERO(errorfds);
  60         }
  61 
  62         return ret;
  63 }
  64 
  65 /*******************************************************************
  66  Similar to sys_select() but catch EINTR and continue.
  67  This is what sys_select() used to do in Samba.
  68 ********************************************************************/
  69 
  70 int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
     /* [<][>][^][v][top][bottom][index][help] */
  71 {
  72         int ret;
  73         fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf;
  74         struct timeval tval2, *ptval, end_time, now_time;
  75 
  76         readfds2 = (readfds ? &readfds_buf : NULL);
  77         writefds2 = (writefds ? &writefds_buf : NULL);
  78         errorfds2 = (errorfds ? &errorfds_buf : NULL);
  79         if (tval) {
  80                 gettimeofday(&end_time, NULL);
  81                 end_time.tv_sec += tval->tv_sec;
  82                 end_time.tv_usec += tval->tv_usec;
  83                 end_time.tv_sec += end_time.tv_usec / 1000000;
  84                 end_time.tv_usec %= 1000000;
  85                 ptval = &tval2;
  86         } else {
  87                 ptval = NULL;
  88         }
  89 
  90         do {
  91                 if (readfds)
  92                         readfds_buf = *readfds;
  93                 if (writefds)
  94                         writefds_buf = *writefds;
  95                 if (errorfds)
  96                         errorfds_buf = *errorfds;
  97                 if (tval) {
  98                         gettimeofday(&now_time, NULL);
  99                         tval2.tv_sec = end_time.tv_sec - now_time.tv_sec;
 100                         tval2.tv_usec = end_time.tv_usec - now_time.tv_usec;
 101                         if ((signed long) tval2.tv_usec < 0) {
 102                                 tval2.tv_usec += 1000000;
 103                                 tval2.tv_sec--;
 104                         }
 105                         if ((signed long) tval2.tv_sec < 0) {
 106                                 ret = 0;
 107                                 break;          /* time has already elapsed */
 108                         }
 109                 }
 110 
 111                 ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval);
 112         } while (ret == -1 && errno == EINTR);
 113 
 114         if (readfds)
 115                 *readfds = readfds_buf;
 116         if (writefds)
 117                 *writefds = writefds_buf;
 118         if (errorfds)
 119                 *errorfds = errorfds_buf;
 120 
 121         return ret;
 122 }

/* [<][>][^][v][top][bottom][index][help] */