Changeset 381

Show
Ignore:
Timestamp:
06/12/07 12:33:40 (2 years ago)
Author:
blackhedd
Message:

converted popen to work with a socketpair instead of a half-duplex pipe. Argument parsing is still not done.

Files:

Legend:

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

    r361 r381  
    299299**********/ 
    300300 
    301 extern "C" const char *evma_popen (const char *cmd, const char *mode
    302 { 
    303         if (!EventMachine) 
    304                 throw std::runtime_error ("not initialized"); 
    305         return EventMachine->Popen (cmd, mode); 
     301extern "C" const char *evma_popen (const char *cmd
     302{ 
     303        if (!EventMachine) 
     304                throw std::runtime_error ("not initialized"); 
     305        return EventMachine->Socketpair (cmd); 
    306306} 
    307307 
  • version_0/ext/ed.cpp

    r377 r381  
    11691169int ConnectionDescriptor::GetCommInactivityTimeout (int *value) 
    11701170{ 
     1171        if (value) { 
     1172                *value = InactivityTimeout; 
     1173                return 1; 
     1174        } 
     1175        else { 
     1176                // TODO, extended logging, got bad parameter. 
     1177                return 0;   
     1178        } 
     1179} 
     1180 
     1181 
     1182/********************************************** 
     1183ConnectionDescriptor::SetCommInactivityTimeout 
     1184**********************************************/ 
     1185 
     1186int ConnectionDescriptor::SetCommInactivityTimeout (int *value) 
     1187{ 
     1188        int out = 0; 
     1189 
     1190        if (value) { 
     1191                if ((*value==0) || (*value >= 2)) { 
     1192                        // Replace the value and send the old one back to the caller. 
     1193                        int v = *value; 
     1194                        *value = InactivityTimeout; 
     1195                        InactivityTimeout = v; 
     1196                        out = 1; 
     1197                } 
     1198                else { 
     1199                        // TODO, extended logging, got bad value. 
     1200                } 
     1201        } 
     1202        else { 
     1203                // TODO, extended logging, got bad parameter. 
     1204        } 
     1205 
     1206        return out; 
     1207} 
     1208 
     1209/******************************* 
     1210DatagramDescriptor::GetPeername 
     1211*******************************/ 
     1212 
     1213bool DatagramDescriptor::GetPeername (struct sockaddr *s) 
     1214{ 
     1215        bool ok = false; 
     1216        if (s) { 
     1217                memset (s, 0, sizeof(struct sockaddr)); 
     1218                memcpy (s, &ReturnAddress, sizeof(ReturnAddress)); 
     1219                ok = true; 
     1220        } 
     1221        return ok; 
     1222} 
     1223 
     1224 
     1225 
     1226/******************************************** 
     1227DatagramDescriptor::GetCommInactivityTimeout 
     1228********************************************/ 
     1229 
     1230int DatagramDescriptor::GetCommInactivityTimeout (int *value) 
     1231{ 
    11711232  if (value) { 
    11721233    *value = InactivityTimeout; 
     
    11791240} 
    11801241 
    1181  
    1182 /********************************************** 
    1183 ConnectionDescriptor::SetCommInactivityTimeout 
    1184 **********************************************/ 
    1185  
    1186 int ConnectionDescriptor::SetCommInactivityTimeout (int *value) 
     1242/******************************************** 
     1243DatagramDescriptor::SetCommInactivityTimeout 
     1244********************************************/ 
     1245 
     1246int DatagramDescriptor::SetCommInactivityTimeout (int *value) 
    11871247{ 
    11881248  int out = 0; 
     
    12071267} 
    12081268 
    1209 /******************************* 
    1210 DatagramDescriptor::GetPeername 
    1211 *******************************/ 
    1212  
    1213 bool DatagramDescriptor::GetPeername (struct sockaddr *s) 
    1214 { 
    1215         bool ok = false; 
    1216         if (s) { 
    1217                 memset (s, 0, sizeof(struct sockaddr)); 
    1218                 memcpy (s, &ReturnAddress, sizeof(ReturnAddress)); 
    1219                 ok = true; 
    1220         } 
    1221         return ok; 
    1222 } 
    1223  
    1224  
    1225  
    1226 /******************************************** 
    1227 DatagramDescriptor::GetCommInactivityTimeout 
    1228 ********************************************/ 
    1229  
    1230 int DatagramDescriptor::GetCommInactivityTimeout (int *value) 
    1231 { 
    1232   if (value) { 
    1233     *value = InactivityTimeout; 
    1234     return 1; 
    1235   } 
    1236   else { 
    1237     // TODO, extended logging, got bad parameter. 
    1238     return 0;   
    1239   } 
    1240 } 
    1241  
    1242 /******************************************** 
    1243 DatagramDescriptor::SetCommInactivityTimeout 
    1244 ********************************************/ 
    1245  
    1246 int DatagramDescriptor::SetCommInactivityTimeout (int *value) 
    1247 { 
    1248   int out = 0; 
    1249  
    1250   if (value) { 
    1251     if ((*value==0) || (*value >= 2)) { 
    1252       // Replace the value and send the old one back to the caller. 
    1253       int v = *value; 
    1254       *value = InactivityTimeout; 
    1255       InactivityTimeout = v; 
    1256       out = 1; 
    1257     } 
    1258     else { 
    1259       // TODO, extended logging, got bad value. 
    1260     } 
    1261   } 
    1262   else { 
    1263     // TODO, extended logging, got bad parameter. 
    1264   } 
    1265  
    1266   return out; 
    1267 } 
    1268  
  • version_0/ext/ed.h

    r377 r381  
    6363 
    6464                virtual bool GetPeername (struct sockaddr*) {return false;} 
     65                virtual bool GetSubprocessPid (pid_t*) {return false;} 
    6566 
    6667                virtual void StartTls() {} 
     
    264265{ 
    265266        public: 
    266                 PipeDescriptor (FILE*, EventMachine_t*); 
     267                PipeDescriptor (FILE*, pid_t, EventMachine_t*); 
    267268                virtual ~PipeDescriptor(); 
    268269 
     
    276277                int SendOutboundData (const char*, int); 
    277278                virtual int GetOutboundDataSize() {return OutboundDataSize;} 
     279 
     280                virtual bool GetSubprocessPid (pid_t*); 
    278281 
    279282        protected: 
     
    295298                int OutboundDataSize; 
    296299 
     300                pid_t SubprocessPid; 
     301 
    297302        private: 
    298303                void _DispatchInboundData (const char *buffer, int size); 
  • version_0/ext/em.cpp

    r379 r381  
    12961296EventMachine_t::Popen 
    12971297*********************/ 
    1298  
     1298#if OBSOLETE 
    12991299const char *EventMachine_t::Popen (const char *cmd, const char *mode) 
    13001300{ 
     
    13321332        #endif 
    13331333} 
     1334#endif // OBSOLETE 
     1335 
     1336/************************** 
     1337EventMachine_t::Socketpair 
     1338**************************/ 
     1339 
     1340const char *EventMachine_t::Socketpair (const char *cmd) 
     1341{ 
     1342        #ifdef OS_WIN32 
     1343        throw std::runtime_error ("socketpair is currently unavailable on this platform"); 
     1344        #endif 
     1345 
     1346        // The whole rest of this function is only compiled on Unix systems. 
     1347        // Eventually we need this functionality (or a full-duplex equivalent) on Windows. 
     1348        #ifdef OS_UNIX 
     1349        const char *output_binding = NULL; 
     1350 
     1351        int sv[2]; 
     1352        if (socketpair (AF_LOCAL, SOCK_STREAM, 0, sv) < 0) 
     1353                return NULL; 
     1354        // from here, all early returns must close the pair of sockets. 
     1355 
     1356        // Set the socketpair nonblocking. Obviously DON'T set CLOEXEC. 
     1357        if (!SetSocketNonblocking (sv[0]) || !SetSocketNonblocking (sv[1])) { 
     1358                close (sv[0]); 
     1359                close (sv[1]); 
     1360                return NULL; 
     1361        } 
     1362 
     1363        pid_t f = fork(); 
     1364        if (f > 0) { 
     1365                close (sv[1]); 
     1366                PipeDescriptor *pd = new PipeDescriptor (fdopen(sv[0], "r+"), f, this); 
     1367                if (!pd) 
     1368                        throw std::runtime_error ("unable to allocate pipe"); 
     1369                Add (pd); 
     1370                output_binding = pd->GetBinding().c_str(); 
     1371        } 
     1372        else if (f == 0) { 
     1373                close (sv[0]); 
     1374                close (0); 
     1375                dup2 (sv[1], STDIN_FILENO); 
     1376                close (sv[1]); 
     1377                dup2 (STDIN_FILENO, STDOUT_FILENO); 
     1378                execlp ("ls", "ls", "-l", (char*)NULL); 
     1379                exit (-1); // end the child process if the exec doesn't work. 
     1380        } 
     1381        else 
     1382                throw std::runtime_error ("no fork"); 
     1383 
     1384        return output_binding; 
     1385        #endif 
     1386} 
    13341387 
    13351388 
  • version_0/ext/em.h

    r373 r381  
    7272                const char *_OpenFileForWriting (const char*); 
    7373                const char *Popen (const char*, const char*); 
     74                const char *Socketpair (const char*); 
    7475 
    7576                void Add (EventableDescriptor*); 
  • version_0/ext/eventmachine.h

    r362 r381  
    5858 
    5959        const char *evma__write_file (const char *filename); 
    60         const char *evma_popen (const char *cmd, const char *mode); 
     60        const char *evma_popen (const char *cmd); 
    6161 
    6262        int evma_set_rlimit_nofile (int n_files); 
  • version_0/ext/pipe.cpp

    r376 r381  
    2525******************************/ 
    2626 
    27 PipeDescriptor::PipeDescriptor (FILE *fp, EventMachine_t *parent_em): 
     27PipeDescriptor::PipeDescriptor (FILE *fp, pid_t subpid, EventMachine_t *parent_em): 
    2828        EventableDescriptor (fileno (fp), parent_em), 
    2929        bReadAttemptedAfterClose (false), 
     
    3131        InactivityTimeout (0), 
    3232        MyStream (fp), 
    33         OutboundDataSize (0) 
    34 
    35 
     33        OutboundDataSize (0), 
     34        SubprocessPid (subpid) 
     35
     36        #ifdef HAVE_EPOLL 
     37        EpollEvent.events = EPOLLIN; 
     38        #endif 
     39
     40 
    3641 
    3742/******************************* 
     
    188193                        OutboundPages.push_front (OutboundPage (buffer, len)); 
    189194                } 
     195                #ifdef HAVE_EPOLL 
     196                EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0)); 
     197                assert (MyEventMachine); 
     198                MyEventMachine->Modify (this); 
     199                #endif 
    190200        } 
    191201        else { 
     
    243253 
    244254 
    245 /********************************* 
     255/******************************** 
    246256PipeDescriptor::SendOutboundData 
    247257********************************/ 
     
    262272        OutboundPages.push_back (OutboundPage (buffer, length)); 
    263273        OutboundDataSize += length; 
     274        #ifdef HAVE_EPOLL 
     275        EpollEvent.events = (EPOLLIN | EPOLLOUT); 
     276        assert (MyEventMachine); 
     277        MyEventMachine->Modify (this); 
     278        #endif 
    264279        return length; 
    265280} 
    266281 
     282/******************************** 
     283PipeDescriptor::GetSubprocessPid 
     284********************************/ 
     285 
     286bool PipeDescriptor::GetSubprocessPid (pid_t *pid) 
     287{ 
     288        bool ok = false; 
     289        if (pid && (SubprocessPid > 0)) { 
     290                *pid = SubprocessPid; 
     291                ok = true; 
     292        } 
     293        return ok; 
     294} 
     295 
  • version_0/ext/rubymain.cpp

    r364 r381  
    313313**************/ 
    314314 
    315 static VALUE t_invoke_popen (VALUE self, VALUE cmd, VALUE mode
    316 { 
    317         const char *f = evma_popen (StringValuePtr(cmd), StringValuePtr(mode)); 
     315static VALUE t_invoke_popen (VALUE self, VALUE cmd
     316{ 
     317        const char *f = evma_popen (StringValuePtr(cmd)); 
    318318        if (!f || !*f) { 
    319319                char *err = strerror (errno); 
     
    399399        rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1); 
    400400        rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1); 
    401         rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 2); 
     401        rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1); 
    402402 
    403403        // Provisional: 
  • version_0/lib/eventmachine.rb

    r373 r381  
    898898        #-- 
    899899        # 
    900         def self::popen cmd, mode="r", handler=nil 
     900        def self::popen cmd, handler=nil 
    901901                klass = if (handler and handler.is_a?(Class)) 
    902902                        handler 
     
    905905                end 
    906906 
    907                 s = invoke_popen cmd, mode 
     907                s = invoke_popen cmd 
    908908                c = klass.new s 
    909909                @conns[s] = c