00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #if defined(__MINGW__) || defined(__MINGW32__)
00014 #  include <winsock.h>
00015 #  undef ERROR
00016 #else
00017 #  include <sys/select.h>
00018 #  include <sys/wait.h>
00019 #endif
00020 #include <sys/types.h>
00021 #include <unistd.h>
00022 #include <basix/posix_port.hpp>
00023 
00025 
00026 namespace mmx {
00027 
00028 
00029 
00030 
00031 
00032 extern table<int,int> out_count;
00033 extern table<int,int> in_count;
00034 
00035 posix_port_rep::posix_port_rep (int kind2, int fd2):
00036   kind (kind2), fd (fd2),
00037   buffer (""), pos (0), alive (true)
00038 {
00039   if ((kind & 1) != 0) out_count[fd]= out_count[fd] + 1;
00040   if ((kind & 2) != 0) in_count [fd]= in_count [fd] + 1;
00041 }
00042 
00043 posix_port_rep::~posix_port_rep () {
00044   if ((kind & 1) != 0) {
00045     out_count[fd]= out_count[fd] - 1;
00046     if (out_count[fd] == 0) reset (out_count, fd);
00047   }
00048   if ((kind & 2) != 0) {
00049     in_count [fd]= in_count [fd] - 1;
00050     if (in_count[fd] == 0) reset (in_count, fd);
00051   }
00052 }
00053 
00054 
00055 
00056 
00057 
00058 void
00059 posix_port_rep::send (const char* s, nat n) {
00060   if (alive) {
00061     int err= ::write (fd, s, n);
00062     (void) err;
00063   }
00064 }
00065 
00066 void
00067 posix_port_rep::feed () {
00068   while (alive && wait (0)) {
00069     int r;
00070     char tempout[1024];
00071     r = ::read (fd, tempout, 1024);
00072     if (r == -1) {
00073 #if defined(__MINGW__) || defined(__MINGW32__)
00074       _cwait (NULL, 0, _WAIT_CHILD);
00075 #else
00076       ::wait (NULL);
00077 #endif
00078       ERROR ("read failed");
00079     }
00080     else if (r == 0) alive= false;
00081     else buffer << string (tempout, r);
00082   }
00083 }
00084 
00085 bool
00086 posix_port_rep::wait (int msecs) {
00087   
00088   if ((kind & 2) == 0 || !alive) return false;
00089   fd_set in_fds;
00090   FD_ZERO (&in_fds);
00091   FD_SET (fd, &in_fds);
00092   
00093   nat nr;
00094   struct timeval tv;
00095   tv.tv_sec  = msecs / 1000;
00096   tv.tv_usec = 1000 * (msecs % 1000);
00097   if (msecs < 0) nr= select (fd + 1, &in_fds, NULL, NULL, NULL);
00098   else nr= select (fd + 1, &in_fds, NULL, NULL, &tv);
00099   
00100   return nr > 0;
00101 }
00102 
00103 
00104 
00105 
00106 
00107 nat
00108 wait_port_event (int msecs) {
00109   
00110   int max_fd= 0;
00111 
00112   fd_set in_fds;
00113   FD_ZERO (&in_fds);
00114   for (iterator<int> it= entries (in_count); busy (it); ++it) {
00115     
00116     FD_SET (*it, &in_fds);
00117     max_fd= max (max_fd, (*it) + 1);
00118   }
00119   
00120   nat nr;
00121   struct timeval tv;
00122   tv.tv_sec  = msecs / 1000;
00123   tv.tv_usec = 1000 * (msecs % 1000);
00124   if (msecs < 0) nr= select (max_fd, &in_fds, NULL, NULL, NULL);
00125   else nr= select (max_fd, &in_fds, NULL, NULL, &tv);
00126   
00127   return nr;
00128 }
00129 
00130 }