Convert operating system errors.
Errors reported by system calls are now converted to the corresponding libdivecomputer status code. This results in a more descriptive and meaningfull return value.
This commit is contained in:
parent
4fd0118d4e
commit
f8417037c6
85
src/irda.c
85
src/irda.c
@ -45,15 +45,25 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef int s_ssize_t;
|
||||
typedef DWORD s_errcode_t;
|
||||
#define S_ERRNO WSAGetLastError ()
|
||||
#define S_EAGAIN WSAEWOULDBLOCK
|
||||
#define S_ENOMEM WSA_NOT_ENOUGH_MEMORY
|
||||
#define S_EINVAL WSAEINVAL
|
||||
#define S_EACCES WSAEACCES
|
||||
#define S_EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||
#define S_INVALID INVALID_SOCKET
|
||||
#define S_IOCTL ioctlsocket
|
||||
#define S_CLOSE closesocket
|
||||
#else
|
||||
typedef ssize_t s_ssize_t;
|
||||
typedef int s_errcode_t;
|
||||
#define S_ERRNO errno
|
||||
#define S_EAGAIN EAGAIN
|
||||
#define S_ENOMEM ENOMEM
|
||||
#define S_EINVAL EINVAL
|
||||
#define S_EACCES EACCES
|
||||
#define S_EAFNOSUPPORT EAFNOSUPPORT
|
||||
#define S_INVALID -1
|
||||
#define S_IOCTL ioctl
|
||||
#define S_CLOSE close
|
||||
@ -73,6 +83,23 @@ struct dc_irda_t {
|
||||
int timeout;
|
||||
};
|
||||
|
||||
static dc_status_t
|
||||
syserror(s_errcode_t errcode)
|
||||
{
|
||||
switch (errcode) {
|
||||
case S_EINVAL:
|
||||
return DC_STATUS_INVALIDARGS;
|
||||
case S_ENOMEM:
|
||||
return DC_STATUS_NOMEMORY;
|
||||
case S_EACCES:
|
||||
return DC_STATUS_NOACCESS;
|
||||
case S_EAFNOSUPPORT:
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
default:
|
||||
return DC_STATUS_IO;
|
||||
}
|
||||
}
|
||||
|
||||
dc_status_t
|
||||
dc_irda_open (dc_irda_t **out, dc_context_t *context)
|
||||
{
|
||||
@ -85,11 +112,7 @@ dc_irda_open (dc_irda_t **out, dc_context_t *context)
|
||||
// Allocate memory.
|
||||
device = (dc_irda_t *) malloc (sizeof (dc_irda_t));
|
||||
if (device == NULL) {
|
||||
#ifdef _WIN32
|
||||
SYSERROR (context, ERROR_OUTOFMEMORY);
|
||||
#else
|
||||
SYSERROR (context, ENOMEM);
|
||||
#endif
|
||||
SYSERROR (context, S_ENOMEM);
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
@ -124,8 +147,9 @@ dc_irda_open (dc_irda_t **out, dc_context_t *context)
|
||||
// Open the socket.
|
||||
device->fd = socket (AF_IRDA, SOCK_STREAM, 0);
|
||||
if (device->fd == S_INVALID) {
|
||||
SYSERROR (context, S_ERRNO);
|
||||
status = DC_STATUS_IO;
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
SYSERROR (context, errcode);
|
||||
status = syserror(errcode);
|
||||
goto error_wsacleanup;
|
||||
}
|
||||
|
||||
@ -155,15 +179,17 @@ dc_irda_close (dc_irda_t *device)
|
||||
|
||||
// Close the socket.
|
||||
if (S_CLOSE (device->fd) != 0) {
|
||||
SYSERROR (device->context, S_ERRNO);
|
||||
dc_status_set_error(&status, DC_STATUS_IO);
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
SYSERROR (device->context, errcode);
|
||||
dc_status_set_error(&status, syserror(errcode));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Terminate the winsock dll.
|
||||
if (WSACleanup () != 0) {
|
||||
SYSERROR (device->context, S_ERRNO);
|
||||
dc_status_set_error(&status, DC_STATUS_IO);
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
SYSERROR (device->context, errcode);
|
||||
dc_status_set_error(&status, syserror(errcode));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -227,9 +253,10 @@ dc_irda_discover (dc_irda_t *device, dc_irda_callback_t callback, void *userdata
|
||||
// discovered, while on Windows it succeeds and sets the number
|
||||
// of devices to zero. Both situations are handled the same here.
|
||||
if (rc != 0) {
|
||||
if (S_ERRNO != S_EAGAIN) {
|
||||
SYSERROR (device->context, S_ERRNO);
|
||||
return DC_STATUS_IO;
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
if (errcode != S_EAGAIN) {
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror(errcode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,8 +332,9 @@ dc_irda_connect_name (dc_irda_t *device, unsigned int address, const char *name)
|
||||
#endif
|
||||
|
||||
if (connect (device->fd, (struct sockaddr *) &peer, sizeof (peer)) != 0) {
|
||||
SYSERROR (device->context, S_ERRNO);
|
||||
return DC_STATUS_IO;
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror(errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -337,8 +365,9 @@ dc_irda_connect_lsap (dc_irda_t *device, unsigned int address, unsigned int lsap
|
||||
#endif
|
||||
|
||||
if (connect (device->fd, (struct sockaddr *) &peer, sizeof (peer)) != 0) {
|
||||
SYSERROR (device->context, S_ERRNO);
|
||||
return DC_STATUS_IO;
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror(errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -357,8 +386,9 @@ dc_irda_get_available (dc_irda_t *device, size_t *value)
|
||||
#endif
|
||||
|
||||
if (S_IOCTL (device->fd, FIONREAD, &bytes) != 0) {
|
||||
SYSERROR (device->context, S_ERRNO);
|
||||
return DC_STATUS_IO;
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror(errcode);
|
||||
}
|
||||
|
||||
if (value)
|
||||
@ -391,8 +421,9 @@ dc_irda_read (dc_irda_t *device, void *data, size_t size, size_t *actual)
|
||||
while (nbytes < size) {
|
||||
int rc = select (device->fd + 1, &fds, NULL, NULL, (device->timeout >= 0 ? &tv : NULL));
|
||||
if (rc < 0) {
|
||||
SYSERROR (device->context, S_ERRNO);
|
||||
status = DC_STATUS_IO;
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror(errcode);
|
||||
goto out;
|
||||
} else if (rc == 0) {
|
||||
break; // Timeout.
|
||||
@ -400,8 +431,9 @@ dc_irda_read (dc_irda_t *device, void *data, size_t size, size_t *actual)
|
||||
|
||||
s_ssize_t n = recv (device->fd, (char*) data + nbytes, size - nbytes, 0);
|
||||
if (n < 0) {
|
||||
SYSERROR (device->context, S_ERRNO);
|
||||
status = DC_STATUS_IO;
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror(errcode);
|
||||
goto out;
|
||||
} else if (n == 0) {
|
||||
break; // EOF reached.
|
||||
@ -437,8 +469,9 @@ dc_irda_write (dc_irda_t *device, const void *data, size_t size, size_t *actual)
|
||||
while (nbytes < size) {
|
||||
s_ssize_t n = send (device->fd, (char*) data + nbytes, size - nbytes, 0);
|
||||
if (n < 0) {
|
||||
SYSERROR (device->context, S_ERRNO);
|
||||
status = DC_STATUS_IO;
|
||||
s_errcode_t errcode = S_ERRNO;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror(errcode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@ -77,6 +77,23 @@ struct dc_serial_t {
|
||||
unsigned int nbits;
|
||||
};
|
||||
|
||||
static dc_status_t
|
||||
syserror(int errcode)
|
||||
{
|
||||
switch (errcode) {
|
||||
case EINVAL:
|
||||
return DC_STATUS_INVALIDARGS;
|
||||
case ENOMEM:
|
||||
return DC_STATUS_NOMEMORY;
|
||||
case ENOENT:
|
||||
return DC_STATUS_NODEVICE;
|
||||
case EACCES:
|
||||
case EBUSY:
|
||||
return DC_STATUS_NOACCESS;
|
||||
default:
|
||||
return DC_STATUS_IO;
|
||||
}
|
||||
}
|
||||
|
||||
dc_status_t
|
||||
dc_serial_enumerate (dc_serial_callback_t callback, void *userdata)
|
||||
@ -154,16 +171,18 @@ dc_serial_open (dc_serial_t **out, dc_context_t *context, const char *name)
|
||||
// without waiting for the modem connection to complete.
|
||||
device->fd = open (name, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if (device->fd == -1) {
|
||||
SYSERROR (context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
#ifndef ENABLE_PTY
|
||||
// Enable exclusive access mode.
|
||||
if (ioctl (device->fd, TIOCEXCL, NULL) != 0) {
|
||||
SYSERROR (context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto error_close;
|
||||
}
|
||||
#endif
|
||||
@ -173,8 +192,9 @@ dc_serial_open (dc_serial_t **out, dc_context_t *context, const char *name)
|
||||
// It is also used to check if the obtained
|
||||
// file descriptor represents a terminal device.
|
||||
if (tcgetattr (device->fd, &device->tty) != 0) {
|
||||
SYSERROR (context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto error_close;
|
||||
}
|
||||
|
||||
@ -199,8 +219,9 @@ dc_serial_close (dc_serial_t *device)
|
||||
|
||||
// Restore the initial terminal attributes.
|
||||
if (tcsetattr (device->fd, TCSANOW, &device->tty) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
dc_status_set_error(&status, DC_STATUS_IO);
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
dc_status_set_error(&status, syserror (errcode));
|
||||
}
|
||||
|
||||
#ifndef ENABLE_PTY
|
||||
@ -210,8 +231,9 @@ dc_serial_close (dc_serial_t *device)
|
||||
|
||||
// Close the device.
|
||||
if (close (device->fd) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
dc_status_set_error(&status, DC_STATUS_IO);
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
dc_status_set_error(&status, syserror (errcode));
|
||||
}
|
||||
|
||||
// Free memory.
|
||||
@ -233,8 +255,9 @@ dc_serial_configure (dc_serial_t *device, unsigned int baudrate, unsigned int da
|
||||
struct termios tty;
|
||||
memset (&tty, 0, sizeof (tty));
|
||||
if (tcgetattr (device->fd, &tty) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
// Setup raw input/output mode without echo.
|
||||
@ -329,8 +352,9 @@ dc_serial_configure (dc_serial_t *device, unsigned int baudrate, unsigned int da
|
||||
}
|
||||
if (cfsetispeed (&tty, baud) != 0 ||
|
||||
cfsetospeed (&tty, baud) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
// Set the character size.
|
||||
@ -425,8 +449,9 @@ dc_serial_configure (dc_serial_t *device, unsigned int baudrate, unsigned int da
|
||||
|
||||
// Apply the new settings.
|
||||
if (tcsetattr (device->fd, TCSANOW, &tty) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
// Configure a custom baudrate if necessary.
|
||||
@ -435,8 +460,9 @@ dc_serial_configure (dc_serial_t *device, unsigned int baudrate, unsigned int da
|
||||
// Get the current settings.
|
||||
struct serial_struct ss;
|
||||
if (ioctl (device->fd, TIOCGSERIAL, &ss) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
// Set the custom divisor.
|
||||
@ -446,14 +472,16 @@ dc_serial_configure (dc_serial_t *device, unsigned int baudrate, unsigned int da
|
||||
|
||||
// Apply the new settings.
|
||||
if (ioctl (device->fd, TIOCSSERIAL, &ss) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
#elif defined(IOSSIOSPEED)
|
||||
speed_t speed = baudrate;
|
||||
if (ioctl (device->fd, IOSSIOSPEED, &speed) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
#else
|
||||
// Custom baudrates are not supported.
|
||||
@ -501,8 +529,9 @@ dc_serial_set_latency (dc_serial_t *device, unsigned int milliseconds)
|
||||
// Get the current settings.
|
||||
struct serial_struct ss;
|
||||
if (ioctl (device->fd, TIOCGSERIAL, &ss) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
// Set or clear the low latency flag.
|
||||
@ -514,8 +543,9 @@ dc_serial_set_latency (dc_serial_t *device, unsigned int milliseconds)
|
||||
|
||||
// Apply the new settings.
|
||||
if (ioctl (device->fd, TIOCSSERIAL, &ss) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
#elif defined(IOSSDATALAT)
|
||||
// Set the receive latency in microseconds. Serial drivers use this
|
||||
@ -523,8 +553,9 @@ dc_serial_set_latency (dc_serial_t *device, unsigned int milliseconds)
|
||||
// the hardware. A value of zero restores the default value.
|
||||
unsigned long usec = (milliseconds == 0 ? 1 : milliseconds * 1000);
|
||||
if (ioctl (device->fd, IOSSDATALAT, &usec) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -558,8 +589,9 @@ dc_serial_read (dc_serial_t *device, void *data, size_t size, size_t *actual)
|
||||
if (timeout > 0) {
|
||||
struct timeval now;
|
||||
if (gettimeofday (&now, NULL) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -583,10 +615,11 @@ dc_serial_read (dc_serial_t *device, void *data, size_t size, size_t *actual)
|
||||
|
||||
int rc = select (device->fd + 1, &fds, NULL, NULL, timeout >= 0 ? &tvt : NULL);
|
||||
if (rc < 0) {
|
||||
if (errno == EINTR)
|
||||
int errcode = errno;
|
||||
if (errcode == EINTR)
|
||||
continue; // Retry.
|
||||
SYSERROR (device->context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
} else if (rc == 0) {
|
||||
break; // Timeout.
|
||||
@ -594,10 +627,11 @@ dc_serial_read (dc_serial_t *device, void *data, size_t size, size_t *actual)
|
||||
|
||||
ssize_t n = read (device->fd, (char *) data + nbytes, size - nbytes);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
int errcode = errno;
|
||||
if (errcode == EINTR || errcode == EAGAIN)
|
||||
continue; // Retry.
|
||||
SYSERROR (device->context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
} else if (n == 0) {
|
||||
break; // EOF.
|
||||
@ -634,8 +668,9 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
|
||||
if (device->halfduplex) {
|
||||
// Get the current time.
|
||||
if (gettimeofday (&tvb, NULL) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -647,10 +682,11 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
|
||||
|
||||
int rc = select (device->fd + 1, NULL, &fds, NULL, NULL);
|
||||
if (rc < 0) {
|
||||
if (errno == EINTR)
|
||||
int errcode = errno;
|
||||
if (errcode == EINTR)
|
||||
continue; // Retry.
|
||||
SYSERROR (device->context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
} else if (rc == 0) {
|
||||
break; // Timeout.
|
||||
@ -658,10 +694,11 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
|
||||
|
||||
ssize_t n = write (device->fd, (const char *) data + nbytes, size - nbytes);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
int errcode = errno;
|
||||
if (errcode == EINTR || errcode == EAGAIN)
|
||||
continue; // Retry.
|
||||
SYSERROR (device->context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
} else if (n == 0) {
|
||||
break; // EOF.
|
||||
@ -677,9 +714,10 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
|
||||
#else
|
||||
while (tcdrain (device->fd) != 0) {
|
||||
#endif
|
||||
if (errno != EINTR ) {
|
||||
SYSERROR (device->context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
if (errcode != EINTR ) {
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -687,8 +725,9 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
|
||||
if (device->halfduplex) {
|
||||
// Get the current time.
|
||||
if (gettimeofday (&tve, NULL) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
status = DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -746,8 +785,9 @@ dc_serial_purge (dc_serial_t *device, dc_direction_t direction)
|
||||
}
|
||||
|
||||
if (tcflush (device->fd, flags) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -775,8 +815,9 @@ dc_serial_set_break (dc_serial_t *device, unsigned int level)
|
||||
unsigned long action = (level ? TIOCSBRK : TIOCCBRK);
|
||||
|
||||
if (ioctl (device->fd, action, NULL) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -794,8 +835,9 @@ dc_serial_set_dtr (dc_serial_t *device, unsigned int level)
|
||||
|
||||
int value = TIOCM_DTR;
|
||||
if (ioctl (device->fd, action, &value) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -813,8 +855,9 @@ dc_serial_set_rts (dc_serial_t *device, unsigned int level)
|
||||
|
||||
int value = TIOCM_RTS;
|
||||
if (ioctl (device->fd, action, &value) != 0 && NOPTY) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -828,8 +871,9 @@ dc_serial_get_available (dc_serial_t *device, size_t *value)
|
||||
|
||||
int bytes = 0;
|
||||
if (ioctl (device->fd, TIOCINQ, &bytes) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
if (value)
|
||||
@ -848,8 +892,9 @@ dc_serial_get_lines (dc_serial_t *device, unsigned int *value)
|
||||
|
||||
int status = 0;
|
||||
if (ioctl (device->fd, TIOCMGET, &status) != 0) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
if (status & TIOCM_CAR)
|
||||
@ -880,9 +925,10 @@ dc_serial_sleep (dc_serial_t *device, unsigned int timeout)
|
||||
ts.tv_nsec = (timeout % 1000) * 1000000;
|
||||
|
||||
while (nanosleep (&ts, &ts) != 0) {
|
||||
if (errno != EINTR ) {
|
||||
SYSERROR (device->context, errno);
|
||||
return DC_STATUS_IO;
|
||||
int errcode = errno;
|
||||
if (errcode != EINTR ) {
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -48,6 +48,23 @@ struct dc_serial_t {
|
||||
unsigned int nbits;
|
||||
};
|
||||
|
||||
static dc_status_t
|
||||
syserror(DWORD errcode)
|
||||
{
|
||||
switch (errcode) {
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
return DC_STATUS_INVALIDARGS;
|
||||
case ERROR_OUTOFMEMORY:
|
||||
return DC_STATUS_NOMEMORY;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
return DC_STATUS_NODEVICE;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return DC_STATUS_NOACCESS;
|
||||
default:
|
||||
return DC_STATUS_IO;
|
||||
}
|
||||
}
|
||||
|
||||
dc_status_t
|
||||
dc_serial_enumerate (dc_serial_callback_t callback, void *userdata)
|
||||
{
|
||||
@ -148,8 +165,9 @@ dc_serial_open (dc_serial_t **out, dc_context_t *context, const char *name)
|
||||
0, // Non-overlapped I/O.
|
||||
NULL);
|
||||
if (device->hFile == INVALID_HANDLE_VALUE) {
|
||||
SYSERROR (context, GetLastError ());
|
||||
status = DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
@ -159,8 +177,9 @@ dc_serial_open (dc_serial_t **out, dc_context_t *context, const char *name)
|
||||
// represents a serial device.
|
||||
if (!GetCommState (device->hFile, &device->dcb) ||
|
||||
!GetCommTimeouts (device->hFile, &device->timeouts)) {
|
||||
SYSERROR (context, GetLastError ());
|
||||
status = DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto error_close;
|
||||
}
|
||||
|
||||
@ -186,14 +205,16 @@ dc_serial_close (dc_serial_t *device)
|
||||
// Restore the initial communication settings and timeouts.
|
||||
if (!SetCommState (device->hFile, &device->dcb) ||
|
||||
!SetCommTimeouts (device->hFile, &device->timeouts)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
dc_status_set_error(&status, DC_STATUS_IO);
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
dc_status_set_error(&status, syserror (errcode));
|
||||
}
|
||||
|
||||
// Close the device.
|
||||
if (!CloseHandle (device->hFile)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
dc_status_set_error(&status, DC_STATUS_IO);
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
dc_status_set_error(&status, syserror (errcode));
|
||||
}
|
||||
|
||||
// Free memory.
|
||||
@ -214,8 +235,9 @@ dc_serial_configure (dc_serial_t *device, unsigned int baudrate, unsigned int da
|
||||
// Retrieve the current settings.
|
||||
DCB dcb;
|
||||
if (!GetCommState (device->hFile, &dcb)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
dcb.fBinary = TRUE; // Enable Binary Transmission
|
||||
@ -303,8 +325,9 @@ dc_serial_configure (dc_serial_t *device, unsigned int baudrate, unsigned int da
|
||||
|
||||
// Apply the new settings.
|
||||
if (!SetCommState (device->hFile, &dcb)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
device->baudrate = baudrate;
|
||||
@ -324,8 +347,9 @@ dc_serial_set_timeout (dc_serial_t *device, int timeout)
|
||||
// Retrieve the current timeouts.
|
||||
COMMTIMEOUTS timeouts;
|
||||
if (!GetCommTimeouts (device->hFile, &timeouts)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
// Update the settings.
|
||||
@ -354,8 +378,9 @@ dc_serial_set_timeout (dc_serial_t *device, int timeout)
|
||||
|
||||
// Activate the new timeouts.
|
||||
if (!SetCommTimeouts (device->hFile, &timeouts)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -393,8 +418,9 @@ dc_serial_read (dc_serial_t *device, void *data, size_t size, size_t *actual)
|
||||
}
|
||||
|
||||
if (!ReadFile (device->hFile, data, size, &dwRead, NULL)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
status = DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -427,23 +453,26 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
|
||||
// Get the current time.
|
||||
if (!QueryPerformanceFrequency(&freq) ||
|
||||
!QueryPerformanceCounter(&begin)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
status = DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!WriteFile (device->hFile, data, size, &dwWritten, NULL)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
status = DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (device->halfduplex) {
|
||||
// Get the current time.
|
||||
if (!QueryPerformanceCounter(&end)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
status = DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
status = syserror (errcode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -503,8 +532,9 @@ dc_serial_purge (dc_serial_t *device, dc_direction_t direction)
|
||||
}
|
||||
|
||||
if (!PurgeComm (device->hFile, flags)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -519,8 +549,9 @@ dc_serial_flush (dc_serial_t *device)
|
||||
INFO (device->context, "Flush: none");
|
||||
|
||||
if (!FlushFileBuffers (device->hFile)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -536,13 +567,15 @@ dc_serial_set_break (dc_serial_t *device, unsigned int level)
|
||||
|
||||
if (level) {
|
||||
if (!SetCommBreak (device->hFile)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
} else {
|
||||
if (!ClearCommBreak (device->hFile)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,8 +593,9 @@ dc_serial_set_dtr (dc_serial_t *device, unsigned int level)
|
||||
int status = (level ? SETDTR : CLRDTR);
|
||||
|
||||
if (!EscapeCommFunction (device->hFile, status)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -578,8 +612,9 @@ dc_serial_set_rts (dc_serial_t *device, unsigned int level)
|
||||
int status = (level ? SETRTS : CLRRTS);
|
||||
|
||||
if (!EscapeCommFunction (device->hFile, status)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -594,8 +629,9 @@ dc_serial_get_available (dc_serial_t *device, size_t *value)
|
||||
COMSTAT stats;
|
||||
|
||||
if (!ClearCommError (device->hFile, NULL, &stats)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
if (value)
|
||||
@ -614,8 +650,9 @@ dc_serial_get_lines (dc_serial_t *device, unsigned int *value)
|
||||
|
||||
DWORD stats = 0;
|
||||
if (!GetCommModemStatus (device->hFile, &stats)) {
|
||||
SYSERROR (device->context, GetLastError ());
|
||||
return DC_STATUS_IO;
|
||||
DWORD errcode = GetLastError ();
|
||||
SYSERROR (device->context, errcode);
|
||||
return syserror (errcode);
|
||||
}
|
||||
|
||||
if (stats & MS_RLSD_ON)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user