diff -cr postgresql-7.2/src/interfaces/odbc/connection.c postgresql-7.2-brad/src/interfaces/odbc/connection.c *** postgresql-7.2/src/interfaces/odbc/connection.c Sun Dec 30 18:09:42 2001 --- postgresql-7.2-brad/src/interfaces/odbc/connection.c Wed Mar 27 10:04:45 2002 *************** *** 19,24 **** --- 19,27 ---- #include #include #include + #ifndef WIN32 + #include + #endif #include "environ.h" #include "socket.h" *************** *** 828,835 **** } break; case 'K': /* Secret key (6.4 protocol) */ ! (void) SOCK_get_int(sock, 4); /* pid */ ! (void) SOCK_get_int(sock, 4); /* key */ break; case 'Z': /* Backend is ready for new query (6.4) */ --- 831,839 ---- } break; case 'K': /* Secret key (6.4 protocol) */ ! self->be_pid = SOCK_get_int(sock, 4); /* pid */ ! self->be_key = SOCK_get_int(sock, 4); /* key */ ! qlog("conn=%u, Backend pid=%u\n",self,self->be_pid); break; case 'Z': /* Backend is ready for new query (6.4) */ *************** *** 1837,1839 **** --- 1841,1903 ---- value = BLCKSZ; return value; } + + int + CC_send_cancel_request(const ConnectionClass *conn) + { + #ifdef WIN32 + int save_errno = (WSAGetLastError()); + #else + int save_errno = errno; + #endif + int tmpsock = -1; + struct + { + uint32 packetlen; + CancelRequestPacket cp; + } crp; + + /* Check we have an open connection */ + if (!conn) + return FALSE; + + if (conn->sock == NULL ) + { + return FALSE; + } + + /* + * We need to open a temporary connection to the postmaster. Use the + * information saved by connectDB to do this with only kernel calls. + */ + if ((tmpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + return FALSE; + } + if (connect(tmpsock, (struct sockaddr *)&(conn->sock->sadr), + sizeof(conn->sock->sadr)) < 0) + { + return FALSE; + } + + /* + * We needn't set nonblocking I/O or NODELAY options here. + */ + crp.packetlen = htonl((uint32) sizeof(crp)); + crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE); + crp.cp.backendPID = htonl(conn->be_pid); + crp.cp.cancelAuthCode = htonl(conn->be_key); + + if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp)) + { + return FALSE; + } + + /* Sent it, done */ + closesocket(tmpsock); + #ifdef WIN32 + WSASetLastError(save_errno); + #else + errno = save_errno; + #endif + } diff -cr postgresql-7.2/src/interfaces/odbc/connection.h postgresql-7.2-brad/src/interfaces/odbc/connection.h *** postgresql-7.2/src/interfaces/odbc/connection.h Mon Nov 5 12:46:38 2001 --- postgresql-7.2-brad/src/interfaces/odbc/connection.h Tue Mar 26 14:45:35 2002 *************** *** 125,130 **** --- 125,146 ---- char tty[PATH_SIZE]; } StartupPacket6_2; + /* Transferred from pqcomm.h: */ + + + typedef ProtocolVersion MsgType; + + #define PG_PROTOCOL(m,n) (((m) << 16) | (n)) + #define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678) + + typedef struct CancelRequestPacket + { + /* Note that each field is stored in network byte order! */ + MsgType cancelRequestCode; /* code to identify a cancel request */ + unsigned int backendPID; /* PID of client's backend */ + unsigned int cancelAuthCode; /* secret key to authorize cancel */ + } CancelRequestPacket; + /* Structure to hold all the connection attributes for a specific connection (used for both registry and file, DSN and DRIVER) *************** *** 266,271 **** --- 282,289 ---- Int2 pg_version_major; Int2 pg_version_minor; char ms_jet; + int be_pid; /* pid returned by backend */ + int be_key; /* auth code needed to send cancel */ #ifdef MULTIBYTE char *client_encoding; char *server_encoding; diff -cr postgresql-7.2/src/interfaces/odbc/execute.c postgresql-7.2-brad/src/interfaces/odbc/execute.c *** postgresql-7.2/src/interfaces/odbc/execute.c Thu Oct 25 01:50:14 2001 --- postgresql-7.2-brad/src/interfaces/odbc/execute.c Wed Mar 27 11:20:26 2002 *************** *** 510,515 **** --- 510,519 ---- if (stmt->data_at_exec < 0) { /* + * Tell the Backend that we're cancelling this request + */ + CC_send_cancel_request(SC_get_conn(stmt)); + /* * MAJOR HACK for Windows to reset the driver manager's cursor * state: Because of what seems like a bug in the Odbc driver * manager, SQLCancel does not act like a SQLFreeStmt(CLOSE), as *************** *** 517,523 **** * force method calls the driver manager's function on behalf of * the application. */ - #ifdef WIN32 if (ci->drivers.cancel_as_freestmt) { --- 521,526 ---- diff -cr postgresql-7.2/src/interfaces/odbc/socket.c postgresql-7.2-brad/src/interfaces/odbc/socket.c *** postgresql-7.2/src/interfaces/odbc/socket.c Sun Oct 28 01:26:14 2001 --- postgresql-7.2-brad/src/interfaces/odbc/socket.c Tue Mar 26 21:40:59 2002 *************** *** 107,113 **** SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname) { struct hostent *host; - struct sockaddr_in sadr; unsigned long iaddr; if (self->socket != -1) --- 107,112 ---- *************** *** 117,123 **** return 0; } ! memset((char *) &sadr, 0, sizeof(sadr)); /* * If it is a valid IP address, use it. Otherwise use hostname lookup. --- 116,122 ---- return 0; } ! memset((char *) &(self->sadr), 0, sizeof(self->sadr)); /* * If it is a valid IP address, use it. Otherwise use hostname lookup. *************** *** 132,144 **** self->errormsg = "Could not resolve hostname."; return 0; } ! memcpy(&(sadr.sin_addr), host->h_addr, host->h_length); } else ! memcpy(&(sadr.sin_addr), (struct in_addr *) & iaddr, sizeof(iaddr)); ! sadr.sin_family = AF_INET; ! sadr.sin_port = htons(port); self->socket = socket(AF_INET, SOCK_STREAM, 0); if (self->socket == -1) --- 131,143 ---- self->errormsg = "Could not resolve hostname."; return 0; } ! memcpy(&(self->sadr.sin_addr), host->h_addr, host->h_length); } else ! memcpy(&(self->sadr.sin_addr), (struct in_addr *) & iaddr, sizeof(iaddr)); ! self->sadr.sin_family = AF_INET; ! self->sadr.sin_port = htons(port); self->socket = socket(AF_INET, SOCK_STREAM, 0); if (self->socket == -1) *************** *** 148,155 **** return 0; } ! if (connect(self->socket, (struct sockaddr *) & (sadr), ! sizeof(sadr)) < 0) { self->errornumber = SOCKET_COULD_NOT_CONNECT; self->errormsg = "Could not connect to remote socket."; --- 147,154 ---- return 0; } ! if (connect(self->socket, (struct sockaddr *) & (self->sadr), ! sizeof(self->sadr)) < 0) { self->errornumber = SOCKET_COULD_NOT_CONNECT; self->errormsg = "Could not connect to remote socket."; diff -cr postgresql-7.2/src/interfaces/odbc/socket.h postgresql-7.2-brad/src/interfaces/odbc/socket.h *** postgresql-7.2/src/interfaces/odbc/socket.h Sun Oct 28 01:26:15 2001 --- postgresql-7.2-brad/src/interfaces/odbc/socket.h Tue Mar 26 21:35:41 2002 *************** *** 64,70 **** char reverse; /* used to handle Postgres 6.2 protocol * (reverse byte order) */ ! }; #define SOCK_get_char(self) (SOCK_get_next_byte(self)) --- 64,70 ---- char reverse; /* used to handle Postgres 6.2 protocol * (reverse byte order) */ ! struct sockaddr_in sadr; /* Used for handling connections for cancel */ }; #define SOCK_get_char(self) (SOCK_get_next_byte(self))