]> sigrok.org Git - libserialport.git/blob - serialport.c
Make sp_list_ports and sp_get_port_by_name return int.
[libserialport.git] / serialport.c
1 /*
2  * This file is part of the libserialport project.
3  *
4  * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
5  * Copyright (C) 2010-2012 Uwe Hermann <uwe@hermann-uwe.de>
6  * Copyright (C) 2013 Martin Ling <martin-libserialport@earth.li>
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as
10  * published by the Free Software Foundation, either version 3 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #ifdef _WIN32
30 #include <windows.h>
31 #include <tchar.h>
32 #else
33 #include <termios.h>
34 #include <sys/ioctl.h>
35 #endif
36 #ifdef __APPLE__
37 #include <IOKit/IOKitLib.h>
38 #include <IOKit/serial/IOSerialKeys.h>
39 #include <sys/syslimits.h>
40 #endif
41 #ifdef __linux__
42 #include "libudev.h"
43 #include "linux/serial.h"
44 #endif
45
46 #include "serialport.h"
47
48 int sp_get_port_by_name(const char *portname, struct sp_port **port_ptr)
49 {
50         struct sp_port *port;
51         int len;
52
53         *port_ptr = NULL;
54
55         if (!portname)
56                 return SP_ERR_ARG;
57
58         if (!(port = malloc(sizeof(struct sp_port))))
59                 return SP_ERR_MEM;
60
61         len = strlen(portname) + 1;
62
63         if (!(port->name = malloc(len)))
64         {
65                 free(port);
66                 return SP_ERR_MEM;
67         }
68
69         memcpy(port->name, portname, len);
70
71         *port_ptr = port;
72
73         return SP_OK;
74 }
75
76 static struct sp_port **sp_list_append(struct sp_port **list, const char *portname)
77 {
78         void *tmp;
79         unsigned int count;
80         for (count = 0; list[count]; count++);
81         if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
82                 goto fail;
83         list = tmp;
84         if (sp_get_port_by_name(portname, &list[count]) != SP_OK)
85                 goto fail;
86         list[count + 1] = NULL;
87         return list;
88 fail:
89         sp_free_port_list(list);
90         return NULL;
91 }
92
93 /**
94  * List the serial ports available on the system.
95  *
96  * @return A null-terminated array of port name strings.
97  */
98 int sp_list_ports(struct sp_port ***list_ptr)
99 {
100         struct sp_port **list;
101         int ret = SP_OK;
102
103         if (!(list = malloc(sizeof(struct sp_port **))))
104                 return SP_ERR_MEM;;
105
106         list[0] = NULL;
107
108 #ifdef _WIN32
109         HKEY key;
110         TCHAR *value, *data;
111         DWORD max_value_len, max_data_size, max_data_len;
112         DWORD value_len, data_size, data_len;
113         DWORD type, index = 0;
114         char *name;
115         int name_len;
116
117         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
118                         0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS)
119         {
120                 ret = SP_ERR_FAIL;
121                 goto out_done;
122         }
123         if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
124                                 &max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS)
125         {
126                 ret = SP_ERR_FAIL;
127                 goto out_close;
128         }
129         max_data_len = max_data_size / sizeof(TCHAR);
130         if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR))))
131         {
132                 ret = SP_ERR_MEM;
133                 goto out_close;
134         }
135         if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR))))
136         {
137                 ret = SP_ERR_MEM;
138                 goto out_free_value;
139         }
140         while (
141                 value_len = max_value_len,
142                 data_size = max_data_size,
143                 RegEnumValue(key, index, value, &value_len,
144                         NULL, &type, (LPBYTE)data, &data_size) == ERROR_SUCCESS)
145         {
146                 data_len = data_size / sizeof(TCHAR);
147                 data[data_len] = '\0';
148 #ifdef UNICODE
149                 name_len = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL)
150 #else
151                 name_len = data_len + 1;
152 #endif
153                 if (!(name = malloc(name_len)))
154                 {
155                         ret = SP_ERR_MEM;
156                         goto out;
157                 }
158 #ifdef UNICODE
159                 WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL);
160 #else
161                 strcpy(name, data);
162 #endif
163                 if (type == REG_SZ && !(list = sp_list_append(list, name)))
164                 {
165                         ret = SP_ERR_MEM;
166                         goto out;
167                 }
168                 index++;
169         }
170 out:
171         free(data);
172 out_free_value:
173         free(value);
174 out_close:
175         RegCloseKey(key);
176 out_done:
177 #endif
178 #ifdef __APPLE__
179         mach_port_t master;
180         CFMutableDictionaryRef classes;
181         io_iterator_t iter;
182         char *path;
183         io_object_t port;
184         CFTypeRef cf_path;
185         Boolean result;
186
187         if (IOMasterPort(MACH_PORT_NULL, &master) != KERN_SUCCESS)
188         {
189                 ret = SP_ERR_FAIL;
190                 goto out_done;
191         }
192
193         if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue)))
194         {
195                 ret = SP_ERR_FAIL;
196                 goto out_done;
197         }
198
199         CFDictionarySetValue(classes,
200                         CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));
201
202         if (!(IOServiceGetMatchingServices(master, classes, &iter)))
203         {
204                 ret = SP_ERR_FAIL;
205                 goto out_done;
206         }
207
208         if (!(path = malloc(PATH_MAX)))
209         {
210                 ret = SP_ERR_MEM;
211                 goto out_release;
212         }
213
214         while ((port = IOIteratorNext(iter))) {
215                 cf_path = IORegistryEntryCreateCFProperty(port,
216                                 CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
217                 if (cf_path) {
218                         result = CFStringGetCString(cf_path,
219                                         path, PATH_MAX, kCFStringEncodingASCII);
220                         CFRelease(cf_path);
221                         if (result && !(list = sp_list_append(list, path)))
222                         {
223                                 ret = SP_ERR_MEM;
224                                 IOObjectRelease(port);
225                                 goto out;
226                         }
227                 }
228                 IOObjectRelease(port);
229         }
230 out:
231         free(path);
232 out_release:
233         IOObjectRelease(iter);
234 out_done:
235 #endif
236 #ifdef __linux__
237         struct udev *ud;
238         struct udev_enumerate *ud_enumerate;
239         struct udev_list_entry *ud_list;
240         struct udev_list_entry *ud_entry;
241         const char *path;
242         struct udev_device *ud_dev, *ud_parent;
243         const char *name;
244         const char *driver;
245         int fd, ioctl_result;
246         struct serial_struct serial_info;
247
248         ud = udev_new();
249         ud_enumerate = udev_enumerate_new(ud);
250         udev_enumerate_add_match_subsystem(ud_enumerate, "tty");
251         udev_enumerate_scan_devices(ud_enumerate);
252         ud_list = udev_enumerate_get_list_entry(ud_enumerate);
253         udev_list_entry_foreach(ud_entry, ud_list)
254         {
255                 path = udev_list_entry_get_name(ud_entry);
256                 ud_dev = udev_device_new_from_syspath(ud, path);
257                 /* If there is no parent device, this is a virtual tty. */
258                 ud_parent = udev_device_get_parent(ud_dev);
259                 if (ud_parent == NULL)
260                 {
261                         udev_device_unref(ud_dev);
262                         continue;
263                 }
264                 name = udev_device_get_devnode(ud_dev);
265                 /* The serial8250 driver has a hardcoded number of ports.
266                  * The only way to tell which actually exist on a given system
267                  * is to try to open them and make an ioctl call. */
268                 driver = udev_device_get_driver(ud_parent);
269                 if (driver && !strcmp(driver, "serial8250"))
270                 {
271                         if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0)
272                                 goto skip;
273                         ioctl_result = ioctl(fd, TIOCGSERIAL, &serial_info);
274                         close(fd);
275                         if (ioctl_result != 0)
276                                 goto skip;
277                         if (serial_info.type == PORT_UNKNOWN)
278                                 goto skip;
279                 }
280                 list = sp_list_append(list, name);
281 skip:
282                 udev_device_unref(ud_dev);
283                 if (!list)
284                 {
285                         ret = SP_ERR_MEM;
286                         goto out;
287                 }
288         }
289 out:
290         udev_enumerate_unref(ud_enumerate);
291         udev_unref(ud);
292 #endif
293
294         if (ret == SP_OK)
295         {
296                 *list_ptr = list;
297         }
298         else
299         {
300                 if (list)
301                         sp_free_port_list(list);
302
303                 *list_ptr = NULL;
304         }
305
306         return ret;
307 }
308
309 /**
310  * Free a port list returned by sp_list_ports.
311  */
312 void sp_free_port_list(struct sp_port **list)
313 {
314         unsigned int i;
315         for (i = 0; list[i]; i++)
316                 free(list[i]);
317         free(list);
318 }
319
320 static int sp_validate_port(struct sp_port *port)
321 {
322         if (port == NULL)
323                 return 0;
324 #ifdef _WIN32
325         if (port->hdl == INVALID_HANDLE_VALUE)
326                 return 0;
327 #else
328         if (port->fd < 0)
329                 return 0;
330 #endif
331         return 1;
332 }
333
334 #define CHECK_PORT() do { if (!sp_validate_port(port)) return SP_ERR_ARG; } while (0)
335
336 /**
337  * Open the specified serial port.
338  *
339  * @param port Pointer to empty port structure allocated by caller.
340  * @param portname Name of port to open.
341  * @param flags Flags to use when opening the serial port. Possible flags
342  *              are: SP_MODE_RDWR, SP_MODE_RDONLY, SP_MODE_NONBLOCK.
343  *
344  * @return SP_OK on success, SP_ERR_FAIL on failure,
345  *         or SP_ERR_ARG if an invalid port or name is passed.
346  */
347 int sp_open(struct sp_port *port, int flags)
348 {
349         if (!port)
350                 return SP_ERR_ARG;
351
352 #ifdef _WIN32
353         DWORD desired_access = 0, flags_and_attributes = 0;
354         /* Map 'flags' to the OS-specific settings. */
355         desired_access |= GENERIC_READ;
356         flags_and_attributes = FILE_ATTRIBUTE_NORMAL;
357         if (flags & SP_MODE_RDWR)
358                 desired_access |= GENERIC_WRITE;
359         if (flags & SP_MODE_NONBLOCK)
360                 flags_and_attributes |= FILE_FLAG_OVERLAPPED;
361
362         port->hdl = CreateFile(port->name, desired_access, 0, 0,
363                          OPEN_EXISTING, flags_and_attributes, 0);
364         if (port->hdl == INVALID_HANDLE_VALUE)
365                 return SP_ERR_FAIL;
366 #else
367         int flags_local = 0;
368         /* Map 'flags' to the OS-specific settings. */
369         if (flags & SP_MODE_RDWR)
370                 flags_local |= O_RDWR;
371         if (flags & SP_MODE_RDONLY)
372                 flags_local |= O_RDONLY;
373         if (flags & SP_MODE_NONBLOCK)
374                 flags_local |= O_NONBLOCK;
375
376         if ((port->fd = open(port->name, flags_local)) < 0)
377                 return SP_ERR_FAIL;
378 #endif
379
380         return SP_OK;
381 }
382
383 /**
384  * Close the specified serial port.
385  *
386  * @param port Pointer to port structure.
387  *
388  * @return SP_OK on success, SP_ERR_FAIL on failure,
389  *         or SP_ERR_ARG if an invalid port is passed.
390  */
391 int sp_close(struct sp_port *port)
392 {
393         CHECK_PORT();
394
395 #ifdef _WIN32
396         /* Returns non-zero upon success, 0 upon failure. */
397         if (CloseHandle(port->hdl) == 0)
398                 return SP_ERR_FAIL;
399 #else
400         /* Returns 0 upon success, -1 upon failure. */
401         if (close(port->fd) == -1)
402                 return SP_ERR_FAIL;
403 #endif
404
405         return SP_OK;
406 }
407
408 /**
409  * Flush serial port buffers.
410  *
411  * @param port Pointer to port structure.
412  *
413  * @return SP_OK on success, SP_ERR_FAIL on failure,
414  *         or SP_ERR_ARG if an invalid port is passed.
415  */
416 int sp_flush(struct sp_port *port)
417 {
418         CHECK_PORT();
419
420 #ifdef _WIN32
421         /* Returns non-zero upon success, 0 upon failure. */
422         if (PurgeComm(port->hdl, PURGE_RXCLEAR | PURGE_TXCLEAR) == 0)
423                 return SP_ERR_FAIL;
424 #else
425         /* Returns 0 upon success, -1 upon failure. */
426         if (tcflush(port->fd, TCIOFLUSH) < 0)
427                 return SP_ERR_FAIL;
428 #endif
429         return SP_OK;
430 }
431
432 /**
433  * Write a number of bytes to the specified serial port.
434  *
435  * @param port Pointer to port structure.
436  * @param buf Buffer containing the bytes to write.
437  * @param count Number of bytes to write.
438  *
439  * @return The number of bytes written, SP_ERR_FAIL on failure,
440  *         or SP_ERR_ARG if an invalid port is passed.
441  */
442 int sp_write(struct sp_port *port, const void *buf, size_t count)
443 {
444         CHECK_PORT();
445
446         if (!buf)
447                 return SP_ERR_ARG;
448
449 #ifdef _WIN32
450         DWORD written = 0;
451         /* Returns non-zero upon success, 0 upon failure. */
452         if (WriteFile(port->hdl, buf, count, &written, NULL) == 0)
453                 return SP_ERR_FAIL;
454         return written;
455 #else
456         /* Returns the number of bytes written, or -1 upon failure. */
457         ssize_t written = write(port->fd, buf, count);
458         if (written < 0)
459                 return SP_ERR_FAIL;
460         else
461                 return written;;
462 #endif
463 }
464
465 /**
466  * Read a number of bytes from the specified serial port.
467  *
468  * @param port Pointer to port structure.
469  * @param buf Buffer where to store the bytes that are read.
470  * @param count The number of bytes to read.
471  *
472  * @return The number of bytes read, SP_ERR_FAIL on failure,
473  *         or SP_ERR_ARG if an invalid port is passed.
474  */
475 int sp_read(struct sp_port *port, void *buf, size_t count)
476 {
477         CHECK_PORT();
478
479         if (!buf)
480                 return SP_ERR_ARG;
481
482 #ifdef _WIN32
483         DWORD bytes_read = 0;
484         /* Returns non-zero upon success, 0 upon failure. */
485         if (ReadFile(port->hdl, buf, count, &bytes_read, NULL) == 0)
486                 return SP_ERR_FAIL;
487         return bytes_read;
488 #else
489         ssize_t bytes_read;
490         /* Returns the number of bytes read, or -1 upon failure. */
491         if ((bytes_read = read(port->fd, buf, count)) < 0)
492                 return SP_ERR_FAIL;
493         return bytes_read;
494 #endif
495 }
496
497 /**
498  * Set serial parameters for the specified serial port.
499  *
500  * @param port Pointer to port structure.
501  * @param baudrate The baudrate to set.
502  * @param bits The number of data bits to use.
503  * @param parity The parity setting to use (0 = none, 1 = even, 2 = odd).
504  * @param stopbits The number of stop bits to use (1 or 2).
505  * @param flowcontrol The flow control settings to use (0 = none, 1 = RTS/CTS,
506  *                    2 = XON/XOFF).
507  *
508  * @return The number of bytes read, SP_ERR_FAIL on failure,
509  *         or SP_ERR_ARG if an invalid argument is passed.
510  */
511 int sp_set_params(struct sp_port *port, int baudrate,
512                               int bits, int parity, int stopbits,
513                               int flowcontrol, int rts, int dtr)
514 {
515         CHECK_PORT();
516
517 #ifdef _WIN32
518         DCB dcb;
519
520         if (!GetCommState(port->hdl, &dcb))
521                 return SP_ERR_FAIL;
522
523         switch (baudrate) {
524         /*
525          * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to
526          * have documented CBR_* macros.
527          */
528         case 110:
529                 dcb.BaudRate = CBR_110;
530                 break;
531         case 300:
532                 dcb.BaudRate = CBR_300;
533                 break;
534         case 600:
535                 dcb.BaudRate = CBR_600;
536                 break;
537         case 1200:
538                 dcb.BaudRate = CBR_1200;
539                 break;
540         case 2400:
541                 dcb.BaudRate = CBR_2400;
542                 break;
543         case 4800:
544                 dcb.BaudRate = CBR_4800;
545                 break;
546         case 9600:
547                 dcb.BaudRate = CBR_9600;
548                 break;
549         case 14400:
550                 dcb.BaudRate = CBR_14400; /* Not available on Unix? */
551                 break;
552         case 19200:
553                 dcb.BaudRate = CBR_19200;
554                 break;
555         case 38400:
556                 dcb.BaudRate = CBR_38400;
557                 break;
558         case 57600:
559                 dcb.BaudRate = CBR_57600;
560                 break;
561         case 115200:
562                 dcb.BaudRate = CBR_115200;
563                 break;
564         case 128000:
565                 dcb.BaudRate = CBR_128000; /* Not available on Unix? */
566                 break;
567         case 256000:
568                 dcb.BaudRate = CBR_256000; /* Not available on Unix? */
569                 break;
570         default:
571                 return SP_ERR_ARG;
572         }
573
574         switch (stopbits) {
575         /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
576         case 1:
577                 dcb.StopBits = ONESTOPBIT;
578                 break;
579         case 2:
580                 dcb.StopBits = TWOSTOPBITS;
581                 break;
582         default:
583                 return SP_ERR_ARG;
584         }
585
586         switch (parity) {
587         /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
588         case SP_PARITY_NONE:
589                 dcb.Parity = NOPARITY;
590                 break;
591         case SP_PARITY_EVEN:
592                 dcb.Parity = EVENPARITY;
593                 break;
594         case SP_PARITY_ODD:
595                 dcb.Parity = ODDPARITY;
596                 break;
597         default:
598                 return SP_ERR_ARG;
599         }
600
601         if (rts != -1) {
602                 if (rts)
603                         dcb.fRtsControl = RTS_CONTROL_ENABLE;
604                 else
605                         dcb.fRtsControl = RTS_CONTROL_DISABLE;
606         }
607
608         if (dtr != -1) {
609                 if (dtr)
610                         dcb.fDtrControl = DTR_CONTROL_ENABLE;
611                 else
612                         dcb.fDtrControl = DTR_CONTROL_DISABLE;
613         }
614
615         if (!SetCommState(port->hdl, &dcb))
616                 return SP_ERR_FAIL;
617 #else
618         struct termios term;
619         speed_t baud;
620         int controlbits;
621
622         if (tcgetattr(port->fd, &term) < 0)
623                 return SP_ERR_FAIL;
624
625         switch (baudrate) {
626         case 50:
627                 baud = B50;
628                 break;
629         case 75:
630                 baud = B75;
631                 break;
632         case 110:
633                 baud = B110;
634                 break;
635         case 134:
636                 baud = B134;
637                 break;
638         case 150:
639                 baud = B150;
640                 break;
641         case 200:
642                 baud = B200;
643                 break;
644         case 300:
645                 baud = B300;
646                 break;
647         case 600:
648                 baud = B600;
649                 break;
650         case 1200:
651                 baud = B1200;
652                 break;
653         case 1800:
654                 baud = B1800;
655                 break;
656         case 2400:
657                 baud = B2400;
658                 break;
659         case 4800:
660                 baud = B4800;
661                 break;
662         case 9600:
663                 baud = B9600;
664                 break;
665         case 19200:
666                 baud = B19200;
667                 break;
668         case 38400:
669                 baud = B38400;
670                 break;
671         case 57600:
672                 baud = B57600;
673                 break;
674         case 115200:
675                 baud = B115200;
676                 break;
677         case 230400:
678                 baud = B230400;
679                 break;
680 #if !defined(__APPLE__) && !defined(__OpenBSD__)
681         case 460800:
682                 baud = B460800;
683                 break;
684 #endif
685         default:
686                 return SP_ERR_ARG;
687         }
688
689         if (cfsetospeed(&term, baud) < 0)
690                 return SP_ERR_FAIL;
691
692         if (cfsetispeed(&term, baud) < 0)
693                 return SP_ERR_FAIL;
694
695         term.c_cflag &= ~CSIZE;
696         switch (bits) {
697         case 8:
698                 term.c_cflag |= CS8;
699                 break;
700         case 7:
701                 term.c_cflag |= CS7;
702                 break;
703         default:
704                 return SP_ERR_ARG;
705         }
706
707         term.c_cflag &= ~CSTOPB;
708         switch (stopbits) {
709         case 1:
710                 term.c_cflag &= ~CSTOPB;
711                 break;
712         case 2:
713                 term.c_cflag |= CSTOPB;
714                 break;
715         default:
716                 return SP_ERR_ARG;
717         }
718
719         term.c_iflag &= ~(IXON | IXOFF | IXANY);
720         term.c_cflag &= ~CRTSCTS;
721         switch (flowcontrol) {
722         case 0:
723                 /* No flow control. */
724                 break;
725         case 1:
726                 term.c_cflag |= CRTSCTS;
727                 break;
728         case 2:
729                 term.c_iflag |= IXON | IXOFF | IXANY;
730                 break;
731         default:
732                 return SP_ERR_ARG;
733         }
734
735         term.c_iflag &= ~IGNPAR;
736         term.c_cflag &= ~(PARENB | PARODD);
737         switch (parity) {
738         case SP_PARITY_NONE:
739                 term.c_iflag |= IGNPAR;
740                 break;
741         case SP_PARITY_EVEN:
742                 term.c_cflag |= PARENB;
743                 break;
744         case SP_PARITY_ODD:
745                 term.c_cflag |= PARENB | PARODD;
746                 break;
747         default:
748                 return SP_ERR_ARG;
749         }
750
751         /* Turn off all serial port cooking. */
752         term.c_iflag &= ~(ISTRIP | INLCR | ICRNL);
753         term.c_oflag &= ~(ONLCR | OCRNL | ONOCR);
754 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
755         term.c_oflag &= ~OFILL;
756 #endif
757
758         /* Disable canonical mode, and don't echo input characters. */
759         term.c_lflag &= ~(ICANON | ECHO);
760
761         /* Ignore modem status lines; enable receiver */
762         term.c_cflag |= (CLOCAL | CREAD);
763
764         /* Write the configured settings. */
765         if (tcsetattr(port->fd, TCSADRAIN, &term) < 0)
766                 return SP_ERR_FAIL;
767
768         if (rts != -1) {
769                 controlbits = TIOCM_RTS;
770                 if (ioctl(port->fd, rts ? TIOCMBIS : TIOCMBIC,
771                                 &controlbits) < 0)
772                         return SP_ERR_FAIL;
773         }
774
775         if (dtr != -1) {
776                 controlbits = TIOCM_DTR;
777                 if (ioctl(port->fd, dtr ? TIOCMBIS : TIOCMBIC,
778                                 &controlbits) < 0)
779                         return SP_ERR_FAIL;
780         }
781 #endif
782
783         return SP_OK;
784 }
785
786 /**
787  * Get error code for failed operation.
788  *
789  * In order to obtain the correct result, this function should be called
790  * straight after the failure, before executing any other system operations.
791  *
792  * @return The system's numeric code for the error that caused the last
793  *         operation to fail.
794  */
795 int sp_last_error_code(void)
796 {
797 #ifdef _WIN32
798         return GetLastError();
799 #else
800         return errno;
801 #endif
802 }
803
804 /**
805  * Get error message for failed operation.
806  *
807  * In order to obtain the correct result, this function should be called
808  * straight after the failure, before executing other system operations.
809  *
810  * @return The system's message for the error that caused the last
811  *         operation to fail. This string may be allocated by the function,
812  *         and can be freed after use by calling sp_free_error_message.
813  */
814 char *sp_last_error_message(void)
815 {
816 #ifdef _WIN32
817         LPVOID message;
818         DWORD error = GetLastError();
819
820         FormatMessage(
821                 FORMAT_MESSAGE_ALLOCATE_BUFFER |
822                 FORMAT_MESSAGE_FROM_SYSTEM |
823                 FORMAT_MESSAGE_IGNORE_INSERTS,
824                 NULL,
825                 error,
826                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
827                 (LPTSTR) &message,
828                 0, NULL );
829
830         return message;
831 #else
832         return strerror(errno);
833 #endif
834 }
835
836 /**
837  * Free error message.
838  *
839  * This function can be used to free a string returned by the
840  * sp_last_error_message function.
841  */
842 void sp_free_error_message(char *message)
843 {
844 #ifdef _WIN32
845         LocalFree(message);
846 #else
847         (void)message;
848 #endif
849 }