basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : posix_port.cpp 00004 * DESCRIPTION: Ports from file descriptors 00005 * COPYRIGHT : (C) 2010 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #include <basix/posix_port.hpp> 00014 #include <sys/types.h> 00015 #include <sys/select.h> 00016 #include <sys/wait.h> 00017 #include <unistd.h> 00018 00020 00021 namespace mmx { 00022 00023 /****************************************************************************** 00024 * Constructor and destructor 00025 ******************************************************************************/ 00026 00027 extern table<int,int> out_count; 00028 extern table<int,int> in_count; 00029 00030 posix_port_rep::posix_port_rep (int kind2, int fd2): 00031 kind (kind2), fd (fd2), 00032 buffer (""), pos (0), alive (true) 00033 { 00034 if ((kind & 1) != 0) out_count[fd]= out_count[fd] + 1; 00035 if ((kind & 2) != 0) in_count [fd]= in_count [fd] + 1; 00036 } 00037 00038 posix_port_rep::~posix_port_rep () { 00039 if ((kind & 1) != 0) { 00040 out_count[fd]= out_count[fd] - 1; 00041 if (out_count[fd] == 0) reset (out_count, fd); 00042 } 00043 if ((kind & 2) != 0) { 00044 in_count [fd]= in_count [fd] - 1; 00045 if (in_count[fd] == 0) reset (in_count, fd); 00046 } 00047 } 00048 00049 /****************************************************************************** 00050 * Default reimplementations of virtual routines 00051 ******************************************************************************/ 00052 00053 void 00054 posix_port_rep::send (const char* s, nat n) { 00055 if (alive) { 00056 int err= ::write (fd, s, n); 00057 (void) err; 00058 } 00059 } 00060 00061 void 00062 posix_port_rep::feed () { 00063 while (alive && wait (0)) { 00064 int r; 00065 char tempout[1024]; 00066 r = ::read (fd, tempout, 1024); 00067 if (r == -1) { 00068 ::wait (NULL); 00069 ERROR ("read failed"); 00070 } 00071 else if (r == 0) alive= false; 00072 else buffer << string (tempout, r); 00073 } 00074 } 00075 00076 bool 00077 posix_port_rep::wait (int msecs) { 00078 //mmout << "Wait " << msecs << " ms on " << expression () << "\n"; 00079 if ((kind & 2) == 0 || !alive) return false; 00080 fd_set in_fds; 00081 FD_ZERO (&in_fds); 00082 FD_SET (fd, &in_fds); 00083 00084 nat nr; 00085 struct timeval tv; 00086 tv.tv_sec = msecs / 1000; 00087 tv.tv_usec = 1000 * (msecs % 1000); 00088 if (msecs < 0) nr= select (fd + 1, &in_fds, NULL, NULL, NULL); 00089 else nr= select (fd + 1, &in_fds, NULL, NULL, &tv); 00090 //mmout << "Received " << nr << " on " << fd << "\n"; 00091 return nr > 0; 00092 } 00093 00094 /****************************************************************************** 00095 * Global select 00096 ******************************************************************************/ 00097 00098 nat 00099 wait_port_event (int msecs) { 00100 //mmout << "Global wait " << msecs << " ms\n"; 00101 int max_fd= 0; 00102 00103 fd_set in_fds; 00104 FD_ZERO (&in_fds); 00105 for (iterator<int> it= entries (in_count); busy (it); ++it) { 00106 //mmout << " Setting " << (*it) << "\n"; 00107 FD_SET (*it, &in_fds); 00108 max_fd= max (max_fd, (*it) + 1); 00109 } 00110 00111 nat nr; 00112 struct timeval tv; 00113 tv.tv_sec = msecs / 1000; 00114 tv.tv_usec = 1000 * (msecs % 1000); 00115 if (msecs < 0) nr= select (max_fd, &in_fds, NULL, NULL, NULL); 00116 else nr= select (max_fd, &in_fds, NULL, NULL, &tv); 00117 //mmout << "Received " << nr << "\n"; 00118 return nr; 00119 } 00120 00121 } // namespace mmx