📄 error.c
字号:
#if defined(WIN32) if (!std_redir) { HANDLE log_handle; int log_fd; struct security_attributes sa; init_security_attributes_allow_all (&sa); log_handle = CreateFile (file, GENERIC_WRITE, FILE_SHARE_READ, &sa.sa, append ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (log_handle == INVALID_HANDLE_VALUE) { msg (M_WARN|M_ERRNO, "Warning: cannot open --log file: %s", file); return; } /* append to logfile? */ if (append) { if (SetFilePointer (log_handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) msg (M_ERR, "Error: cannot seek to end of --log file: %s", file); } /* set up for redirection */ if (!SetStdHandle (STD_OUTPUT_HANDLE, log_handle) || !SetStdHandle (STD_ERROR_HANDLE, log_handle)) msg (M_ERR, "Error: cannot redirect stdout/stderr to --log file: %s", file); /* direct stdout/stderr to point to log_handle */ log_fd = _open_osfhandle ((intptr_t)log_handle, _O_TEXT); if (log_fd == -1) msg (M_ERR, "Error: --log redirect failed due to _open_osfhandle failure"); /* open log_handle as FILE stream */ ASSERT (msgfp == NULL); msgfp = _fdopen (log_fd, "w"); if (msgfp == NULL) msg (M_ERR, "Error: --log redirect failed due to _fdopen"); std_redir = true; }#elif defined(HAVE_DUP2) if (!std_redir) { int out = open (file, O_CREAT | O_WRONLY | (append ? O_APPEND : O_TRUNC), S_IRUSR | S_IWUSR); if (out < 0) { msg (M_WARN|M_ERRNO, "Warning: Error redirecting stdout/stderr to --log file: %s", file); return; } if (dup2 (out, 1) == -1) msg (M_ERR, "--log file redirection error on stdout"); if (dup2 (out, 2) == -1) msg (M_ERR, "--log file redirection error on stderr"); if (out > 2) close (out); std_redir = true; }#else msg (M_WARN, "WARNING: The --log option is not supported on this OS because it lacks the dup2 function");#endif}/* * Functions used to check return status * of I/O operations. */unsigned int x_cs_info_level; /* GLOBAL */unsigned int x_cs_verbose_level; /* GLOBAL */unsigned int x_cs_err_delay_ms; /* GLOBAL */voidreset_check_status (){ x_cs_info_level = 0; x_cs_verbose_level = 0;}voidset_check_status (unsigned int info_level, unsigned int verbose_level){ x_cs_info_level = info_level; x_cs_verbose_level = verbose_level;}/* * Called after most socket or tun/tap operations, via the inline * function check_status(). * * Decide if we should print an error message, and see if we can * extract any useful info from the error, such as a Path MTU hint * from the OS. */voidx_check_status (int status, const char *description, struct link_socket *sock, struct tuntap *tt){ const int my_errno = (sock ? openvpn_errno_socket () : openvpn_errno ()); const char *extended_msg = NULL; msg (x_cs_verbose_level, "%s %s returned %d", sock ? proto2ascii (sock->info.proto, true) : "", description, status); if (status < 0) { struct gc_arena gc = gc_new ();#if EXTENDED_SOCKET_ERROR_CAPABILITY /* get extended socket error message and possible PMTU hint from OS */ if (sock) { int mtu; extended_msg = format_extended_socket_error (sock->sd, &mtu, &gc); if (mtu > 0 && sock->mtu != mtu) { sock->mtu = mtu; sock->info.mtu_changed = true; } }#elif defined(WIN32) /* get possible driver error from TAP-Win32 driver */ extended_msg = tap_win32_getinfo (tt, &gc);#endif if (true) // JYFIXME: was: if (my_errno != EAGAIN) { if (extended_msg) msg (x_cs_info_level, "%s %s [%s]: %s (code=%d)", description, sock ? proto2ascii (sock->info.proto, true) : "", extended_msg, strerror_ts (my_errno, &gc), my_errno); else msg (x_cs_info_level, "%s %s: %s (code=%d)", description, sock ? proto2ascii (sock->info.proto, true) : "", strerror_ts (my_errno, &gc), my_errno); /* avoid a barrage of errors, JYFIXME -- set this to something */ if (x_cs_err_delay_ms) sleep_milliseconds (x_cs_err_delay_ms); } gc_free (&gc); }}/* * In multiclient mode, put a client-specific prefix * before each message. */const char *x_msg_prefix; /* GLOBAL */#ifdef USE_PTHREADpthread_key_t x_msg_prefix_key; /* GLOBAL */#endifvoidmsg_thread_init (void){#ifdef USE_PTHREAD ASSERT (!pthread_key_create (&x_msg_prefix_key, NULL));#endif}voidmsg_thread_uninit (void){#ifdef USE_PTHREAD pthread_key_delete (x_msg_prefix_key);#endif}/* * Exiting. */voidopenvpn_exit (int status){#ifdef WIN32 uninit_win32 ();#endif exit (status);}#ifdef WIN32const char *strerror_win32 (DWORD errnum, struct gc_arena *gc){ /* * This code can be omitted, though often the Windows * WSA error messages are less informative than the * Posix equivalents. */#if 1 switch (errnum) { /* * When the TAP-Win32 driver returns STATUS_UNSUCCESSFUL, this code * gets returned to user space. */ case ERROR_GEN_FAILURE: return "General failure (ERROR_GEN_FAILURE)"; case ERROR_IO_PENDING: return "I/O Operation in progress (ERROR_IO_PENDING)"; case WSA_IO_INCOMPLETE: return "I/O Operation in progress (WSA_IO_INCOMPLETE)"; case WSAEINTR: return "Interrupted system call (WSAEINTR)"; case WSAEBADF: return "Bad file number (WSAEBADF)"; case WSAEACCES: return "Permission denied (WSAEACCES)"; case WSAEFAULT: return "Bad address (WSAEFAULT)"; case WSAEINVAL: return "Invalid argument (WSAEINVAL)"; case WSAEMFILE: return "Too many open files (WSAEMFILE)"; case WSAEWOULDBLOCK: return "Operation would block (WSAEWOULDBLOCK)"; case WSAEINPROGRESS: return "Operation now in progress (WSAEINPROGRESS)"; case WSAEALREADY: return "Operation already in progress (WSAEALREADY)"; case WSAEDESTADDRREQ: return "Destination address required (WSAEDESTADDRREQ)"; case WSAEMSGSIZE: return "Message too long (WSAEMSGSIZE)"; case WSAEPROTOTYPE: return "Protocol wrong type for socket (WSAEPROTOTYPE)"; case WSAENOPROTOOPT: return "Bad protocol option (WSAENOPROTOOPT)"; case WSAEPROTONOSUPPORT: return "Protocol not supported (WSAEPROTONOSUPPORT)"; case WSAESOCKTNOSUPPORT: return "Socket type not supported (WSAESOCKTNOSUPPORT)"; case WSAEOPNOTSUPP: return "Operation not supported on socket (WSAEOPNOTSUPP)"; case WSAEPFNOSUPPORT: return "Protocol family not supported (WSAEPFNOSUPPORT)"; case WSAEAFNOSUPPORT: return "Address family not supported by protocol family (WSAEAFNOSUPPORT)"; case WSAEADDRINUSE: return "Address already in use (WSAEADDRINUSE)"; case WSAENETDOWN: return "Network is down (WSAENETDOWN)"; case WSAENETUNREACH: return "Network is unreachable (WSAENETUNREACH)"; case WSAENETRESET: return "Net dropped connection or reset (WSAENETRESET)"; case WSAECONNABORTED: return "Software caused connection abort (WSAECONNABORTED)"; case WSAECONNRESET: return "Connection reset by peer (WSAECONNRESET)"; case WSAENOBUFS: return "No buffer space available (WSAENOBUFS)"; case WSAEISCONN: return "Socket is already connected (WSAEISCONN)"; case WSAENOTCONN: return "Socket is not connected (WSAENOTCONN)"; case WSAETIMEDOUT: return "Connection timed out (WSAETIMEDOUT)"; case WSAECONNREFUSED: return "Connection refused (WSAECONNREFUSED)"; case WSAELOOP: return "Too many levels of symbolic links (WSAELOOP)"; case WSAENAMETOOLONG: return "File name too long (WSAENAMETOOLONG)"; case WSAEHOSTDOWN: return "Host is down (WSAEHOSTDOWN)"; case WSAEHOSTUNREACH: return "No Route to Host (WSAEHOSTUNREACH)"; case WSAENOTEMPTY: return "Directory not empty (WSAENOTEMPTY)"; case WSAEPROCLIM: return "Too many processes (WSAEPROCLIM)"; case WSAEUSERS: return "Too many users (WSAEUSERS)"; case WSAEDQUOT: return "Disc Quota Exceeded (WSAEDQUOT)"; case WSAESTALE: return "Stale NFS file handle (WSAESTALE)"; case WSASYSNOTREADY: return "Network SubSystem is unavailable (WSASYSNOTREADY)"; case WSAVERNOTSUPPORTED: return "WINSOCK DLL Version out of range (WSAVERNOTSUPPORTED)"; case WSANOTINITIALISED: return "Successful WSASTARTUP not yet performed (WSANOTINITIALISED)"; case WSAEREMOTE: return "Too many levels of remote in path (WSAEREMOTE)"; case WSAHOST_NOT_FOUND: return "Host not found (WSAHOST_NOT_FOUND)"; default: break; }#endif /* format a windows error message */ { char message[256]; struct buffer out = alloc_buf_gc (256, gc); const int status = FormatMessage ( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, errnum, 0, message, sizeof (message), NULL); if (!status) { buf_printf (&out, "[Unknown Win32 Error]"); } else { char *cp; for (cp = message; *cp != '\0'; ++cp) { if (*cp == '\n' || *cp == '\r') *cp = ' '; } buf_printf(&out, "%s", message); } return BSTR (&out); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -