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 }