📄 overrides.c
字号:
int rc = getsockopt(fd - SOCK_SHIFT, level, option, optval, optlen); if (rc < 0) errno = WSAGetLastError(); TRACE("fd %d, level %d, option %d -> rc %d; %s", fd, level, option, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_pipe(int *fds){ HANDLE rd_pipe, wr_pipe; if (!CreatePipe(&rd_pipe,&wr_pipe,NULL,0)) { errno = WSAGetLastError(); return (-1); } fds[0] = (int) rd_pipe; fds[1] = (int) wr_pipe; return 0;}static const char *timeval_str(const struct timeval *tv){ static unsigned char buf[30]; snprintf(buf, sizeof(buf), "%ld.%03ld", tv->tv_sec, tv->tv_usec/1000); return buf;}static char *fd_set_str(char *buf, size_t len, const fd_set *fd, int num_fds){ char *p = buf; char *end = buf + len; int i, num; for (i = num = 0; i < num_fds; i++) { if (FD_ISSET(i,fd)) { p += sprintf (p, "%d,", i); num++; } if (p > end - 12) { strcat(p, "<overflow>"); return buf; } } if (num == 0) return "<none set>"; return buf;}static voidselect_dump(int num_fds, const fd_set *rd, const fd_set *wr, const fd_set *ex){ char buf_rd[512], buf_wr[512], buf_ex[512]; TRACE("\tread-fds: %s\n" "\twrite-fds: %s\n" "\texcept-fds: %s\n", rd ? fd_set_str(buf_rd,sizeof(buf_rd),rd,num_fds) : "<none>", wr ? fd_set_str(buf_wr,sizeof(buf_wr),wr,num_fds) : "<none>", ex ? fd_set_str(buf_ex,sizeof(buf_ex),ex,num_fds) : "<none>");}static int select_read (int fd, struct fd_set *rd){ int rc = 0; HANDLE hnd = (HANDLE) fd; if (hnd == GetStdHandle(STD_INPUT_HANDLE)) { if (console_peek(hnd)) { FD_SET(fd, rd); rc++; } } else { hnd = (HANDLE) _get_osfhandle(fd); if (WaitForSingleObject(hnd, 0) == WAIT_OBJECT_0) { FD_SET (fd, rd); rc++; } } return rc;}static intselect_one_loop(int num_fds, struct fd_set *rd, struct fd_set *wr, struct fd_set *ex){ struct timeval tv = { 0, 100 }; int rc, fd; for (rc = fd = 0; fd < num_fds; fd++) { HANDLE hnd = (HANDLE)fd; if (GetFileType(hnd) == FILE_TYPE_PIPE) { DWORD read = 0; if (PeekNamedPipe(hnd, NULL, 0, NULL, &read, NULL) && read > 0) { FD_SET (fd, rd); rc++; } } else if (fd < SOCK_SHIFT) { if (FD_ISSET(fd,rd)) rc += select_read(fd, rd); if (FD_ISSET(fd,wr)) rc++; /* assume always writable */ } else { /* A Winsock socket */ fd_set sock_rd, sock_wr, sock_ex; int sel_rc; FD_ZERO(&sock_rd); FD_ZERO(&sock_wr); FD_ZERO(&sock_ex); FD_SET(fd - SOCK_SHIFT, &sock_rd); FD_SET(fd - SOCK_SHIFT, &sock_wr); FD_SET(fd - SOCK_SHIFT, &sock_ex); sel_rc = select(fd + 1, &sock_rd, NULL, NULL, &tv); if (sel_rc > 0) { FD_SET(fd, rd); rc++; } else if (sel_rc < 0) { errno = WSAGetLastError(); } sel_rc = select(fd + 1, NULL, &sock_wr, NULL, &tv); if (sel_rc > 0) { FD_SET (fd, wr); rc++; } else if (sel_rc < 0) { errno = WSAGetLastError(); } sel_rc = select(fd + 1, NULL, NULL, &sock_ex, &tv); if (sel_rc > 0) { FD_SET (fd, ex); rc++; } else if (sel_rc < 0) { errno = WSAGetLastError(); } } } return (rc);}int win32_select (int num_fds, struct fd_set *rd, struct fd_set *wr, struct fd_set *ex, struct timeval *tv){ struct fd_set tmp_rd, tmp_wr, tmp_ex; struct timeval expiry, start_time; int fd, rc; BOOL expired = FALSE; TRACE("in: num-fd %d, %s%s%s, tv %s", num_fds, rd ? "r" : "-", wr ? "w" : "-", ex ? "x" : "-", tv ? timeval_str(tv) : "NULL"); if (get_cmd_opt_int("verbose") == 2) select_dump(num_fds, rd, wr, ex); FD_ZERO(&tmp_rd); FD_ZERO(&tmp_wr); FD_ZERO(&tmp_ex); if (tv) { gettimeofday(&start_time, NULL); expiry.tv_sec = start_time.tv_sec + tv->tv_sec; expiry.tv_usec = start_time.tv_usec + tv->tv_usec; /* TODO: Move to gettimeofday() implementation? --jonas */ while (expiry.tv_usec >= 1000000L) { expiry.tv_usec -= 1000000L; expiry.tv_sec++; } } errno = 0; for (rc = 0; !expired; ) { rc += select_one_loop (num_fds, &tmp_rd, &tmp_wr, &tmp_ex); if (tv) { struct timeval now; gettimeofday(&now, NULL); if (now.tv_sec > expiry.tv_sec || (now.tv_sec == expiry.tv_sec && now.tv_usec >= expiry.tv_usec)) expired = TRUE; } if (rc) break; } /* Copy fd_sets to output */ if (rd) FD_ZERO(rd); if (wr) FD_ZERO(wr); if (ex) FD_ZERO(ex); for (fd = 0; fd < num_fds; fd++) { if (rd && FD_ISSET(fd,&tmp_rd)) FD_SET (fd, rd); if (wr && FD_ISSET(fd,&tmp_wr)) FD_SET (fd, wr); if (ex && FD_ISSET(fd,&tmp_ex)) FD_SET (fd, ex); } TRACE("-> rc %d, err %d", rc, rc < 0 ? errno : 0); if (get_cmd_opt_int("verbose") == 2) select_dump(num_fds, rd, wr, ex); if (get_cmd_opt_int("verbose") == 2) Sleep (400); else Sleep (0); return rc;}/* This function handles most Winsock errors we're able to produce. */static char *get_winsock_error(int err, char *buf, size_t len){ char *p; switch (err) { case WSAEINTR: p = "Call interrupted."; break; case WSAEBADF: p = "Bad file"; break; case WSAEACCES: p = "Bad access"; break; case WSAEFAULT: p = "Bad argument"; break; case WSAEINVAL: p = "Invalid arguments"; break; case WSAEMFILE: p = "Out of file descriptors"; break; case WSAEWOULDBLOCK: p = "Call would block"; break; case WSAEINPROGRESS: case WSAEALREADY: p = "Blocking call progress"; break; case WSAENOTSOCK: p = "Descriptor is not a socket."; break; case WSAEDESTADDRREQ: p = "Need destination address"; break; case WSAEMSGSIZE: p = "Bad message size"; break; case WSAEPROTOTYPE: p = "Bad protocol"; break; case WSAENOPROTOOPT: p = "Protocol option is unsupported"; break; case WSAEPROTONOSUPPORT: p = "Protocol is unsupported"; break; case WSAESOCKTNOSUPPORT: p = "Socket is unsupported"; break; case WSAEOPNOTSUPP: p = "Operation not supported"; break; case WSAEAFNOSUPPORT: p = "Address family not supported"; break; case WSAEPFNOSUPPORT: p = "Protocol family not supported"; break; case WSAEADDRINUSE: p = "Address already in use"; break; case WSAEADDRNOTAVAIL: p = "Address not available"; break; case WSAENETDOWN: p = "Network down"; break; case WSAENETUNREACH: p = "Network unreachable"; break; case WSAENETRESET: p = "Network has been reset"; break; case WSAECONNABORTED: p = "Connection was aborted"; break; case WSAECONNRESET: p = "Connection was reset"; break; case WSAENOBUFS: p = "No buffer space"; break; case WSAEISCONN: p = "Socket is already connected"; break; case WSAENOTCONN: p = "Socket is not connected"; break; case WSAESHUTDOWN: p = "Socket has been shut down"; break; case WSAETOOMANYREFS: p = "Too many references"; break; case WSAETIMEDOUT: p = "Timed out"; break; case WSAECONNREFUSED: p = "Connection refused"; break; case WSAELOOP: p = "Loop??"; break; case WSAENAMETOOLONG: p = "Name too long"; break; case WSAEHOSTDOWN: p = "Host down"; break; case WSAEHOSTUNREACH: p = "Host unreachable"; break; case WSAENOTEMPTY: p = "Not empty"; break; case WSAEPROCLIM: p = "Process limit reached"; break; case WSAEUSERS: p = "Too many users"; break; case WSAEDQUOT: p = "Bad quota"; break; case WSAESTALE: p = "Something is stale"; break; case WSAEREMOTE: p = "Remote error"; break; case WSAEDISCON: p = "Disconnected"; break; /* Extended Winsock errors */ case WSASYSNOTREADY: p = "Winsock library is not ready"; break; case WSANOTINITIALISED: p = "Winsock library not initalised"; break; case WSAVERNOTSUPPORTED: p = "Winsock version not supported."; break; /* getXbyY() errors (already handled in herrmsg): Authoritative Answer: Host not found */ case WSAHOST_NOT_FOUND: p = "Host not found"; break; /* Non-Authoritative: Host not found, or SERVERFAIL */ case WSATRY_AGAIN: p = "Host not found, try again"; break; /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ case WSANO_RECOVERY: p = "Unrecoverable error in call to nameserver"; break; /* Valid name, no data record of requested type */ case WSANO_DATA: p = "No data record of requested type"; break; default: return NULL; } strncpy(buf, p, len); buf[len - 1] = '\0'; return buf;}/* A smarter strerror() */char *win32_strerror(int err){ static char buf[512]; char *p; if (err >= 0 && err < sys_nerr) { strncpy(buf, strerror(err), sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; } else { if (!get_winsock_error(err, buf, sizeof(buf)) && !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, LANG_NEUTRAL, buf, sizeof(buf)-1, NULL)) sprintf (buf, "Unknown error %d (%#x)", err, err); } /* strip trailing '\r\n' or '\n'. */ if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2) *p = '\0'; if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1) *p = '\0'; return buf;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -