294{
295 try {
296
297 set_option(boost::asio::serial_port_base::baud_rate(baud_rate));
298 } catch (boost::system::system_error &) {
299 auto handle = native_handle();
300
301 auto handle_errno = [](int retval) {
302 if (retval != 0) {
303 throw Slic3r::RuntimeError(
304 (boost::format("Could not set baud rate: %1%") % strerror(errno)).str()
305 );
306 }
307 };
308
309#if __APPLE__
310 termios ios;
311 handle_errno(::tcgetattr(handle, &ios));
312 handle_errno(::cfsetspeed(&ios, baud_rate));
313 speed_t newSpeed = baud_rate;
314 handle_errno(::ioctl(handle, IOSSIOSPEED, &newSpeed));
315 handle_errno(::tcsetattr(handle, TCSANOW, &ios));
316#elif __linux__
317
318
319
320
321
322
323#define K_NCCS 19
324 struct termios2 {
325 tcflag_t c_iflag;
326 tcflag_t c_oflag;
327 tcflag_t c_cflag;
328 tcflag_t c_lflag;
329 cc_t c_line;
330 cc_t c_cc[K_NCCS];
331 speed_t c_ispeed;
332 speed_t c_ospeed;
333 };
334#define BOTHER CBAUDEX
335
336 termios2 ios;
337 handle_errno(::ioctl(handle, TCGETS2, &ios));
338 ios.c_ispeed = ios.c_ospeed = baud_rate;
339 ios.c_cflag &= ~CBAUD;
340 ios.c_cflag |= BOTHER | CLOCAL | CREAD;
341 ios.c_cc[VMIN] = 1;
342 ios.c_cc[VTIME] = 1;
343 handle_errno(::ioctl(handle, TCSETS2, &ios));
344
345#elif __OpenBSD__
346 struct termios ios;
347 handle_errno(::tcgetattr(handle, &ios));
348 handle_errno(::cfsetspeed(&ios, baud_rate));
349 handle_errno(::tcsetattr(handle, TCSAFLUSH, &ios));
350#else
351 throw Slic3r::RuntimeError("Custom baud rates are not currently supported on this OS");
352#endif
353 }
354}