24 #ifndef GOBY_MIDDLEWARE_IO_DETAIL_PTY_INTERFACE_H
25 #define GOBY_MIDDLEWARE_IO_DETAIL_PTY_INTERFACE_H
38 #include <boost/asio/posix/stream_descriptor.hpp>
77 bool use_indexed_groups =
false>
79 :
public detail::IOThread<line_in_group, line_out_group, publish_layer, subscribe_layer,
80 goby::middleware::protobuf::PTYConfig,
81 boost::asio::posix::stream_descriptor, ThreadType, use_indexed_groups>
84 detail::IOThread<line_in_group, line_out_group, publish_layer, subscribe_layer,
86 boost::asio::posix::stream_descriptor, ThreadType, use_indexed_groups>;
96 this->
interthread().template publish<line_in_group>(ready);
102 void async_write(std::shared_ptr<const goby::middleware::protobuf::IOData> io_msg)
override
107 void open_socket()
override;
118 bool use_indexed_groups>
120 subscribe_layer, ThreadType,
121 use_indexed_groups>::open_socket()
124 const char* pty_external_symlink = this->cfg().port().
c_str();
125 struct stat stat_buffer;
127 if (lstat(pty_external_symlink, &stat_buffer) == 0)
129 if (S_ISLNK(stat_buffer.st_mode) == 1)
131 if (remove(pty_external_symlink) == -1)
132 throw(
goby::Exception(std::string(
"Could not remove existing symlink: ") +
133 pty_external_symlink));
137 throw(
goby::Exception(std::string(
"File exists and is not symlink: ") +
138 pty_external_symlink));
143 int pty_internal = posix_openpt(O_RDWR | O_NOCTTY);
145 if (pty_internal == -1)
146 throw(
goby::Exception(std::string(
"Error in posix_openpt: ") + std::strerror(errno)));
147 if (grantpt(pty_internal) == -1)
148 throw(
goby::Exception(std::string(
"Error in grantpt: ") + std::strerror(errno)));
149 if (unlockpt(pty_internal) == -1)
150 throw(
goby::Exception(std::string(
"Error in unlockpt: ") + std::strerror(errno)));
154 if (tcgetattr(pty_internal, &ps) == -1)
155 throw(
goby::Exception(std::string(
"Unable to get attributes for pty configuration: ") +
168 switch (this->cfg().baud())
170 case 2400: cfsetspeed(&ps, B2400);
break;
171 case 4800: cfsetspeed(&ps, B4800);
break;
172 case 9600: cfsetspeed(&ps, B9600);
break;
173 case 19200: cfsetspeed(&ps, B19200);
break;
174 case 38400: cfsetspeed(&ps, B38400);
break;
175 case 57600: cfsetspeed(&ps, B57600);
break;
176 case 115200: cfsetspeed(&ps, B115200);
break;
183 ps.c_cflag &= ~CSTOPB;
185 ps.c_cflag &= ~CRTSCTS;
187 if (tcsetattr(pty_internal, TCSANOW, &ps) == -1)
188 throw(
goby::Exception(std::string(
"Unable to set pty configuration attributes ") +
191 this->mutable_socket().assign(pty_internal);
194 char pty_external_path[256];
195 ptsname_r(pty_internal, pty_external_path,
sizeof(pty_external_path));
197 if (symlink(pty_external_path, pty_external_symlink) == -1)
198 throw(
goby::Exception(std::string(
"Could not create symlink: ") + pty_external_symlink));