Skip to content

Commit 637fb20

Browse files
committed
network.c: Properly handle return values of WSAStartup()
WSAStartup() returns 0 on success and positive error codes (WSA error codes) on failure. Checking if ret < 0 won't catch any error. https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup Signed-off-by: Dan Nechita <dan.nechita@analog.com>
1 parent 571ed98 commit 637fb20

File tree

1 file changed

+67
-6
lines changed

1 file changed

+67
-6
lines changed

network.c

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,59 @@
5454
#ifndef MSG_NOSIGNAL
5555
#define MSG_NOSIGNAL 0
5656
#endif
57+
58+
static int translate_wsa_error_to_posix(int wsa_err)
59+
{
60+
switch (wsa_err) {
61+
case WSAEACCES: return -EACCES;
62+
case WSAEADDRINUSE: return -EADDRINUSE;
63+
case WSAEADDRNOTAVAIL: return -EADDRNOTAVAIL;
64+
case WSAEAFNOSUPPORT: return -EAFNOSUPPORT;
65+
case WSAEALREADY: return -EALREADY;
66+
case WSAECONNREFUSED: return -ECONNREFUSED;
67+
case WSAECONNRESET: return -ECONNRESET;
68+
case WSAECONNABORTED: return -ECONNABORTED;
69+
case WSAEFAULT: return -EFAULT;
70+
case WSAEINPROGRESS: return -EINPROGRESS;
71+
case WSAEISCONN: return -EISCONN;
72+
case WSAEMFILE: return -EMFILE;
73+
case WSAENETDOWN: return -ENETDOWN;
74+
case WSAENETUNREACH: return -ENETUNREACH;
75+
case WSAENOBUFS: return -ENOBUFS;
76+
case WSAENOTSOCK: return -ENOTSOCK;
77+
case WSAEPROTONOSUPPORT: return -EPROTONOSUPPORT;
78+
case WSAETIMEDOUT: return -ETIMEDOUT;
79+
case WSAEHOSTUNREACH: return -EHOSTUNREACH;
80+
case WSAEINVAL: return -EINVAL;
81+
case WSAEWOULDBLOCK: return -EAGAIN;
82+
#ifdef ESHUTDOWN
83+
case WSAESHUTDOWN: return -ESHUTDOWN;
84+
#else
85+
case WSAESHUTDOWN: return -ECONNABORTED;
86+
#endif
87+
case WSAENOTCONN: return -ENOTCONN;
88+
case WSAEOPNOTSUPP: return -EOPNOTSUPP;
89+
default: {
90+
if (wsa_err > -4096 && wsa_err < 0) // pass through for POSIX errors
91+
return wsa_err;
92+
else
93+
return -EIO; // generic fallback
94+
}
95+
}
96+
}
5797
#endif
5898

99+
/* Helper function to translate WSA errors to POSIX at API boundary.
100+
ret is expected to be negative. */
101+
static int translate_error_for_api(int ret)
102+
{
103+
#ifdef _WIN32
104+
if (ret < 0)
105+
return translate_wsa_error_to_posix(-ret);
106+
#endif
107+
return ret;
108+
}
109+
59110
#define NETWORK_TIMEOUT_MS 5000
60111

61112
struct iio_context_pdata {
@@ -326,6 +377,7 @@ network_setup_iiod_client(const struct iio_device *dev,
326377
* See commit 9eff490 for more info.
327378
*/
328379
ret = create_socket(pdata->addrinfo, NETWORK_TIMEOUT_MS);
380+
ret = translate_error_for_api(ret);
329381
if (ret < 0) {
330382
dev_perror(dev, ret, "Unable to create socket");
331383
return iio_ptr(ret);
@@ -348,6 +400,7 @@ network_setup_iiod_client(const struct iio_device *dev,
348400
}
349401

350402
ret = set_blocking_mode(io_ctx->fd, false);
403+
ret = translate_error_for_api(ret);
351404
if (ret < 0) {
352405
dev_perror(dev, ret, "Unable to set blocking mode");
353406
goto err_free_iiod_client;
@@ -380,7 +433,8 @@ static ssize_t network_read_attr(const struct iio_attr *attr,
380433
const struct iio_context *ctx = iio_device_get_context(dev);
381434
struct iio_context_pdata *pdata = iio_context_get_pdata(ctx);
382435

383-
return iiod_client_attr_read(pdata->iiod_client, attr, dst, len);
436+
return (ssize_t)translate_error_for_api(
437+
(int)iiod_client_attr_read(pdata->iiod_client, attr, dst, len));
384438
}
385439

386440
static ssize_t network_write_attr(const struct iio_attr *attr,
@@ -390,7 +444,8 @@ static ssize_t network_write_attr(const struct iio_attr *attr,
390444
const struct iio_context *ctx = iio_device_get_context(dev);
391445
struct iio_context_pdata *pdata = iio_context_get_pdata(ctx);
392446

393-
return iiod_client_attr_write(pdata->iiod_client, attr, src, len);
447+
return (ssize_t)translate_error_for_api(
448+
(int)iiod_client_attr_write(pdata->iiod_client, attr, src, len));
394449
}
395450

396451
static const struct iio_device *
@@ -408,7 +463,8 @@ static int network_set_trigger(const struct iio_device *dev,
408463
const struct iio_context *ctx = iio_device_get_context(dev);
409464
struct iio_context_pdata *pdata = iio_context_get_pdata(ctx);
410465

411-
return iiod_client_set_trigger(pdata->iiod_client, dev, trigger);
466+
return translate_error_for_api(
467+
iiod_client_set_trigger(pdata->iiod_client, dev, trigger));
412468
}
413469

414470
static void network_shutdown(struct iio_context *ctx)
@@ -553,13 +609,15 @@ static ssize_t network_write_data(struct iiod_client_pdata *io_ctx,
553609
const char *src, size_t len,
554610
unsigned int timeout_ms)
555611
{
556-
return network_send(io_ctx, src, len, MSG_NOSIGNAL, timeout_ms);
612+
return (ssize_t)translate_error_for_api(
613+
(int)network_send(io_ctx, src, len, MSG_NOSIGNAL, timeout_ms));
557614
}
558615

559616
static ssize_t network_read_data(struct iiod_client_pdata *io_ctx,
560617
char *dst, size_t len, unsigned int timeout_ms)
561618
{
562-
return network_recv(io_ctx, dst, len, 0, timeout_ms);
619+
return (ssize_t)translate_error_for_api(
620+
(int)network_recv(io_ctx, dst, len, 0, timeout_ms));
563621
}
564622

565623
static struct iio_context * network_create_context(const struct iio_context_params *params,
@@ -586,7 +644,8 @@ static struct iio_context * network_create_context(const struct iio_context_para
586644
WSADATA wsaData;
587645

588646
ret = WSAStartup(MAKEWORD(2, 0), &wsaData);
589-
if (ret < 0) {
647+
if (ret != 0) {
648+
ret = translate_wsa_error_to_posix(ret);
590649
prm_perror(params, ret, "WSAStartup failed");
591650
return iio_ptr(ret);
592651
}
@@ -655,6 +714,7 @@ static struct iio_context * network_create_context(const struct iio_context_para
655714

656715
ret = dnssd_discover_host(params, addr_str,
657716
sizeof(addr_str), &port_num);
717+
ret = translate_error_for_api(ret);
658718
if (ret < 0) {
659719
char buf[1024];
660720
iio_strerror(-ret, buf, sizeof(buf));
@@ -711,6 +771,7 @@ static struct iio_context * network_create_context(const struct iio_context_para
711771
}
712772

713773
fd = create_socket(res, params->timeout_ms);
774+
fd = translate_error_for_api(fd);
714775
if (fd < 0) {
715776
ret = fd;
716777
goto err_free_addrinfo;

0 commit comments

Comments
 (0)