diff -Nur gamin-0.0.26.orig/libgamin/gam_api.c gamin-0.0.26/libgamin/gam_api.c --- gamin-0.0.26.orig/libgamin/gam_api.c 2005-02-17 12:42:57.000000000 +0100 +++ gamin-0.0.26/libgamin/gam_api.c 2005-04-09 23:56:23.000000000 +0200 @@ -1300,7 +1300,6 @@ int FAMCancelMonitor(FAMConnection * fc, const FAMRequest * fr) { - GAMDataPtr conn; int ret; if ((fc == NULL) || (fr == NULL)) { @@ -1317,16 +1316,6 @@ GAM_DEBUG(DEBUG_INFO, "FAMCancelMonitor(%d)\n", fr->reqnum); /* - * destroy the request internally - */ - conn = fc->client; - ret = gamin_data_del_req(conn, fr->reqnum); - if (ret < 0) { - FAMErrno = FAM_ARG; - return (-1); - } - - /* * send destruction message to the server */ ret = gamin_send_request(GAM_REQ_CANCEL, fc->fd, NULL, diff -Nur gamin-0.0.26.orig/libgamin/gam_data.c gamin-0.0.26/libgamin/gam_data.c --- gamin-0.0.26.orig/libgamin/gam_data.c 2005-02-17 12:44:38.000000000 +0100 +++ gamin-0.0.26/libgamin/gam_data.c 2005-04-09 23:56:00.000000000 +0200 @@ -458,6 +458,12 @@ event->code = evn->type; conn->evn_ready = 0; conn->evn_read -= evn->len; + if (event->code == FAMAcknowledge) { + /* + * destroy the request internally + */ + gamin_data_del_req(conn, evn->seq); + } if (conn->evn_read > 0) { /* * there was other events piggy-backed on the same read, diff -Nur gamin-0.0.26.orig/server/gam_connection.c gamin-0.0.26/server/gam_connection.c --- gamin-0.0.26.orig/server/gam_connection.c 2005-02-17 11:11:26.000000000 +0100 +++ gamin-0.0.26/server/gam_connection.c 2005-04-09 23:56:00.000000000 +0200 @@ -327,7 +327,10 @@ gam_subscription_set_listener(sub, conn->listener); gam_add_subscription(sub); break; - case GAM_REQ_CANCEL: + case GAM_REQ_CANCEL: { + char *path; + int pathlen; + sub = gam_listener_get_subscription_by_reqno(conn->listener, req->seq); @@ -339,9 +342,17 @@ } GAM_DEBUG(DEBUG_INFO, "Cancelling subscription for (%d)\n", req->seq); + path = g_strdup(gam_subscription_get_path(sub)); + pathlen = gam_subscription_pathlen(sub); gam_remove_subscription(sub); gam_listener_remove_subscription(conn->listener, sub); - break; + + if (gam_send_ack(conn, req->seq, path, pathlen) < 0) { + GAM_DEBUG(DEBUG_INFO, "Failed to send ack to PID %d\n", + gam_connection_get_pid(conn)); + } + g_free(path); + } break; case GAM_REQ_DEBUG: #ifdef GAMIN_DEBUG_API gam_debug_add(conn, &req->path[0], options); @@ -543,7 +554,59 @@ return (-1); } return (0); +} +/** + * gam_send_ack: + * @conn: the connection data + * @path: the file/directory path + * + * Emit an acknowledge event to the connection + * + * Returns 0 in case of success and -1 in case of failure + */ +int +gam_send_ack(GamConnDataPtr conn, int reqno, + const char *path, int len) +{ + GAMPacket req; + size_t tlen; + int ret; + + if ((conn == NULL) || (conn->fd < 0) || (path == NULL)) + return (-1); + + if (len <= 0) { + GAM_DEBUG(DEBUG_INFO, "Empty file path\n"); + return (-1); + } + + if (len >= MAXPATHLEN) { + GAM_DEBUG(DEBUG_INFO, "File path too long %s\n", path); + return (-1); + } + + GAM_DEBUG(DEBUG_INFO, "Event to %d : %d, %d, %s\n", conn->pid, + reqno, FAMAcknowledge, path); + /* + * prepare the packet + */ + tlen = GAM_PACKET_HEADER_LEN + len; + /* We use only local socket so no need for network byte order conversion */ + req.len = (unsigned short) tlen; + req.version = GAM_PROTO_VERSION; + req.seq = reqno; + req.type = FAMAcknowledge; + req.pathlen = len; + memcpy(&req.path[0], path, len); + ret = + gam_client_conn_write(conn->source, conn->fd, (gpointer) & req, + tlen); + if (!ret) { + GAM_DEBUG(DEBUG_INFO, "Failed to send event to %d\n", conn->pid); + return (-1); + } + return (0); } /************************************************************************ diff -Nur gamin-0.0.26.orig/server/gam_connection.h gamin-0.0.26/server/gam_connection.h --- gamin-0.0.26.orig/server/gam_connection.h 2004-12-01 13:12:55.000000000 +0100 +++ gamin-0.0.26/server/gam_connection.h 2005-04-09 22:26:16.000000000 +0200 @@ -47,6 +47,10 @@ int event, const char *path, int len); +int gam_send_ack (GamConnDataPtr conn, + int reqno, + const char *path, + int len); void gam_connections_debug (void); #ifdef __cplusplus }