Line data Source code
1 : /*
2 : * Purpose: Test for dbsqlexec on closed connection
3 : */
4 :
5 : #include "common.h"
6 :
7 : #if HAVE_UNISTD_H
8 : #include <unistd.h>
9 : #endif /* HAVE_UNISTD_H */
10 :
11 : #include <freetds/time.h>
12 :
13 : #if HAVE_SYS_SOCKET_H
14 : #include <sys/socket.h>
15 : #endif /* HAVE_SYS_SOCKET_H */
16 :
17 : #if HAVE_SYS_STAT_H
18 : #include <sys/stat.h>
19 : #endif /* HAVE_SYS_STAT_H */
20 :
21 : #if HAVE_SYS_IOCTL_H
22 : #include <sys/ioctl.h>
23 : #endif /* HAVE_SYS_IOCTL_H */
24 :
25 : #if HAVE_SYS_WAIT_H
26 : #include <sys/wait.h>
27 : #endif /* HAVE_SYS_WAIT_H */
28 :
29 : #if HAVE_NETINET_IN_H
30 : #include <netinet/in.h>
31 : #endif /* HAVE_NET_INET_IN_H */
32 :
33 : #include <freetds/utils.h>
34 :
35 : #if HAVE_FSTAT && defined(S_IFSOCK)
36 :
37 : static char *UNITTEST;
38 : static int end_socket = -1;
39 :
40 : static int
41 20 : shutdown_socket(DBPROCESS *dbproc)
42 : {
43 : union {
44 : struct sockaddr sa;
45 : char data[256];
46 : } u;
47 : SOCKLEN_T addrlen;
48 : struct stat file_stat;
49 : TDS_SYS_SOCKET sockets[2];
50 :
51 20 : TDS_SYS_SOCKET socket = DBIOWDESC(dbproc);
52 :
53 20 : if (fstat(socket, &file_stat))
54 : return 0;
55 20 : if ((file_stat.st_mode & S_IFSOCK) != S_IFSOCK)
56 : return 0;
57 :
58 20 : addrlen = sizeof(u);
59 20 : if (tds_getsockname(socket, &u.sa, &addrlen) < 0 || (u.sa.sa_family != AF_INET && u.sa.sa_family != AF_INET6))
60 : return 0;
61 :
62 : /* replace socket with a new one */
63 20 : if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0)
64 : return 0;
65 :
66 20 : tds_socket_set_nosigpipe(sockets[0], 1);
67 :
68 : /* substitute socket */
69 20 : close(socket);
70 20 : dup2(sockets[0], socket);
71 :
72 : /* close connection */
73 20 : close(sockets[0]);
74 20 : end_socket = sockets[1];
75 20 : return 1;
76 : }
77 :
78 : static int
79 20 : test(int close_socket)
80 : {
81 : LOGINREC *login;
82 : DBPROCESS *dbproc;
83 : RETCODE ret;
84 20 : int expected_error = -1;
85 :
86 20 : printf("Starting %s\n", UNITTEST);
87 :
88 20 : dbinit();
89 :
90 20 : dberrhandle(syb_err_handler);
91 20 : dbmsghandle(syb_msg_handler);
92 :
93 20 : printf("About to logon\n");
94 :
95 20 : login = dblogin();
96 20 : DBSETLPWD(login, PASSWORD);
97 20 : DBSETLUSER(login, USER);
98 20 : DBSETLAPP(login, "hang");
99 :
100 20 : printf("About to open\n");
101 :
102 20 : dbproc = dbopen(login, SERVER);
103 20 : dbsetuserdata(dbproc, (BYTE*) &expected_error);
104 20 : if (strlen(DATABASE))
105 20 : dbuse(dbproc, DATABASE);
106 20 : dbloginfree(login);
107 :
108 20 : dbcmd(dbproc, "select * from sysobjects");
109 20 : printf("dbsqlexec should not hang.\n");
110 :
111 20 : ret = dbsettime(15);
112 20 : if (ret != SUCCEED) {
113 0 : fprintf(stderr, "Failed. Error setting timeout.\n");
114 0 : return 1;
115 : }
116 :
117 20 : if (!shutdown_socket(dbproc)) {
118 0 : fprintf(stderr, "Error shutting down connection\n");
119 0 : return 1;
120 : }
121 20 : if (close_socket)
122 10 : close(end_socket);
123 :
124 20 : alarm(20);
125 20 : expected_error = close_socket ? 20006 : 20003;
126 20 : ret = dbsqlexec(dbproc);
127 20 : alarm(0);
128 20 : if (ret != FAIL) {
129 0 : fprintf(stderr, "Failed. Expected FAIL to be returned.\n");
130 0 : return 1;
131 : }
132 :
133 20 : dbsetuserdata(dbproc, NULL);
134 20 : if (!close_socket)
135 10 : close(end_socket);
136 20 : dbexit();
137 :
138 20 : printf("dblib okay on %s\n", __FILE__);
139 20 : return 0;
140 : }
141 :
142 10 : TEST_MAIN()
143 : {
144 10 : UNITTEST = argv[0];
145 10 : read_login_info(argc, argv);
146 10 : if (test(0) || test(1))
147 : return 1;
148 : return 0;
149 : }
150 :
151 : #else
152 : TEST_MAIN()
153 : {
154 : fprintf(stderr, "Not possible for this platform.\n");
155 : return 0;
156 : }
157 : #endif
158 :
|