00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 static pid_t initialised;
00033 static int select_pipe[2];
00034 static VOLATILE unsigned pipe_written, pipe_read;
00035
00036
00037
00038
00039
00040
00041 void sys_select_signal(char c)
00042 {
00043 if (!initialised) return;
00044
00045 if (pipe_written > pipe_read+256) return;
00046
00047 if (write(select_pipe[1], &c, 1) == 1) pipe_written++;
00048 }
00049
00050
00051
00052
00053
00054
00055
00056 int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
00057 {
00058 int ret, saved_errno;
00059 fd_set *readfds2, readfds_buf;
00060
00061 if (initialised != sys_getpid()) {
00062 pipe(select_pipe);
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 if(set_blocking(select_pipe[0],0)==-1)
00074 smb_panic("select_pipe[0]: O_NONBLOCK failed.\n");
00075 if(set_blocking(select_pipe[1],0)==-1)
00076 smb_panic("select_pipe[1]: O_NONBLOCK failed.\n");
00077
00078 initialised = sys_getpid();
00079 }
00080
00081 maxfd = MAX(select_pipe[0]+1, maxfd);
00082
00083
00084 if (readfds) {
00085 readfds2 = readfds;
00086 } else {
00087 readfds2 = &readfds_buf;
00088 FD_ZERO(readfds2);
00089 }
00090 FD_SET(select_pipe[0], readfds2);
00091
00092 errno = 0;
00093 ret = select(maxfd,readfds2,writefds,errorfds,tval);
00094
00095 if (ret <= 0) {
00096 FD_ZERO(readfds2);
00097 if (writefds)
00098 FD_ZERO(writefds);
00099 if (errorfds)
00100 FD_ZERO(errorfds);
00101 } else if (FD_ISSET(select_pipe[0], readfds2)) {
00102 char c;
00103 saved_errno = errno;
00104 if (read(select_pipe[0], &c, 1) == 1) {
00105 pipe_read++;
00106
00107
00108
00109
00110
00111
00112 ret = -1;
00113 #if 0
00114
00115 DEBUG(0,("select got %u signal\n", (unsigned int)c));
00116 #endif
00117 errno = EINTR;
00118 } else {
00119 FD_CLR(select_pipe[0], readfds2);
00120 ret--;
00121 errno = saved_errno;
00122 }
00123 }
00124
00125 return ret;
00126 }
00127
00128
00129
00130
00131
00132
00133 int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
00134 {
00135 int ret;
00136 fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf;
00137 struct timeval tval2, *ptval, end_time;
00138
00139 readfds2 = (readfds ? &readfds_buf : NULL);
00140 writefds2 = (writefds ? &writefds_buf : NULL);
00141 errorfds2 = (errorfds ? &errorfds_buf : NULL);
00142 if (tval) {
00143 GetTimeOfDay(&end_time);
00144 end_time.tv_sec += tval->tv_sec;
00145 end_time.tv_usec += tval->tv_usec;
00146 end_time.tv_sec += end_time.tv_usec / 1000000;
00147 end_time.tv_usec %= 1000000;
00148 errno = 0;
00149 tval2 = *tval;
00150 ptval = &tval2;
00151 } else {
00152 ptval = NULL;
00153 }
00154
00155 do {
00156 if (readfds)
00157 readfds_buf = *readfds;
00158 if (writefds)
00159 writefds_buf = *writefds;
00160 if (errorfds)
00161 errorfds_buf = *errorfds;
00162 if (ptval && (errno == EINTR)) {
00163 struct timeval now_time;
00164 SMB_BIG_INT tdif;
00165
00166 GetTimeOfDay(&now_time);
00167 tdif = usec_time_diff(&end_time, &now_time);
00168 if (tdif <= 0) {
00169 ret = 0;
00170 break;
00171 }
00172 ptval->tv_sec = tdif / 1000000;
00173 ptval->tv_usec = tdif % 1000000;
00174 }
00175
00176
00177
00178
00179
00180
00181 ret = select(maxfd, readfds2, writefds2, errorfds2, ptval);
00182 } while (ret == -1 && errno == EINTR);
00183
00184 if (readfds)
00185 *readfds = readfds_buf;
00186 if (writefds)
00187 *writefds = writefds_buf;
00188 if (errorfds)
00189 *errorfds = errorfds_buf;
00190
00191 return ret;
00192 }