⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timeout3.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
#include "common.h"/* TODO port to windows, use thread */#if defined(TDS_HAVE_PTHREAD_MUTEX) && HAVE_ALARM#if HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#if TIME_WITH_SYS_TIME# if HAVE_SYS_TIME_H#  include <sys/time.h># endif# include <time.h>#else# if HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif#if HAVE_ERRNO_H#include <errno.h>#endif /* HAVE_ERRNO_H */#if HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif /* HAVE_SYS_SOCKET_H */#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif /* HAVE_NETINET_IN_H */#include <pthread.h>#include "tds.h"/*	test connection timeout*/static char software_version[] = "$Id: timeout3.c,v 1.6 2007/11/26 18:12:31 freddy77 Exp $";static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };static void init_connect(void);static voidinit_connect(void){	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {		printf("Unable to allocate env\n");		exit(1);	}	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {		printf("Unable to allocate connection\n");		SQLFreeEnv(Environment);		exit(1);	}}static pthread_t      fake_thread;static TDS_SYS_SOCKET fake_sock;static void *fake_thread_proc(void * arg);static intinit_fake_server(int ip_port){	struct sockaddr_in sin;	TDS_SYS_SOCKET s;	int err;	memset(&sin, 0, sizeof(sin));	sin.sin_addr.s_addr = INADDR_ANY;	sin.sin_port = htons((short) ip_port);	sin.sin_family = AF_INET;	if (TDS_IS_SOCKET_INVALID(s = socket(AF_INET, SOCK_STREAM, 0))) {		perror("socket");		exit(1);	}	if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {		perror("bind");		CLOSESOCKET(s);		return 1;	}	listen(s, 5);	err = pthread_create(&fake_thread, NULL, fake_thread_proc, int2ptr(s));	if (err != 0) {		perror("pthread_create");		exit(1);	}	return 0;}static void *fake_thread_proc(void * arg){	TDS_SYS_SOCKET s = ptr2int(arg);	socklen_t len;	char buf[128];	struct sockaddr_in sin;	memset(&sin, 0, sizeof(sin));	len = sizeof(sin);	alarm(30);	if ((fake_sock = accept(s, (struct sockaddr *) &sin, &len)) < 0) {		perror("accept");		exit(1);	}	CLOSESOCKET(s);	for (;;) {		/* just read and discard */		len = READSOCKET(fake_sock, buf, sizeof(buf));		if (len == 0)			break;		if (len < 0 && sock_errno != TDSSOCK_EINPROGRESS)			break;	}	return NULL;}intmain(int argc, char *argv[]){	int res;	char tmp[2048];	char sqlstate[6];	SQLSMALLINT len;	int port;	time_t start_time, end_time;	if (read_login_info())		exit(1);	/*	 * prepare our odbcinst.ini 	 * is better to do it before connect cause uniODBC cache INIs	 * the name must be odbcinst.ini cause unixODBC accept only this name	 */	if (DRIVER[0]) {		FILE *f = fopen("odbcinst.ini", "w");		if (f) {			fprintf(f, "[FreeTDS]\nDriver = %s\n", DRIVER);			fclose(f);			/* force iODBC */			setenv("ODBCINSTINI", "./odbcinst.ini", 1);			setenv("SYSODBCINSTINI", "./odbcinst.ini", 1);			/* force unixODBC (only directory) */			setenv("ODBCSYSINI", ".", 1);		}	}	for (port = 12340; port < 12350; ++port)		if (!init_fake_server(port))			break;	if (port == 12350) {		fprintf(stderr, "Cannot bind to a port\n");		return 1;	}	printf("Fake server binded at port %d\n", port);	init_connect();	res = SQLSetConnectAttr(Connection, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER) 10, sizeof(SQLINTEGER));	if (!SQL_SUCCEEDED(res))		ODBC_REPORT_ERROR("SQLSetConnectAttr error");	res = SQLSetConnectAttr(Connection, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) 10, sizeof(SQLINTEGER));	if (!SQL_SUCCEEDED(res))		ODBC_REPORT_ERROR("SQLSetConnectAttr error");	/* this is expected to work with unixODBC */	printf("try to connect to our port just to check connection timeout\n");	sprintf(tmp, "DRIVER=FreeTDS;SERVER=127.0.0.1;Port=%d;TDS_Version=7.0;UID=test;PWD=test;DATABASE=tempdb;", port);	start_time = time(NULL);	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);	if (SQL_SUCCEEDED(res)) {		fprintf(stderr, "SQLDriverConnect should fail (res=%d)\n", (int) res);		return 1;	}	end_time = time(NULL);	strcpy(sqlstate, "XXXXX");	tmp[0] = 0;	res = SQLGetDiagRec(SQL_HANDLE_DBC, Connection, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) tmp, sizeof(tmp), NULL);	if (!SQL_SUCCEEDED(res)) {		printf("SQLGetDiagRec should not fail\n");		return 1;	}	Disconnect();	CLOSESOCKET(fake_sock);	pthread_join(fake_thread, NULL);	printf("Message: %s - %s\n", sqlstate, tmp);	if (strcmp(sqlstate, "HYT00") || !strstr(tmp, "Timeout")) {		fprintf(stderr, "Invalid timeout message\n");		return 1;	}	if (end_time - start_time < 10 || end_time - start_time > 16) {		fprintf(stderr, "Unexpected connect timeout (%d)\n", (int) (end_time - start_time));		return 1;	}	printf("Done.\n");	return 0;}#else	/* !TDS_HAVE_PTHREAD_MUTEX */intmain(void){	printf("Not possible for this platform.\n");	return 0;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -