Skip to Content.
Sympa Menu

freetds - Re: WARNING: Changing tds_connect() API

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Brian Bruns" <camber AT ais.org>
  • To: freetds AT franklin.oit.unc.edu
  • Subject: Re: WARNING: Changing tds_connect() API
  • Date: Thu, 12 Sep 2002 11:20:25 -0400



> My original thoughts were along these lines...but as I looked further, I
> realized that tds_connect() really needs to be able to change the state at
> different points depending on various conditions. The TDSSOCKET shouldn't
> appear live until after the connect() call,

The socket is allocated with tds->s = 0 so it is by definition dead until
after connect().

> and if the login fails it should
> appear dead when the "Login incorrect." message is sent.

Easy enough, just call tds_client_msg() with NULL, or close the socket and
set tds->s to 0. Either way, DBDEAD will be true.

> So breaking up the
> calls in the ways that you suggest really don't provide the degree of
> control that I think is needed.

Unless I'm missing something, I think it should be possible to do this.
I'd vastly prefer to keep the call signatures of the tds_*() functions
simple.

> Here's an excerpt from my version, showing the critical sections where the
> state needs to change. Note that the two calls to tds_client_msg() shown
> below need the state to be dead, while any calls to tds_client_msg()
> performed from tds_process_login_tokens() need the state to be live:
>
> if (connect(tds->s, (struct sockaddr *) &sin, sizeof(sin)) <0) {
> char message[128];
> sprintf(message, "src/tds/login.c: tds_connect: %s:%d",
> inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
> perror(message);
> tds_client_msg(tds->tds_ctx, tds, 20009, 9, 0, 0,
> "Server is unavailable or does not exist.");
> tds_free_config(config);
> tds_free_socket(tds);
> *tdsp = NULL;
> return;
> }
> }
> /* END OF NEW CODE */
>
> /* We are now connected!
> * Save our TDSSOCKET now, to ensure that we don't appear
> * to be DBDEAD() upon entry to error/message handlers.
> */
> ---> *tdsp = tds;

Done prior to entering function.

>
> if (IS_TDS7_PLUS(tds)) {
> tds->out_flag=0x10;
> tds7_send_login(tds,config);
> } else {
> tds->out_flag=0x02;
> tds_send_login(tds,config);
> }
> if (!tds_process_login_tokens(tds)) {
> /* Login incorrect...mark the socket dead. */
> ---> *tdsp = NULL;
How about:
tds_close_socket(tds);
where: tds_close_socket(TDSSOCKET *tds) { close(tds->s); tds->s=0; }

>
> tds_client_msg(tds->tds_ctx, tds, 20014, 9, 0, 0,
> "Login incorrect.");
>
> tds_free_config(config);
> tds_free_socket(tds);

(remove free socket and becomes callers responsibility)

> return;

return TDS_FAIL;
> }
>





Archive powered by MHonArc 2.6.24.

Top of Page