The xmalloc/xfree functions from YAZ are used to manage memory.
[ir-tcl-moved-to-github.git] / ir-tcl.c
index 58ed23d..a9742c1 100644 (file)
--- a/ir-tcl.c
+++ b/ir-tcl.c
@@ -5,7 +5,19 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: ir-tcl.c,v $
- * Revision 1.87  1996-05-29 06:37:51  adam
+ * Revision 1.91  1996-07-03 13:31:11  adam
+ * The xmalloc/xfree functions from YAZ are used to manage memory.
+ *
+ * Revision 1.90  1996/06/27  14:21:00  adam
+ * Yet another Windows port.
+ *
+ * Revision 1.89  1996/06/11  15:27:15  adam
+ * Event type set to connect a little earlier in the do_connect function.
+ *
+ * Revision 1.88  1996/06/03  09:04:22  adam
+ * Changed a few logf calls.
+ *
+ * Revision 1.87  1996/05/29  06:37:51  adam
  * Function ir_tcl_get_grs_r enhanced so that specific elements can be
  * extracted.
  *
@@ -360,14 +372,14 @@ static void delete_IR_record (IrTcl_RecordList *rl)
         default:
             break;
         }
-        free (rl->u.dbrec.buf);
+        xfree (rl->u.dbrec.buf);
         break;
     case Z_NamePlusRecord_surrogateDiagnostic:
         ir_deleteDiags (&rl->u.surrogateDiagnostics.list,
                         &rl->u.surrogateDiagnostics.num);
         break;
     }
-    free (rl->elements);
+    xfree (rl->elements);
 }
 
 static IrTcl_RecordList *new_IR_record (IrTcl_SetObj *setobj, 
@@ -416,7 +428,7 @@ int ir_tcl_eval (Tcl_Interp *interp, const char *command)
               interp->result);
     }
     Tcl_FreeResult (interp);
-    free (tmp);
+    xfree (tmp);
     return r;
 }
 
@@ -468,7 +480,7 @@ static void delete_IR_records (IrTcl_SetObj *setobj)
     {
         delete_IR_record (rl);
         rl1 = rl->next;
-        free (rl);
+        xfree (rl);
     }
     setobj->record_list = NULL;
 }
@@ -574,7 +586,7 @@ static void set_referenceId (ODR o, Z_ReferenceId **dst, const char *src)
 
 static void get_referenceId (char **dst, Z_ReferenceId *src)
 {
-    free (*dst);
+    xfree (*dst);
     if (!src)
     {
         *dst = NULL;
@@ -599,6 +611,7 @@ static int do_init_request (void *obj, Tcl_Interp *interp,
 
     if (argc <= 0)
         return TCL_OK;
+    logf (LOG_DEBUG, "init %s", *argv);
     if (!p->cs_link)
     {
         interp->result = "init: not connected";
@@ -877,7 +890,7 @@ static int do_implementationName (void *obj, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &p->implementationName);
     if (argc == 3)
     {
-        free (p->implementationName);
+        xfree (p->implementationName);
         if (ir_tcl_strdup (interp, &p->implementationName, argv[2])
             == TCL_ERROR)
             return TCL_ERROR;
@@ -986,10 +999,10 @@ static int do_idAuthentication (void *obj, Tcl_Interp *interp,
 
     if (argc >= 3 || argc == -1)
     {
-        free (p->idAuthenticationOpen);
-        free (p->idAuthenticationGroupId);
-        free (p->idAuthenticationUserId);
-        free (p->idAuthenticationPassword);
+        xfree (p->idAuthenticationOpen);
+        xfree (p->idAuthenticationGroupId);
+        xfree (p->idAuthenticationUserId);
+        xfree (p->idAuthenticationPassword);
     }
     if (argc >= 3 || argc <= 0)
     {
@@ -1050,6 +1063,7 @@ static int do_connect (void *obj, Tcl_Interp *interp,
         return TCL_OK;
     if (argc == 3)
     {
+        logf (LOG_DEBUG, "connect %s %s", *argv, argv[2]);
         if (p->hostname)
         {
             interp->result = "already connected";
@@ -1090,23 +1104,23 @@ static int do_connect (void *obj, Tcl_Interp *interp,
         }
         if (ir_tcl_strdup (interp, &p->hostname, argv[2]) == TCL_ERROR)
             return TCL_ERROR;
+        p->eventType = "connect";
         if ((r=cs_connect (p->cs_link, addr)) < 0)
         {
             interp->result = "connect fail";
             ir_tcl_disconnect (p);
             return TCL_ERROR;
         }
-        logf(LOG_DEBUG, "cs_connect() returned %d fd=%d", r,
-             cs_fileno(p->cs_link));
-        p->eventType = "connect";
         ir_select_add (cs_fileno (p->cs_link), p);
         if (r == 1)
         {
+            logf (LOG_DEBUG, "connect pending fd=%d", cs_fileno(p->cs_link));
             ir_select_add_write (cs_fileno (p->cs_link), p);
             p->state = IR_TCL_R_Connecting;
         }
         else
         {
+            logf (LOG_DEBUG, "connect ok fd=%d", cs_fileno(p->cs_link));
             p->state = IR_TCL_R_Idle;
             if (p->callback)
                 ir_tcl_eval (p->interp, p->callback);
@@ -1125,7 +1139,7 @@ void ir_tcl_disconnect (IrTcl_Obj *p)
     if (p->hostname)
     {
         logf(LOG_DEBUG, "Closing connection to %s", p->hostname);
-        free (p->hostname);
+        xfree (p->hostname);
         p->hostname = NULL;
         ir_select_remove_write (cs_fileno (p->cs_link), p);
         ir_select_remove (cs_fileno (p->cs_link), p);
@@ -1185,7 +1199,7 @@ static int do_comstack (void *o, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &obj->comstackType);
     else if (argc == 3)
     {
-        free (obj->comstackType);
+        xfree (obj->comstackType);
         if (ir_tcl_strdup (interp, &obj->comstackType, argv[2]) == TCL_ERROR)
             return TCL_ERROR;
     }
@@ -1246,7 +1260,7 @@ static int do_callback (void *obj, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &p->callback);
     if (argc == 3)
     {
-        free (p->callback);
+        xfree (p->callback);
         if (argv[2][0])
         {
             if (ir_tcl_strdup (interp, &p->callback, argv[2]) == TCL_ERROR)
@@ -1275,7 +1289,7 @@ static int do_failback (void *obj, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &p->failback);
     else if (argc == 3)
     {
-        free (p->failback);
+        xfree (p->failback);
         if (argv[2][0])
         {
             if (ir_tcl_strdup (interp, &p->failback, argv[2]) == TCL_ERROR)
@@ -1304,7 +1318,7 @@ static int do_initResponse (void *obj, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &p->initResponse);
     if (argc == 3)
     {
-        free (p->initResponse);
+        xfree (p->initResponse);
         if (argv[2][0])
         {
             if (ir_tcl_strdup (interp, &p->initResponse, argv[2]) == TCL_ERROR)
@@ -1391,8 +1405,8 @@ static int do_databaseNames (void *obj, Tcl_Interp *interp,
     if (argc == -1)
     {
         for (i=0; i<p->num_databaseNames; i++)
-            free (p->databaseNames[i]);
-        free (p->databaseNames);
+            xfree (p->databaseNames[i]);
+        xfree (p->databaseNames);
     }
     if (argc <= 0)
     {
@@ -1409,8 +1423,8 @@ static int do_databaseNames (void *obj, Tcl_Interp *interp,
     if (p->databaseNames)
     {
         for (i=0; i<p->num_databaseNames; i++)
-            free (p->databaseNames[i]);
-        free (p->databaseNames);
+            xfree (p->databaseNames[i]);
+        xfree (p->databaseNames);
     }
     p->num_databaseNames = argc - 2;
     p->databaseNames =
@@ -1455,7 +1469,7 @@ static int do_queryType (void *obj, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &p->queryType);
     if (argc == 3)
     {
-        free (p->queryType);
+        xfree (p->queryType);
         if (ir_tcl_strdup (interp, &p->queryType, argv[2]) == TCL_ERROR)
             return TCL_ERROR;
     }
@@ -1547,7 +1561,7 @@ static int do_referenceId (void *obj, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &p->referenceId);
     if (argc == 3)
     {
-        free (p->referenceId);
+        xfree (p->referenceId);
         if (ir_tcl_strdup (interp, &p->referenceId, argv[2]) == TCL_ERROR)
             return TCL_ERROR;
     }
@@ -1570,13 +1584,13 @@ static int do_preferredRecordSyntax (void *obj, Tcl_Interp *interp,
     }
     else if (argc == -1)
     {
-        free (p->preferredRecordSyntax);
+        xfree (p->preferredRecordSyntax);
         p->preferredRecordSyntax = NULL;
         return TCL_OK;
     }
     if (argc == 3)
     {
-        free (p->preferredRecordSyntax);
+        xfree (p->preferredRecordSyntax);
         p->preferredRecordSyntax = NULL;
         if (argv[2][0] && (p->preferredRecordSyntax = 
                            ir_tcl_malloc (sizeof(*p->preferredRecordSyntax))))
@@ -1609,7 +1623,7 @@ static int do_elementSetNames (void *obj, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &p->elementSetNames);
     if (argc == 3)
     {
-        free (p->elementSetNames);
+        xfree (p->elementSetNames);
         if (ir_tcl_strdup (interp, &p->elementSetNames, argv[2]) == TCL_ERROR)
             return TCL_ERROR;
     }
@@ -1634,7 +1648,7 @@ static int do_smallSetElementSetNames (void *obj, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &p->smallSetElementSetNames);
     if (argc == 3)
     {
-        free (p->smallSetElementSetNames);
+        xfree (p->smallSetElementSetNames);
         if (ir_tcl_strdup (interp, &p->smallSetElementSetNames,
                            argv[2]) == TCL_ERROR)
             return TCL_ERROR;
@@ -1660,7 +1674,7 @@ static int do_mediumSetElementSetNames (void *obj, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &p->mediumSetElementSetNames);
     if (argc == 3)
     {
-        free (p->mediumSetElementSetNames);
+        xfree (p->mediumSetElementSetNames);
         if (ir_tcl_strdup (interp, &p->mediumSetElementSetNames,
                            argv[2]) == TCL_ERROR)
             return TCL_ERROR;
@@ -1765,7 +1779,7 @@ static void ir_obj_delete (ClientData clientData)
     odr_destroy (obj->odr_in);
     odr_destroy (obj->odr_out);
     odr_destroy (obj->odr_pr);
-    free (obj);
+    xfree (obj);
 }
 
 /* 
@@ -1868,9 +1882,11 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv)
     p = obj->parent;
     if (argc != 3)
     {
+        logf (LOG_DEBUG, "search %s", *argv);
         interp->result = "wrong # args";
         return TCL_ERROR;
     }
+    logf (LOG_DEBUG, "search %s %s", *argv, argv[2]);
     if (!obj->set_inher.num_databaseNames)
     {
         interp->result = "no databaseNames";
@@ -1938,7 +1954,8 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv)
         req->mediumSetElementSetNames = NULL; 
     
     req->query = &query;
-    
+   
+    logf (LOG_DEBUG, "queryType %s", obj->set_inher.queryType);
     if (!strcmp (obj->set_inher.queryType, "rpn"))
     {
         Z_RPNQuery *RPNquery;
@@ -1951,7 +1968,6 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv)
         }
         query.which = Z_Query_type_1;
         query.u.type_1 = RPNquery;
-        logf (LOG_DEBUG, "RPN");
     }
 #if CCL2RPN
     else if (!strcmp (obj->set_inher.queryType, "cclrpn"))
@@ -1973,13 +1989,14 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv)
                               ccl_err_msg(error), NULL);
             return TCL_ERROR;
         }
+#if 0
         ccl_pr_tree (rpn, stderr);
         fprintf (stderr, "\n");
+#endif
         assert((RPNquery = ccl_rpn_query(rpn)));
         RPNquery->attributeSetId = oid_getoidbyent (&bib1);
         query.which = Z_Query_type_1;
         query.u.type_1 = RPNquery;
-        logf (LOG_DEBUG, "CCLRPN");
     }
 #endif
     else if (!strcmp (obj->set_inher.queryType, "ccl"))
@@ -1988,7 +2005,6 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv)
         query.u.type_2 = &ccl_query;
         ccl_query.buf = (unsigned char *) argv[2];
         ccl_query.len = strlen (argv[2]);
-        logf (LOG_DEBUG, "CCL");
     }
     else
     {
@@ -2015,7 +2031,7 @@ static int do_searchResponse (void *o, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &obj->searchResponse);
     if (argc == 3)
     {
-        free (obj->searchResponse);
+        xfree (obj->searchResponse);
         if (argv[2][0])
         {
             if (ir_tcl_strdup (interp, &obj->searchResponse, argv[2])
@@ -2045,7 +2061,7 @@ static int do_presentResponse (void *o, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &obj->presentResponse);
     if (argc == 3)
     {
-        free (obj->presentResponse);
+        xfree (obj->presentResponse);
         if (argv[2][0])
         {
             if (ir_tcl_strdup (interp, &obj->presentResponse, argv[2])
@@ -2132,7 +2148,7 @@ static int do_setName (void *o, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &obj->setName);
     if (argc == 3)
     {
-        free (obj->setName);
+        xfree (obj->setName);
         if (ir_tcl_strdup (interp, &obj->setName, argv[2])
             == TCL_ERROR)
             return TCL_ERROR;
@@ -2262,7 +2278,7 @@ static int do_recordElements (void *o, Tcl_Interp *interp,
     }
     if (argc == 3)
     {
-        free (obj->recordElements);
+        xfree (obj->recordElements);
         return ir_tcl_strdup (NULL, &obj->recordElements, 
                               (*argv[2] ? argv[2] : NULL));
     }
@@ -2281,7 +2297,6 @@ static int ir_diagResult (Tcl_Interp *interp, IrTcl_Diagnostic *list, int num)
 
     for (i = 0; i<num; i++)
     {
-        logf (LOG_DEBUG, "Diagnostic, code %d", list[i].condition);
         sprintf (buf, "%d", list[i].condition);
         Tcl_AppendElement (interp, buf);
         cp = diagbib1_str (list[i].condition);
@@ -2501,6 +2516,7 @@ static int do_present (void *o, Tcl_Interp *interp, int argc, char **argv)
     }
     else 
         number = 10;
+    logf (LOG_DEBUG, "present %s %d %d", *argv, start, number);
     p = obj->parent;
     if (!p->cs_link)
     {
@@ -2659,7 +2675,7 @@ static void ir_set_obj_delete (ClientData clientData)
 
     ir_tcl_method (NULL, -1, NULL, tabs, NULL);
 
-    free (p);
+    xfree (p);
 }
 
 /*
@@ -2678,7 +2694,7 @@ static int ir_set_obj_init (ClientData clientData, Tcl_Interp *interp,
         return TCL_ERROR;
     }
     obj = ir_tcl_malloc (sizeof(*obj));
-    logf (LOG_DEBUG, "ir set create");
+    logf (LOG_DEBUG, "ir set create %s", argv[1]);
     if (parentData)
     {
         int i;
@@ -2809,6 +2825,7 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv)
         interp->result = "wrong # args";
         return TCL_ERROR;
     }
+    logf (LOG_DEBUG, "scan %s %s", *argv, argv[2]);
     if (!p->set_inher.num_databaseNames)
     {
         interp->result = "no databaseNames";
@@ -2847,8 +2864,6 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv)
     bib1.value = VAL_BIB1;
 
     req->attributeSet = oid_getoidbyent (&bib1);
-    ccl_pr_tree (rpn, stderr);
-    fprintf (stderr, "\n");
     if (!(req->termListAndStartPoint = ccl_scan_query (rpn)))
         return TCL_ERROR;
 #endif
@@ -2881,7 +2896,7 @@ static int do_scanResponse (void *o, Tcl_Interp *interp,
         return ir_tcl_strdel (interp, &obj->scanResponse);
     if (argc == 3)
     {
-        free (obj->scanResponse);
+        xfree (obj->scanResponse);
         if (argv[2][0])
         {
             if (ir_tcl_strdup (interp, &obj->scanResponse, argv[2])
@@ -3088,7 +3103,7 @@ static void ir_scan_obj_delete (ClientData clientData)
     tabs[1].tab = NULL;
 
     ir_tcl_method (NULL, -1, NULL, tabs, NULL);
-    free (obj);
+    xfree (obj);
 }
 
 /* 
@@ -3106,6 +3121,7 @@ static int ir_scan_obj_mk (ClientData clientData, Tcl_Interp *interp,
         interp->result = "wrong # args";
         return TCL_ERROR;
     }
+    logf (LOG_DEBUG, "ir scan create %s", argv[1]);
     if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info))
     {
         interp->result = "No parent";
@@ -3139,13 +3155,13 @@ static void ir_initResponse (void *obj, Z_InitResponse *initrs)
 
     get_referenceId (&p->set_inher.referenceId, initrs->referenceId);
 
-    free (p->targetImplementationId);
+    xfree (p->targetImplementationId);
     ir_tcl_strdup (p->interp, &p->targetImplementationId,
                initrs->implementationId);
-    free (p->targetImplementationName);
+    xfree (p->targetImplementationName);
     ir_tcl_strdup (p->interp, &p->targetImplementationName,
                initrs->implementationName);
-    free (p->targetImplementationVersion);
+    xfree (p->targetImplementationVersion);
     ir_tcl_strdup (p->interp, &p->targetImplementationVersion,
                initrs->implementationVersion);
 
@@ -3155,7 +3171,7 @@ static void ir_initResponse (void *obj, Z_InitResponse *initrs)
     memcpy (&p->options, initrs->options, sizeof(initrs->options));
     memcpy (&p->protocolVersion, initrs->protocolVersion,
             sizeof(initrs->protocolVersion));
-    free (p->userInformationField);
+    xfree (p->userInformationField);
     p->userInformationField = NULL;
     if (initrs->userInformationField)
     {
@@ -3179,8 +3195,8 @@ static void ir_deleteDiags (IrTcl_Diagnostic **dst_list, int *dst_num)
 {
     int i;
     for (i = 0; i<*dst_num; i++)
-        free (dst_list[i]->addinfo);
-    free (*dst_list);
+        xfree (dst_list[i]->addinfo);
+    xfree (*dst_list);
     *dst_list = NULL;
     *dst_num = 0;
 }
@@ -3195,6 +3211,7 @@ static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_num,
     *dst_list = ir_tcl_malloc (sizeof(**dst_list) * num);
     for (i = 0; i<num; i++)
     {
+        const char *cp;
         switch (list[i]->which)
         {
         case Z_DiagRec_defaultFormat:
@@ -3203,6 +3220,9 @@ static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_num,
             if (addinfo && 
                 ((*dst_list)[i].addinfo = ir_tcl_malloc (strlen(addinfo)+1)))
                 strcpy ((*dst_list)[i].addinfo, addinfo);
+            cp = diagbib1_str ((*dst_list)[i].condition);
+            logf (LOG_DEBUG, "Diag %d %s %s", (*dst_list)[i].condition,
+                  cp ? cp : "", addinfo ? addinfo : "");
             break;
         default:
             (*dst_list)[i].addinfo = NULL;
@@ -3329,7 +3349,7 @@ static void ir_searchResponse (void *o, Z_SearchResponse *searchrs,
     if (searchrs->nextResultSetPosition)
         setobj->nextResultSetPosition = *searchrs->nextResultSetPosition;
 
-    logf (LOG_DEBUG, "Search response %d, %d hits", 
+    logf (LOG_DEBUG, "status %d hits %d", 
           setobj->searchStatus, setobj->resultCount);
     if (zrs)
     {
@@ -3393,7 +3413,7 @@ static void ir_scanResponse (void *o, Z_ScanResponse *scanrs,
         scanobj->positionOfTerm = -1;
     logf (LOG_DEBUG, "positionOfTerm=%d", scanobj->positionOfTerm);
 
-    free (scanobj->entries);
+    xfree (scanobj->entries);
     scanobj->entries = NULL;
 
     ir_deleteDiags (&scanobj->nonSurrogateDiagnosticList,
@@ -3551,7 +3571,6 @@ static void ir_select_read (ClientData clientData)
             ir_obj_delete (p);
             return;
         }
-        logf(LOG_DEBUG, "Decoded ok");
         /* handle APDU and invoke callback */
         rq = p->request_queue;
         if (!rq)
@@ -3560,7 +3579,7 @@ static void ir_select_read (ClientData clientData)
             exit (1);
         }
         object_name = rq->object_name;
-        logf (LOG_DEBUG, "getCommandInfo (%s)", object_name);
+        logf (LOG_DEBUG, "Object %s", object_name);
         apdu_call = NULL;
         if (Tcl_GetCommandInfo (p->interp, object_name, &cmd_info))
         {
@@ -3611,10 +3630,10 @@ static void ir_select_read (ClientData clientData)
             ir_tcl_eval (p->interp, apdu_call);
         else if (rq->callback)
             ir_tcl_eval (p->interp, rq->callback);
-        free (rq->buf_out);
-        free (rq->callback);
-        free (rq->object_name);
-        free (rq);
+        xfree (rq->buf_out);
+        xfree (rq->callback);
+        xfree (rq->object_name);
+        xfree (rq);
         odr_reset (p->odr_in);
         if (p->ref_count == 1)
         {
@@ -3630,7 +3649,7 @@ static void ir_select_read (ClientData clientData)
 /*
  * ir_select_write: handle outgoing packages - not yet written.
  */
-static void ir_select_write (ClientData clientData)
+static int ir_select_write (ClientData clientData)
 {
     IrTcl_Obj *p = clientData;
     int r;
@@ -3644,7 +3663,7 @@ static void ir_select_write (ClientData clientData)
         if (r == 1)
         {
             logf (LOG_DEBUG, "cs_rcvconnect returned 1");
-            return;
+            return 2;
         }
         p->state = IR_TCL_R_Idle;
         p->ref_count = 2;
@@ -3659,22 +3678,22 @@ static void ir_select_write (ClientData clientData)
                 ir_tcl_eval (p->interp, p->failback);
             }
             ir_obj_delete (p);
-            return;
+            return 2;
         }
         if (p->callback)
             ir_tcl_eval (p->interp, p->callback);
         ir_obj_delete (p);
-        return;
+        return 2;
     }
     rq = p->request_queue;
     if (!rq || !rq->buf_out)
-        return;
+        return 0;
     assert (rq);
     if ((r=cs_put (p->cs_link, rq->buf_out, rq->len_out)) < 0)
     {
         logf (LOG_DEBUG, "cs_put write fail");
         p->ref_count = 2;
-        free (rq->buf_out);
+        xfree (rq->buf_out);
         rq->buf_out = NULL;
         ir_tcl_disconnect (p);
         if (p->failback)
@@ -3689,17 +3708,23 @@ static void ir_select_write (ClientData clientData)
         logf (LOG_DEBUG, "Write completed");
         p->state = IR_TCL_R_Waiting;
         ir_select_remove_write (cs_fileno (p->cs_link), p);
-        free (rq->buf_out);
+        xfree (rq->buf_out);
         rq->buf_out = NULL;
     }
+    return 1;
 }
 
 static void ir_select_notify (ClientData clientData, int r, int w, int e)
 {
-    if (r)
+    if (w)
+    {
+        if (!ir_select_write (clientData) && r)
+            ir_select_read (clientData);
+    } 
+    else if (r)
+    {
         ir_select_read (clientData);
-    else if (w)
-        ir_select_write (clientData);
+    }
 }
 
 /* ------------------------------------------------------- */