示例#1
0
文件: net.c 项目: alex-fang/freetds
/**
 * Close current socket
 * for last socket close entire connection
 * for MARS send FIN request
 */
void
tds_close_socket(TDSSOCKET * tds)
{
	if (!IS_TDSDEAD(tds)) {
#if ENABLE_ODBC_MARS
		TDSCONNECTION *conn = tds->conn;
		unsigned n = 0, count = 0;
		tds_mutex_lock(&conn->list_mtx);
		for (; n < conn->num_sessions; ++n)
			if (TDSSOCKET_VALID(conn->sessions[n]))
				++count;
		if (count > 1)
			tds_append_fin(tds);
		tds_mutex_unlock(&conn->list_mtx);
		if (count <= 1) {
			tds_disconnect(tds);
			tds_connection_close(conn);
		} else {
			tds_set_state(tds, TDS_DEAD);
		}
#else
		tds_disconnect(tds);
		if (CLOSESOCKET(tds_get_s(tds)) == -1)
			tdserror(tds_get_ctx(tds), tds,  TDSECLOS, sock_errno);
		tds_set_s(tds, INVALID_SOCKET);
		tds_set_state(tds, TDS_DEAD);
#endif
	}
}
示例#2
0
/*
 * pool_user_create
 * accepts a client connection and adds it to the users list and returns it
 */
TDS_POOL_USER *
pool_user_create(TDS_POOL * pool, TDS_SYS_SOCKET s)
{
	TDS_POOL_USER *puser;
	TDS_SYS_SOCKET fd;
	TDSSOCKET *tds;
	LOGIN_EVENT *ev;

	tdsdump_log(TDS_DBG_NETWORK, "accepting connection\n");
	if (TDS_IS_SOCKET_INVALID(fd = tds_accept(s, NULL, NULL))) {
		char *errstr = sock_strerror(errno);
		tdsdump_log(TDS_DBG_ERROR, "error calling assert :%s\n", errstr);
		sock_strerror_free(errstr);
		return NULL;
	}

	if (tds_socket_set_nonblocking(fd) != 0) {
		CLOSESOCKET(fd);
		return NULL;
	}

	puser = pool_user_find_new(pool);
	if (!puser) {
		CLOSESOCKET(fd);
		return NULL;
	}

	tds = tds_alloc_socket(pool->ctx, BLOCKSIZ);
	if (!tds) {
		CLOSESOCKET(fd);
		return NULL;
	}
	ev = (LOGIN_EVENT *) calloc(1, sizeof(*ev));
	if (!ev || TDS_FAILED(tds_iconv_open(tds->conn, "UTF-8", 0))) {
		free(ev);
		tds_free_socket(tds);
		CLOSESOCKET(fd);
		return NULL;
	}
	/* FIX ME - little endian emulation should be config file driven */
	tds->conn->emul_little_endian = 1;
	tds_set_s(tds, fd);
	tds->state = TDS_IDLE;
	tds->out_flag = TDS_LOGIN;

	puser->sock.tds = tds;
	puser->user_state = TDS_SRV_QUERY;
	puser->sock.poll_recv = false;
	puser->sock.poll_send = false;

	/* launch login asyncronously */
	ev->puser = puser;
	ev->pool = pool;

	if (tds_thread_create_detached(login_proc, ev) != 0) {
		pool_free_user(pool, puser);
		fprintf(stderr, "error creating thread\n");
		return NULL;
	}

	return puser;
}