kopia lustrzana https://github.com/stlink-org/stlink
				
				
				
			
		
			
				
	
	
		
			269 wiersze
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			269 wiersze
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
| #ifdef __MINGW32__
 | |
| 
 | |
| #include "mingw.h"
 | |
| 
 | |
| #undef socket
 | |
| #undef connect
 | |
| #undef accept
 | |
| #undef shutdown
 | |
| 
 | |
| #include <string.h>
 | |
| #include <errno.h>
 | |
| #include <assert.h>
 | |
| 
 | |
| int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
 | |
| {
 | |
|     struct timeval timeout, *toptr;
 | |
|     fd_set ifds, ofds, efds, *ip, *op;
 | |
|     unsigned int i, rc;
 | |
| 
 | |
|     /* Set up the file-descriptor sets in ifds, ofds and efds. */
 | |
|     FD_ZERO(&ifds);
 | |
|     FD_ZERO(&ofds);
 | |
|     FD_ZERO(&efds);
 | |
|     for (i = 0, op = ip = 0; i < nfds; ++i) {
 | |
| 	fds[i].revents = 0;
 | |
| 	if(fds[i].events & (POLLIN|POLLPRI)) {
 | |
| 		ip = &ifds;
 | |
| 		FD_SET(fds[i].fd, ip);
 | |
| 	}
 | |
| 	if(fds[i].events & POLLOUT) {
 | |
| 		op = &ofds;
 | |
| 		FD_SET(fds[i].fd, op);
 | |
| 	}
 | |
| 	FD_SET(fds[i].fd, &efds);
 | |
|     } 
 | |
| 
 | |
|     /* Set up the timeval structure for the timeout parameter */
 | |
|     if(timo < 0) {
 | |
| 	toptr = 0;
 | |
|     } else {
 | |
| 	toptr = &timeout;
 | |
| 	timeout.tv_sec = timo / 1000;
 | |
| 	timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
 | |
|     }
 | |
| 
 | |
| #ifdef DEBUG_POLL
 | |
|     printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n",
 | |
|            (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op);
 | |
| #endif
 | |
|     rc = select(0, ip, op, &efds, toptr);
 | |
| #ifdef DEBUG_POLL
 | |
|     printf("Exiting select rc=%d\n", rc);
 | |
| #endif
 | |
| 
 | |
|     if(rc <= 0)
 | |
| 	return rc;
 | |
| 
 | |
|     if(rc > 0) {
 | |
|         for ( i = 0; i < nfds; ++i) {
 | |
|             int fd = fds[i].fd;
 | |
|     	if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds))
 | |
|     		fds[i].revents |= POLLIN;
 | |
|     	if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds))
 | |
|     		fds[i].revents |= POLLOUT;
 | |
|     	if(FD_ISSET(fd, &efds))
 | |
|     		/* Some error was detected ... should be some way to know. */
 | |
|     		fds[i].revents |= POLLHUP;
 | |
| #ifdef DEBUG_POLL
 | |
|         printf("%d %d %d revent = %x\n", 
 | |
|                 FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), 
 | |
|                 fds[i].revents
 | |
|         );
 | |
| #endif
 | |
|         }
 | |
|     }
 | |
|     return rc;
 | |
| }
 | |
| static void
 | |
| set_connect_errno(int winsock_err)
 | |
| {
 | |
|     switch(winsock_err) {
 | |
|         case WSAEINVAL:
 | |
|         case WSAEALREADY:
 | |
|         case WSAEWOULDBLOCK:
 | |
|             errno = EINPROGRESS;
 | |
|             break;
 | |
|         default:
 | |
|             errno = winsock_err;
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| set_socket_errno(int winsock_err)
 | |
| {
 | |
|     switch(winsock_err) {
 | |
|         case WSAEWOULDBLOCK:
 | |
|             errno = EAGAIN;
 | |
|             break;
 | |
|         default:
 | |
|             errno = winsock_err;
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| /*
 | |
|  * A wrapper around the socket() function. The purpose of this wrapper
 | |
|  * is to ensure that the global errno symbol is set if an error occurs,
 | |
|  * even if we are using winsock.
 | |
|  */
 | |
| SOCKET
 | |
| win32_socket(int domain, int type, int protocol)
 | |
| {
 | |
|     SOCKET fd = socket(domain, type, protocol);
 | |
|     if(fd == INVALID_SOCKET) {
 | |
|         set_socket_errno(WSAGetLastError());
 | |
|     }
 | |
|     return fd;
 | |
| }
 | |
| /*
 | |
|  * A wrapper around the connect() function. The purpose of this wrapper
 | |
|  * is to ensure that the global errno symbol is set if an error occurs,
 | |
|  * even if we are using winsock.
 | |
|  */
 | |
| int
 | |
| win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len)
 | |
| {
 | |
|     int rc = connect(fd, addr, addr_len);
 | |
|     assert(rc == 0 || rc == SOCKET_ERROR);
 | |
|     if(rc == SOCKET_ERROR) {
 | |
|         set_connect_errno(WSAGetLastError());
 | |
|     }
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * A wrapper around the accept() function. The purpose of this wrapper
 | |
|  * is to ensure that the global errno symbol is set if an error occurs,
 | |
|  * even if we are using winsock.
 | |
|  */
 | |
| SOCKET
 | |
| win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len)
 | |
| {
 | |
|     SOCKET newfd = accept(fd, addr, addr_len);
 | |
|     if(newfd == INVALID_SOCKET) {
 | |
|         set_socket_errno(WSAGetLastError());
 | |
|         newfd = -1;
 | |
|     }
 | |
|     return newfd;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * A wrapper around the shutdown() function. The purpose of this wrapper
 | |
|  * is to ensure that the global errno symbol is set if an error occurs,
 | |
|  * even if we are using winsock.
 | |
|  */
 | |
| int
 | |
| win32_shutdown(SOCKET fd, int mode)
 | |
| {
 | |
|     int rc = shutdown(fd, mode);
 | |
|     assert(rc == 0 || rc == SOCKET_ERROR);
 | |
|     if(rc == SOCKET_ERROR) {
 | |
|         set_socket_errno(WSAGetLastError());
 | |
|     }
 | |
|     return rc;
 | |
| }
 | |
| int win32_close_socket(SOCKET fd) {
 | |
|     int rc;
 | |
| 
 | |
|     rc = closesocket(fd);
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| 
 | |
| ssize_t win32_write_socket(SOCKET fd, void *buf, int n)
 | |
| {
 | |
|     int rc = send(fd, buf, n, 0);
 | |
|     if(rc == SOCKET_ERROR) {
 | |
|         set_socket_errno(WSAGetLastError());
 | |
|     }
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| ssize_t win32_read_socket(SOCKET fd, void *buf, int n)
 | |
| {
 | |
|     int rc = recv(fd, buf, n, 0);
 | |
|     if(rc == SOCKET_ERROR) {
 | |
|         set_socket_errno(WSAGetLastError());
 | |
|     }
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| 
 | |
| char * win32_strtok_r(char *s, const char *delim, char **lasts)
 | |
| {
 | |
| 	register char *spanp;
 | |
| 	register int c, sc;
 | |
| 	char *tok;
 | |
| 
 | |
| 
 | |
| 	if (s == NULL && (s = *lasts) == NULL)
 | |
| 		return (NULL);
 | |
| 
 | |
| 	/*
 | |
| 	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
 | |
| 	 */
 | |
| cont:
 | |
| 	c = *s++;
 | |
| 	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
 | |
| 		if (c == sc)
 | |
| 			goto cont;
 | |
| 	}
 | |
| 
 | |
| 	if (c == 0) {		/* no non-delimiter characters */
 | |
| 		*lasts = NULL;
 | |
| 		return (NULL);
 | |
| 	}
 | |
| 	tok = s - 1;
 | |
| 
 | |
| 	/*
 | |
| 	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
 | |
| 	 * Note that delim must have one NUL; we stop if we see that, too.
 | |
| 	 */
 | |
| 	for (;;) {
 | |
| 		c = *s++;
 | |
| 		spanp = (char *)delim;
 | |
| 		do {
 | |
| 			if ((sc = *spanp++) == c) {
 | |
| 				if (c == 0)
 | |
| 					s = NULL;
 | |
| 				else
 | |
| 					s[-1] = 0;
 | |
| 				*lasts = s;
 | |
| 				return (tok);
 | |
| 			}
 | |
| 		} while (sc != 0);
 | |
| 	}
 | |
| 	/* NOTREACHED */
 | |
| }
 | |
| 
 | |
| char *win32_strsep (char **stringp, const char *delim)
 | |
| {
 | |
| 	register char *s;
 | |
| 	register const char *spanp;
 | |
| 	register int c, sc;
 | |
| 	char *tok;
 | |
| 
 | |
| 	if ((s = *stringp) == NULL)
 | |
| 		return (NULL);
 | |
| 	for (tok = s;;) {
 | |
| 		c = *s++;
 | |
| 		spanp = delim;
 | |
| 		do {
 | |
| 			if ((sc = *spanp++) == c) {
 | |
| 				if (c == 0)
 | |
| 					s = NULL;
 | |
| 				else
 | |
| 					s[-1] = 0;
 | |
| 				*stringp = s;
 | |
| 				return (tok);
 | |
| 			}
 | |
| 		} while (sc != 0);
 | |
| 	}
 | |
| 	/* NOTREACHED */
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 
 |