Fresco/Prague/src/IPC Agent.cc,1.10,1.11 Coprocess.cc,1.20,1.21 PipeAgent.cc,1.10,1.11 TTYAgent.cc,1.16,1.17 ptybuf.cc,1.19,1.20

Tobias Hunger <[email protected]> Thu, 06 Nov 2003 18:04:04 +0000
Newsgroups gmane.comp.video.fresco.cvs
Message-ID <[email protected]>
Update of /cvs/fresco/Fresco/Prague/src/IPC
In directory purcel:/tmp/cvs-serv25254/Prague/src/IPC

Modified Files:
	Agent.cc Coprocess.cc PipeAgent.cc TTYAgent.cc ptybuf.cc 
Log Message:
Throw std::runtime_error when something goes wrong creating a PTY/TTY.
This causes the TermDemo to fail gracefully instead of crashing,


Index: Agent.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Prague/src/IPC/Agent.cc,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- Agent.cc	31 Oct 2003 22:33:12 -0000	1.10
+++ Agent.cc	6 Nov 2003 18:04:01 -0000	1.11
@@ -27,7 +27,7 @@
 Agent::Agent() : _refcount(1), _iomask(none), _running(false) { }
 Agent::~Agent() { }
 
-void Agent::start()
+void Agent::start()  throw(std::runtime_error)
 {
     _running = true;
     if (_iomask & in && ibuf()) Dispatcher::instance()->bind(this, ibuf()->fd(), in);

Index: Coprocess.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Prague/src/IPC/Coprocess.cc,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- Coprocess.cc	3 Nov 2003 17:53:54 -0000	1.20
+++ Coprocess.cc	6 Nov 2003 18:04:01 -0000	1.21
@@ -106,7 +106,7 @@
     terminate();
 }
 
-void Coprocess::start()
+void Coprocess::start() throw(std::runtime_error)
 {
     Prague::Guard<Mutex> guard(_mutex);
     processes.push_back(this);

Index: PipeAgent.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Prague/src/IPC/PipeAgent.cc,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- PipeAgent.cc	31 Oct 2003 22:33:12 -0000	1.10
+++ PipeAgent.cc	6 Nov 2003 18:04:01 -0000	1.11
@@ -33,7 +33,7 @@
 
 PipeAgent::~PipeAgent() { shutdown(in|out|err); }
 
-void PipeAgent::start()
+void PipeAgent::start() throw(std::runtime_error)
 {
     if (_id >= 0)
     {

Index: TTYAgent.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Prague/src/IPC/TTYAgent.cc,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- TTYAgent.cc	31 Oct 2003 22:33:12 -0000	1.16
+++ TTYAgent.cc	6 Nov 2003 18:04:01 -0000	1.17
@@ -37,7 +37,7 @@
     shutdown(in|out|err);
 }
 
-void TTYAgent::start()
+void TTYAgent::start() throw(std::runtime_error)
 {
     Trace trace("TTYAgent::start");
     if (pid() >= 0)

Index: ptybuf.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Prague/src/IPC/ptybuf.cc,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- ptybuf.cc	31 Oct 2003 22:33:12 -0000	1.19
+++ ptybuf.cc	6 Nov 2003 18:04:01 -0000	1.20
@@ -1,9 +1,10 @@
 /*$Id$
  *
  * This source file is a part of the Fresco Project.
- * Copyright (C) 1999 Stefan Seefeld <[email protected]>
+ * Copyright (C) 1999 Stefan Seefeld <[email protected]>
  * Copyright (C) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
  * Copyright (C) 2001 Bastian Blank <[email protected]>
+ * Copyright (C) 2003 Tobias Hunger <[email protected]>
  * http://www.fresco.org
  *
  * This library is free software; you can redistribute it and/or
@@ -22,216 +23,208 @@
  * MA 02139, USA.
  */
 #include <Prague/IPC/ptybuf.hh>
-#include <cstdio>
 #include <cerrno>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <termios.h>
-#include <Prague/Sys/Thread.hh>
+#include <sstream>
+#include <iostream>
 
 using namespace Prague;
 
 #if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY)
-#undef HAVE_DEV_PTMX
+#  undef HAVE_DEV_PTMX
 #endif
 
 #ifdef HAVE_PTY_H
-# include <pty.h>
+#  include <pty.h>
 #endif
 #if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H)
-# include <sys/stropts.h>
+#  include <sys/stropts.h>
 #endif
 
 #if defined (HAVE_LIBUTIL_H)
-# include <libutil.h>
+#  include <libutil.h>
 #endif
 
+#if defined (HAVE_OPENPTY) || defined (BSD4_4)
+#elif defined (HAVE__GETPTY)
+#elif defined (HAVE_DEV_PTMX)
+#elif defined (HAVE_DEV_PTS_AND_PTC)
+#else
+#  include <fcntl.h>
+#endif
+
+inline void throw_runtime_error(const std::string s) throw(std::runtime_error)
+{
+    throw std::runtime_error(s + ": " + strerror(errno));
+}
+
 //inline char ctrl(char c) { return c & 0x1f;}
 
 ptybuf::ptybuf() :
-  ipcbuf(std::ios::in | std::ios::out),
-  tty(-1)
+  ipcbuf(std::ios::in | std::ios::out)
 { }
 
 ptybuf::~ptybuf()
 {
-    if (tty != -1)
-      close ( tty );
+    if (my_tty != -1)
+        close(my_tty);
 }
 
-std::streamsize ptybuf::sys_read(char *buf, std::streamsize len)
+std::streamsize ptybuf::sys_read(char *buf, std::streamsize len) throw(std::runtime_error)
 {
     std::streamsize rval = -1;
     do
         rval = ::read(fd(), buf, len);
     while (rval == -1 && errno == EINTR);
     if (rval == -1 && errno == EIO) return 0;
-    if (rval == -1 && errno != EAGAIN) perror("ptybuf::read");
-    return rval;
+    if (rval == -1 && errno != EAGAIN)
+        throw_runtime_error("ptybuf::read failed");
 }
 
-int ptybuf::openpty()
+int ptybuf::openpty() throw (std::runtime_error)
 {
-    if (tty == -1)
-        setup();
+    if (fd() == -1)
+      setup();
     return fd();
 }
 
-int ptybuf::opentty()
+int ptybuf::opentty() throw (std::runtime_error)
 {
-    if (tty == -1)
+    if (my_tty == -1)
         setup();
-    return tty;
+    return my_tty;
 }
 
-void ptybuf::setup()
+void ptybuf::setup() throw (std::runtime_error)
 {
     int ttyfd;
     int ptyfd;
 
+    std::cerr << "Trying to open PTY/TTY pair..." << std::endl;
+
 #if defined(HAVE_OPENPTY) || defined(BSD4_4)
-    /* openpty(3) exists in OSF/1 and some other os'es */
-    if ()::openpty(&ptyfd, &ttyfd, NULL, NULL, NULL) < 0);
-    {
-        perror("openpty");
-        return;
-    }
+    // openpty(3) exists in OSF/1 and some other os'es
+    std::cerr << "  using openpty." << std::endl;
+    int i;
+
+    i = ::openpty(&ptyfd, &ttyfd, NULL, NULL, NULL);
+    if (i < 0) throw_runtime_error("Openpty failed");
 
     fd(ptyfd);
-    tty = ttyfd;
-    ptydev = ttyname(ptyfd);
+    my_tty = ttyfd;
+    my_ptydev = ttyname(ptyfd);
 #elif defined(HAVE__GETPTY)
-    /*
-     * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
-     * pty's automagically when needed
-     */
+    // _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
+    // pty's automagically when needed
+    std::cerr << "  using _getpty." << std::endl;
 
     char *name = _getpty(&ptyfd, O_RDWR, 0622, 0);
-    if (!name)
-    {
-        perror("_getpty");
-        return;
-    }
+    if (!name) throw_runtime_error("_getpty failed")
 
     // Open the slave side.
     ttyfd = open(name, O_RDWR | O_NOCTTY);
-    if (ttyfd < 0)
-    {
-        perror(name);
-        close(ptyfd);
-        return;
-    }
+    if (ttyfd < 0) throw_runtime_error("Failed to open");
 
     fd(ptyfd);
-    tty = ttyfd;
+    my_tty = ttyfd;
     ptydev = name;
 #elif defined(HAVE_DEV_PTMX)
     /*
      * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
      * also has bsd-style ptys, but they simply do not work.)
      */
-    int ptm;
+    std::cerr << "  using ptmx." << std::endl;
+
     mysig_t old_signal;
     char *name;
 
     ptyfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
-    if (ptyfd < 0)
-    {
-        perror("/dev/ptmx");
-        return;
-    }
+    if (ptyfd < 0) throw_runtime_error("Failed to open /dev/ptmx");
 
     old_signal = mysignal(SIGCHLD, SIG_DFL);
 
     if (grantpt(ptyfd) < 0)
     {
-        perror("grantpt");
-        return;
+        close(ptyfd);
+        throw_runtime_error("grantpt failed");
     }
 
     mysignal(SIGCHLD, old_signal);
 
     if (unlockpt(ptyfd) < 0)
     {
-        perror("unlockpt");
-        return;
+        close(ptyfd);
+        throw_runtime_error("unlockpt failed");
     }
 
     // Open the slave side.
     ttyfd = open(name, O_RDWR | O_NOCTTY);
-    if (ttyfd < 0)
-    {
-        perror(name);
-        close(ptyfd);
-        return;
-    }
+    if (ttyfd < 0) throw_runtime_error("Failed to open");
 
     fd(ptyfd);
-    tty = ttyfd;
-    ptydev = ptsname(ptm);
+    my_tty = ttyfd;
+    my_ptydev = std::string(name);
 #elif defined(HAVE_DEV_PTS_AND_PTC)
-    // AIX-style pty code.
+    /* AIX-style pty code. */
+    std::cerr << "  using pts/ptc." << std::endl;
+
     ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
-    if (ptyfd < 0)
-    {
-        perror("Could not open /dev/ptc");
-        return;
-    }
+    if (ptyfd < 0) throw_runtime_error("Failed to open /dev/ptc");
 
     char *name = ttyname(ptyfd);
 
     ttyfd = open(name, O_RDWR | O_NOCTTY);
     if (ttyfd < 0)
     {
-        perror(name);
         close(ptyfd);
-        return;
+        throw_runtime_error("Failed to open "+name)
     }
 
     fd(ptyfd);
-    tty = ttyfd;
-    ptydev = name;
+    my_tty = ttyfd;
+    my_ptydev = name;
 #else
-    // BSD-style pty code.
-    char buf1[64];
-    char buf2[64];
-    int i;
-    const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
-    const char *ptyminors = "0123456789abcdef";
-    int num_minors = strlen ( ptyminors );
-    int num_ptys = strlen ( ptymajors ) * num_minors;
+    /* BSD-style pty code. */
+    std::cerr << "  using BSD-style." << std::endl;
 
-    for ( i = 0; i < num_ptys; i++ )
-    {
-        snprintf ( buf1, sizeof buf1, "/dev/pty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]);
-        snprintf ( buf2, sizeof buf2, "/dev/tty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]);
+    std::stringstream buf1;
+    std::stringstream buf2;
+    const std::string ptymajors("pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ");
+    const std::string ptyminors("0123456789abcdef");
+    int num_minors = ptyminors.length();
+    int num_ptys = ptymajors.length() * num_minors;
 
-        ptyfd = open ( buf1, O_RDWR | O_NOCTTY );
+    for (size_t i = 0; i < num_ptys; i++)
+    {
+        buf1.str("/dev/pty");
+        buf1 << ptymajors[i / num_minors] << ptyminors[i % num_minors];
+        buf2.str("/dev/tty");
+        buf2 << ptymajors[i / num_minors] << ptyminors[i % num_minors];
 
-        if ( ptyfd < 0 )
+        ptyfd = open(buf1.str().c_str(), O_RDWR | O_NOCTTY);
+        if (ptyfd < 0)
         {
             /* Try SCO style naming */
-            snprintf ( buf1, sizeof buf1, "/dev/ptyp%d", i );
-            snprintf ( buf2, sizeof buf2, "/dev/ttyp%d", i );
-
-            ptyfd = open ( buf1, O_RDWR | O_NOCTTY );
-            if ( ptyfd < 0 ) continue;
-        }
+            buf1.str("/dev/ptyp"); buf1 << i;
+            buf2.str("/dev/ttyp"); buf2 << i;
 
-        /* Open the slave side. */
-        ttyfd = open ( buf2, O_RDWR | O_NOCTTY );
-        if ( ttyfd < 0 )
-        {
-            perror ( buf2 );
-            close ( ptyfd );
-            return;
+            ptyfd = open(buf1.str().c_str(), O_RDWR | O_NOCTTY);
+            if (ptyfd < 0) continue;
         }
+        break; // found a master, get out of here!
+    }
 
-        fd(ptyfd);
-        tty = ttyfd;
-        ptydev = buf1;
+    /* Open the slave side. */
+    ttyfd = open(buf2.str().c_str(), O_RDWR | O_NOCTTY);
+    if (ttyfd < 0)
+    {
+        close(ptyfd);
+        throw_runtime_error("Failed to open "+buf2.str());
     }
+
+    fd(ptyfd);
+    my_tty = ttyfd;
+    my_ptydev = buf1.str();
 #endif
+
+    std::cerr << "Got TTY/PTY pair." << std::endl;
 }