Line data Source code
1 : #include "common.h"
2 :
3 : #if HAVE_UNISTD_H
4 : #include <unistd.h>
5 : #endif /* HAVE_UNISTD_H */
6 :
7 : #if HAVE_SYS_SOCKET_H
8 : #include <sys/socket.h>
9 : #endif /* HAVE_SYS_SOCKET_H */
10 :
11 : #if HAVE_SYS_STAT_H
12 : #include <sys/stat.h>
13 : #endif /* HAVE_SYS_STAT_H */
14 :
15 : #if HAVE_SYS_IOCTL_H
16 : #include <sys/ioctl.h>
17 : #endif /* HAVE_SYS_IOCTL_H */
18 :
19 : #if HAVE_SYS_WAIT_H
20 : #include <sys/wait.h>
21 : #endif /* HAVE_SYS_WAIT_H */
22 :
23 : #include <freetds/utils.h>
24 :
25 : /*
26 : * test error on connection close
27 : * With a trick we simulate a connection close then we try to
28 : * prepare or execute a query. This should fail and return an error message.
29 : */
30 :
31 : #ifdef _WIN32
32 : #define SHUT_RDWR SD_BOTH
33 : #endif
34 :
35 : static int
36 32 : close_last_socket(void)
37 : {
38 32 : TDS_SYS_SOCKET max_socket = odbc_find_last_socket();
39 :
40 32 : if (max_socket < 0) {
41 0 : fprintf(stderr, "Error finding last socket\n");
42 0 : return 0;
43 : }
44 :
45 : /* close connection */
46 32 : shutdown(max_socket, SHUT_RDWR);
47 :
48 32 : return 1;
49 : }
50 :
51 : static int
52 32 : Test(int direct, int long_query)
53 : {
54 : SQLTCHAR buf[256];
55 : SQLTCHAR sqlstate[6];
56 : char sql[5100];
57 :
58 32 : odbc_mark_sockets_opened();
59 32 : odbc_connect();
60 :
61 32 : if (!close_last_socket()) {
62 0 : fprintf(stderr, "Error closing connection\n");
63 0 : return 1;
64 : }
65 :
66 32 : if (long_query) {
67 16 : memset(sql, '-', sizeof(sql));
68 16 : strcpy(sql + 5000, "\nSELECT 1");
69 : } else {
70 16 : strcpy(sql, "SELECT 1");
71 : }
72 :
73 : /* force disconnection closing socket */
74 32 : if (direct) {
75 16 : CHKExecDirect(T(sql), SQL_NTS, "E");
76 : } else {
77 : SQLSMALLINT cols;
78 : /* use prepare, force dialog with server */
79 16 : if (CHKPrepare(T(sql), SQL_NTS, "SE") == SQL_SUCCESS)
80 12 : CHKNumResultCols(&cols, "E");
81 : }
82 :
83 32 : CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, buf, TDS_VECTOR_SIZE(buf), NULL, "SI");
84 32 : sqlstate[5] = 0;
85 32 : printf("state=%s err=%s\n", C(sqlstate), C(buf));
86 :
87 32 : odbc_disconnect();
88 :
89 32 : printf("Done.\n");
90 32 : return 0;
91 : }
92 :
93 : int
94 8 : main(void)
95 : {
96 : /* check with short queries */
97 8 : if (Test(0, 0) || Test(1, 0))
98 : return 1;
99 :
100 : /* check with large queries, this will trigger different paths */
101 8 : if (Test(0, 1) || Test(1, 1))
102 : return 1;
103 : return 0;
104 : }
|