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