Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read WSA socket errors #31

Merged
merged 1 commit into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions asyn/drvAsynSerial/drvAsynIPPort.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ connectIt(void *drvPvt, asynUser *pasynUser)
SOCKET fd;
int i;
int sockOpt;
char sockerrmsg[256];

/*
* Sanity check
Expand Down Expand Up @@ -440,8 +441,9 @@ connectIt(void *drvPvt, asynUser *pasynUser)
* Create the socket
*/
if ((fd = epicsSocketCreate(tty->farAddr.oa.sa.sa_family, tty->socketType, 0)) < 0) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't create socket: %s", strerror(SOCKERRNO));
"Can't create socket: %s", sockerrmsg);
return asynError;
}

Expand All @@ -451,9 +453,10 @@ connectIt(void *drvPvt, asynUser *pasynUser)
i = 1;
if ((tty->flags & FLAG_BROADCAST)
&& (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void *)&i, sizeof i) < 0)) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't set %s socket BROADCAST option: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
epicsSocketDestroy(fd);
return asynError;
}
Expand All @@ -469,9 +472,10 @@ connectIt(void *drvPvt, asynUser *pasynUser)
#endif
if ((tty->flags & FLAG_SO_REUSEPORT)
&& (setsockopt(fd, SOL_SOCKET, sockOpt, (void *)&i, sizeof i) < 0)) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't set %s socket SO_REUSEPORT option: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
epicsSocketDestroy(fd);
return asynError;
}
Expand All @@ -498,8 +502,9 @@ connectIt(void *drvPvt, asynUser *pasynUser)
*/
if (tty->localAddrSize > 0) {
if (bind(fd, &tty->localAddr.sa, tty->localAddrSize)) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"unable to bind to local port: %s", strerror(SOCKERRNO));
"unable to bind to local port: %s", sockerrmsg);
epicsSocketDestroy(fd);
return asynError;
}
Expand All @@ -512,9 +517,10 @@ connectIt(void *drvPvt, asynUser *pasynUser)
*/
if (tty->socketType != SOCK_DGRAM) {
if (connect(fd, &tty->farAddr.oa.sa, (int)tty->farAddrSize) < 0) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't connect to %s: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
epicsSocketDestroy(fd);
if (tty->flags & FLAG_DONE_LOOKUP)
tty->flags |= FLAG_NEED_LOOKUP;
Expand All @@ -526,17 +532,19 @@ connectIt(void *drvPvt, asynUser *pasynUser)
if ((tty->socketType == SOCK_STREAM)
&& (tty->farAddr.oa.sa.sa_family == AF_INET)
&& (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&i, sizeof i) < 0)) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't set %s socket NODELAY option: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
epicsSocketDestroy(fd);
return asynError;
}
#ifdef USE_POLL
if (setNonBlock(fd, 1) < 0) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't set %s O_NONBLOCK option: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
epicsSocketDestroy(fd);
return asynError;
}
Expand Down Expand Up @@ -588,6 +596,7 @@ static asynStatus writeIt(void *drvPvt, asynUser *pasynUser,
epicsTimeStamp startTime;
epicsTimeStamp endTime;
int haveStartTime;
char sockerrmsg[256];

assert(tty);
asynPrint(pasynUser, ASYN_TRACE_FLOW,
Expand Down Expand Up @@ -621,9 +630,10 @@ static asynStatus writeIt(void *drvPvt, asynUser *pasynUser,
tv.tv_sec = writePollmsec / 1000;
tv.tv_usec = (writePollmsec % 1000) * 1000;
if (setsockopt(tty->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv) < 0) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't set %s socket send timeout: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
return asynError;
}
}
Expand All @@ -637,9 +647,10 @@ static asynStatus writeIt(void *drvPvt, asynUser *pasynUser,
pollfd.events = POLLOUT;
epicsTimeGetCurrent(&startTime);
while ((pollstatus = poll(&pollfd, 1, writePollmsec)) < 0) {
if (errno != EINTR) {
if (SOCKERRNO != SOCK_EINTR) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"%s poll() failed: %s", tty->IPDeviceName, strerror(errno));
"%s poll() failed: %s", tty->IPDeviceName, sockerrmsg);
return asynError;
}
epicsTimeGetCurrent(&endTime);
Expand Down Expand Up @@ -690,9 +701,10 @@ static asynStatus writeIt(void *drvPvt, asynUser *pasynUser,
break;
}
else {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
"%s write error: %s", tty->IPDeviceName,
strerror(SOCKERRNO));
sockerrmsg);
closeConnection(pasynUser,tty,"Write error");
status = asynError;
break;
Expand All @@ -718,6 +730,7 @@ static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
epicsTimeStamp startTime;
epicsTimeStamp endTime;
asynStatus status = asynSuccess;
char sockerrmsg[256];

assert(tty);
asynPrint(pasynUser, ASYN_TRACE_FLOW,
Expand Down Expand Up @@ -747,9 +760,10 @@ static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
tv.tv_sec = readPollmsec / 1000;
tv.tv_usec = (readPollmsec % 1000) * 1000;
if (setsockopt(tty->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) < 0) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Can't set %s socket receive timeout: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
status = asynError;
}
}
Expand All @@ -762,9 +776,10 @@ static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
pollfd.events = POLLIN;
epicsTimeGetCurrent(&startTime);
while (poll(&pollfd, 1, readPollmsec) < 0) {
if (errno != EINTR) {
if (SOCKERRNO != SOCK_EINTR) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Poll() failed: %s", strerror(errno));
"Poll() failed: %s", sockerrmsg);
return asynError;
}
epicsTimeGetCurrent(&endTime);
Expand Down Expand Up @@ -798,16 +813,17 @@ static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
if (thisRead < 0) {
int should_disconnect = (((tty->disconnectOnReadTimeout) && (pasynUser->timeout > 0)) ||
((SOCKERRNO != SOCK_EWOULDBLOCK) && (SOCKERRNO != SOCK_EINTR)));
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
if (should_disconnect) {
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"%s read error: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
closeConnection(pasynUser,tty,"Read error");
status = asynError;
} else {
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"%s timeout: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
status = asynTimeout;
}
}
Expand Down
26 changes: 18 additions & 8 deletions asyn/drvAsynSerial/drvAsynIPServerPort.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
int reason = 0;
int x;
asynStatus status = asynSuccess;
char sockerrmsg[256];

assert(tty);
asynPrint(pasynUser, ASYN_TRACE_FLOW,
Expand Down Expand Up @@ -212,16 +213,17 @@ static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
tty->nRead += thisRead;
}
if (thisRead < 0) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
if ((SOCKERRNO != SOCK_EINTR)) {
epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
"%s read error: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
closeConnection(pasynUser, tty);
status = asynError;
} else {
epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
"%s timeout: %s",
tty->IPDeviceName, strerror(SOCKERRNO));
tty->IPDeviceName, sockerrmsg);
status = asynTimeout;
}
}
Expand Down Expand Up @@ -295,6 +297,7 @@ static void connectionListener(void *drvPvt)
int i;
portList_t *pl, *p;
int connected;
char sockerrmsg[256];

/*
* Sanity check
Expand Down Expand Up @@ -328,9 +331,10 @@ static void connectionListener(void *drvPvt)
"drvAsynIPServerPort: new connection, socket=%d on %s\n",
clientFd, tty->serverInfo);
if (clientFd < 0) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
asynPrint(pasynUser, ASYN_TRACE_ERROR,
"drvAsynIPServerPort: accept error on %s: fd=%d, %s\n", tty->serverInfo,
tty->fd, strerror(errno));
tty->fd, sockerrmsg);
continue;
}
/* Search for a port which is disconnected */
Expand Down Expand Up @@ -384,13 +388,15 @@ int createServerSocket(ttyController_t *tty) {
struct sockaddr_in serverAddr;
int oneVal=1;
char srvaddrtxt[256];
char sockerrmsg[256];
assert(tty);
/*
* Create the socket
*/
if (tty->fd == INVALID_SOCKET) {
if ((tty->fd = (int)epicsSocketCreate(PF_INET, tty->socketType, 0)) < 0) {
printf("Can't create socket: %s", strerror(SOCKERRNO));
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
printf("Can't create socket: %s", sockerrmsg);
return -1;
}

Expand All @@ -406,8 +412,9 @@ int createServerSocket(ttyController_t *tty) {
if (tty->interfaceInfo != NULL && *tty->interfaceInfo &&
epicsStrCaseCmp(tty->interfaceInfo, "localhost")) {
if (hostToIPAddr(tty->interfaceInfo, &serverAddr.sin_addr) < 0) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
printf("using ANY interface, cannot lookup '%s': %s\n",
tty->interfaceInfo, strerror(SOCKERRNO));
tty->interfaceInfo, sockerrmsg);
return -1;
}
}
Expand All @@ -422,13 +429,15 @@ int createServerSocket(ttyController_t *tty) {
epicsSocketEnableAddressUseForDatagramFanout(tty->fd);
}
if (setsockopt(tty->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&oneVal, sizeof(int))) {
printf("Error calling setsockopt %s: %s\n", tty->serverInfo, strerror(errno));
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
printf("Error calling setsockopt %s: %s\n", tty->serverInfo, sockerrmsg);
epicsSocketDestroy(tty->fd);
tty->fd = INVALID_SOCKET;
return -1;
}
if (bind(tty->fd, (struct sockaddr *) &serverAddr, sizeof (serverAddr)) < 0) {
printf("Error in binding %s: %s\n", tty->serverInfo, strerror(errno));
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
printf("Error in binding %s: %s\n", tty->serverInfo, sockerrmsg);
epicsSocketDestroy(tty->fd);
tty->fd = INVALID_SOCKET;
return -1;
Expand All @@ -440,8 +449,9 @@ int createServerSocket(ttyController_t *tty) {
if (tty->socketType != SOCK_DGRAM) {
i = listen(tty->fd, tty->maxClients);
if (i < 0) {
epicsSocketConvertErrnoToString(sockerrmsg, sizeof(sockerrmsg));
printf("Error calling listen() on %s: %s\n",
tty->serverInfo, strerror(errno));
tty->serverInfo, sockerrmsg);
epicsSocketDestroy(tty->fd);
tty->fd = INVALID_SOCKET;
return -1;
Expand Down
Loading