Skip to content

Commit

Permalink
Read WSA socket errors
Browse files Browse the repository at this point in the history
  • Loading branch information
FreddieAkeroyd committed Jan 20, 2025
1 parent 83ce4d0 commit 1fad5ba
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 24 deletions.
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

0 comments on commit 1fad5ba

Please sign in to comment.