00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #include <basix/posix_port.hpp>
00014 #include <basix/system.hpp>
00015 #include <fcntl.h>
00016 #include <unistd.h>
00017 #include <sys/types.h>
00018 
00019 #if defined(__MINGW__) || defined(__MINGW32__)
00020 #  include <stdio.h>
00021 #  include <share.h>
00022 #endif
00023 
00025 
00026 namespace mmx {
00027 
00028 
00029 
00030 
00031 
00032 static void
00033 get_lock (FILE* f, int kind) {
00034 #if !(defined(__MINGW__) || defined(__MINGW32__))
00035   struct flock fl;
00036   int fd= fileno (f);
00037   fl.l_type   = kind == 2? F_RDLCK: F_WRLCK;
00038   fl.l_whence = SEEK_SET;
00039   fl.l_start  = 0;
00040   fl.l_len    = 0;
00041   fl.l_pid    = getpid ();
00042   fcntl (fd, F_SETLKW, &fl);
00043   
00044 #endif
00045 }
00046 
00047 static void
00048 release_lock (FILE* f) {
00049 #if !(defined(__MINGW__) || defined(__MINGW32__))
00050   struct flock fl;
00051   int fd= fileno (f);
00052   fl.l_type   = F_UNLCK;
00053   fl.l_whence = SEEK_SET;
00054   fl.l_start  = 0;
00055   fl.l_len    = 0;
00056   fl.l_pid    = getpid ();
00057   fcntl (fd, F_SETLK, &fl);
00058   
00059 #endif
00060 }
00061 
00062 
00063 
00064 
00065 
00066 class file_port_rep: public posix_port_rep {
00067   FILE*  f;
00068   bool   cf;
00069   bool   lock;
00070   string name;
00071   int    next;
00072 
00073 public:
00074   syntactic expression () const {
00075     if (this->kind == 1) return syn ("output_file_port", syntactic (name));
00076     if (this->kind == 2) return syn ("input_file_port", syntactic (name));
00077     return syn ("input_output_file_port", syntactic (name));
00078   }
00079 
00080   bool busy () {
00081     if (this->kind == 2) return can_read () > 0;
00082     return true;
00083   }
00084   nat can_write () {
00085     if (this->kind == 2) return 0;
00086     return (nat) (-1);
00087   }
00088   nat can_read () {
00089     if (next != -1) return 1;
00090     if (this->kind == 1 || feof (f) != 0) return 0;
00091     next= fgetc (f);
00092     if (next != -1) return 1;
00093     return 0;
00094   }
00095 
00096   void write (const char* s, nat n) {
00097     for (nat i=0; i<n; i++) fputc (s[i], f); }
00098   void read (char* s, nat n) {
00099     if (next != -1 && n > 0) { s[0]= next; s++; n--; next= -1; }
00100     for (nat i=0; i<n; i++) s[i]= fgetc (f); }
00101 
00102   void flush () { fflush (f); }
00103 
00104 public:
00105   inline file_port_rep (int kind, FILE* f2, bool cf2, bool lock2,
00106                         const string& name2):
00107       posix_port_rep (kind, fileno (f2)),
00108       f (f2), cf (cf2), lock (lock2), name (name2), next (-1) {
00109     if (lock) get_lock (f, this->kind); }
00110   inline ~file_port_rep () {
00111     if (lock) release_lock (f);
00112     if (cf) fclose (f); }
00113 };
00114 
00115 static port
00116 output_file_port (FILE* f, bool close_flag, bool lock, const string& name) {
00117   return (port_rep*) new file_port_rep (1, f, close_flag, lock, name);
00118 }
00119 
00120 static port
00121 input_file_port (FILE* f, bool close_flag, bool lock, const string& name) {
00122   return (port_rep*) new file_port_rep (2, f, close_flag, lock, name);
00123 }
00124 
00125 static port
00126 input_output_file_port (FILE* f, bool cf, bool lock, const string& name) {
00127   return (port_rep*) new file_port_rep (3, f, cf, lock, name);
00128 }
00129 
00130 
00131 
00132 
00133 
00134 table<int,int> out_count (0);
00135 table<int,int> in_count  (0);
00136 
00137 port mmin = input_file_port (stdin , false, false, "mmin");
00138 port mmout= formatting_port (output_file_port (stdout, false, false, "mmout"));
00139 port mmerr= formatting_port (output_file_port (stderr, false, false, "mmerr"));
00140 
00141 port
00142 output_file_port (const string& name) {
00143   string name_s= decode_name (name);
00144   char* temp= as_charp (name_s);
00145 #if defined(__MINGW__) || defined(__MINGW32__)
00146   FILE* f= _fsopen (temp, "w", _SH_DENYRW);
00147 #else
00148   FILE* f= fopen (temp, "w");
00149 #endif
00150   free_charp (temp);
00151   if (f == NULL) return error_port ("file '" * name * "' not writable");
00152   return output_file_port (f, true, true, name);
00153 }
00154 
00155 port
00156 input_file_port (const string& name) {
00157   string name_s= decode_name (name);
00158   char* temp= as_charp (name_s);
00159 #if defined(__MINGW__) || defined(__MINGW32__)
00160   FILE* f= _fsopen (temp, "r", _SH_DENYWR);
00161 #else
00162   FILE* f= fopen (temp, "r");
00163 #endif
00164   free_charp (temp);
00165   if (f == NULL) return error_port ("file '" * name * "' not found");
00166   return input_file_port (f, true, true, name);
00167 }
00168 
00169 port
00170 input_output_file_port (const string& name) {
00171   string name_s= decode_name (name);
00172   char* temp= as_charp (name_s);
00173 #if defined(__MINGW__) || defined(__MINGW32__)
00174   FILE* f= _fsopen (temp, "w+", _SH_DENYRW);
00175 #else
00176   FILE* f= fopen (temp, "w+");
00177 #endif
00178   free_charp (temp);
00179   if (f == NULL) return error_port ("file '" * name * "' did not open");
00180   return input_output_file_port (f, true, true, name);
00181 }
00182 
00183 }