Changeset 336

Show
Ignore:
Timestamp:
05/30/07 22:04:54 (2 years ago)
Author:
blackhedd
Message:

provisional implementation of EventMachine#popen

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • version_0/ext/cmain.cpp

    r325 r336  
    291291} 
    292292 
     293 
     294/********** 
     295evma_popen 
     296**********/ 
     297 
     298extern "C" const char *evma_popen (const char *cmd, const char *mode) 
     299{ 
     300        if (!EventMachine) 
     301                throw std::runtime_error ("not initialized"); 
     302        return EventMachine->Popen (cmd, mode); 
     303} 
     304 
     305 
     306 
  • version_0/ext/ed.h

    r325 r336  
    227227}; 
    228228 
     229/******************** 
     230class PipeDescriptor 
     231********************/ 
     232 
     233class PipeDescriptor: public EventableDescriptor 
     234{ 
     235        public: 
     236                PipeDescriptor (FILE*); 
     237                virtual ~PipeDescriptor(); 
     238 
     239                virtual void Read(); 
     240                virtual void Write(); 
     241                virtual void Heartbeat(); 
     242 
     243                virtual bool SelectForRead(); 
     244                virtual bool SelectForWrite(); 
     245 
     246        protected: 
     247                EventMachine_t *MyEventMachine; 
     248}; 
     249 
    229250 
    230251 
  • version_0/ext/em.cpp

    r334 r336  
    10341034 
    10351035 
     1036/********************* 
     1037EventMachine_t::Popen 
     1038*********************/ 
     1039 
     1040const char *EventMachine_t::Popen (const char *cmd, const char *mode) 
     1041{ 
     1042        #ifdef OS_WIN32 
     1043        throw std::runtime_error ("popen is currently unavailable on this platform"); 
     1044        #endif 
     1045 
     1046        // The whole rest of this function is only compiled on Unix systems. 
     1047        // Eventually we need this functionality (or a full-duplex equivalent) on Windows. 
     1048        #ifdef OS_UNIX 
     1049        const char *output_binding = NULL; 
     1050 
     1051        FILE *fp = popen (cmd, mode); 
     1052        if (!fp) 
     1053                return NULL; 
     1054 
     1055        // From here, all early returns must pclose the stream. 
     1056 
     1057        // According to the pipe(2) manpage, descriptors returned from pipe have both 
     1058        // CLOEXEC and NONBLOCK clear. Do NOT set CLOEXEC. DO set nonblocking. 
     1059        if (!SetSocketNonblocking (fileno (fp))) { 
     1060                pclose (fp); 
     1061                return NULL; 
     1062        } 
     1063 
     1064        { // Looking good. 
     1065                PipeDescriptor *pd = new PipeDescriptor (fp); 
     1066                if (!pd) 
     1067                        throw std::runtime_error ("unable to allocate pipe"); 
     1068                Add (pd); 
     1069                output_binding = pd->GetBinding().c_str(); 
     1070        } 
     1071 
     1072        return output_binding; 
     1073        #endif 
     1074} 
     1075 
     1076 
     1077 
    10361078//#endif // OS_UNIX 
    10371079 
  • version_0/ext/em.h

    r334 r336  
    7171                const char *CreateUnixDomainServer (const char*); 
    7272                const char *_OpenFileForWriting (const char*); 
     73                const char *Popen (const char*, const char*); 
    7374 
    7475                void Add (EventableDescriptor*); 
  • version_0/ext/eventmachine.h

    r334 r336  
    5656 
    5757        const char *evma__write_file (const char *filename); 
     58        const char *evma_popen (const char *cmd, const char *mode); 
    5859 
    5960#if __cplusplus 
  • version_0/ext/rubymain.cpp

    r325 r336  
    303303        if (!f || !*f) 
    304304                rb_raise (rb_eRuntimeError, "file not opened"); 
     305        return rb_str_new2 (f); 
     306} 
     307 
     308/************** 
     309t_invoke_popen 
     310**************/ 
     311 
     312static VALUE t_invoke_popen (VALUE self, VALUE cmd, VALUE mode) 
     313{ 
     314        const char *f = evma_popen (StringValuePtr(cmd), StringValuePtr(mode)); 
     315        if (!f || !*f) { 
     316                char *err = strerror (errno); 
     317                char buf[100]; 
     318                memset (buf, 0, sizeof(buf)); 
     319                snprintf (buf, sizeof(buf)-1, "no popen: %s", (err?err:"???")); 
     320                rb_raise (rb_eRuntimeError, buf); 
     321        } 
    305322        return rb_str_new2 (f); 
    306323} 
     
    336353        rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1); 
    337354        rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1); 
     355        rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 2); 
    338356 
    339357  // Provisional: 
  • version_0/lib/eventmachine.rb

    r326 r336  
    816816  end 
    817817 
     818  #-- 
     819  # 
     820  def self::popen cmd, mode="r" 
     821          EventMachine::invoke_popen cmd, mode 
     822  end 
    818823 
    819824  private