static void process_one_event (RepoWatchInfo *info, const char *worktree, PFILE_NOTIFY_INFORMATION event, gboolean last_event) { WTStatus *status = info->status; char *filename; gboolean add_to_queue = TRUE; #if 0 if (handle_consecutive_duplicate_event (info, event)) add_to_queue = FALSE; #endif filename = convert_to_unix_path (event->FileName, event->FileNameLength); handle_rename (info, event, worktree, filename, last_event); if (event->Action == FILE_ACTION_MODIFIED) { seaf_debug ("Modified %s.\n", filename); /* Ignore modified event for directories. */ char *full_path = g_build_filename (worktree, filename, NULL); if (g_file_test(full_path, G_FILE_TEST_IS_DIR)) { g_free (full_path); goto out; } g_free (full_path); if (add_to_queue) add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } else if (event->Action == FILE_ACTION_ADDED) { seaf_debug ("Created %s.\n", filename); add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } else if (event->Action == FILE_ACTION_REMOVED) { seaf_debug ("Deleted %s.\n", filename); add_event_to_queue (status, WT_EVENT_DELETE, filename, NULL); } out: g_free (filename); g_atomic_int_set (&info->status->last_changed, (gint)time(NULL)); }
// test important PRIVATE gboolean _inotify_poll() { #define EVENT_SIZE ( sizeof (struct inotify_event) ) #define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) if (_inotify_fd != -1) { char buffer[EVENT_BUF_LEN]; int length = read(_inotify_fd, buffer, EVENT_BUF_LEN); struct inotify_event *move_out_event = NULL; GFile* old = NULL;// test : use real fileops to test it for (int i=0; i<length; ) { struct inotify_event *event = (struct inotify_event *) &buffer[i]; i += EVENT_SIZE+event->len; if(desktop_file_filter(event->name)) continue; if (event->len) { GFile* p = g_hash_table_lookup(_monitor_table, GINT_TO_POINTER(event->wd)); if (g_file_equal(p, _desktop_file)) { /* BEGIN MOVE EVENT HANDLE */ if ((event->mask & IN_MOVED_FROM) && (move_out_event == NULL)) { move_out_event = event; old = g_file_get_child(p, event->name); continue; } else if ((event->mask & IN_MOVED_FROM) && (move_out_event != NULL)) { GFile* f = g_file_get_child(_desktop_file, event->name); handle_delete(f); g_object_unref(f); continue; } else if ((event->mask & IN_MOVED_TO) && (move_out_event != NULL)) { move_out_event = NULL; GFile* f = g_file_get_child(p, event->name); handle_rename(old, f); g_object_unref(f); g_object_unref(old); old = NULL; continue; /* END MVOE EVENT HANDLE */ } else if (event->mask & IN_DELETE) { GFile* f = g_file_get_child(p, event->name); handle_delete(f); g_object_unref(f); } else if (event->mask & IN_CREATE) { GFile* f = g_file_get_child(p, event->name); handle_new(f); g_object_unref(f); } else { GFile* f = g_file_get_child(p, event->name); _add_monitor_directory(f); handle_update(f); g_object_unref(f); } } else { if (event->mask & IN_MOVED_TO) { GFile* f = g_file_get_child(_desktop_file, event->name); handle_delete(f); g_object_unref(f); } handle_update(p); } } } if (move_out_event != NULL) { handle_delete(old); move_out_event = NULL; } return TRUE; } else { return FALSE; } }
static int handle_fuse_request(struct fuse *fuse, struct fuse_handler* handler, const struct fuse_in_header *hdr, const void *data, size_t data_len) { switch (hdr->opcode) { case FUSE_LOOKUP: { /* bytez[] -> entry_out */ const char* name = data; return handle_lookup(fuse, handler, hdr, name); } case FUSE_FORGET: { const struct fuse_forget_in *req = data; return handle_forget(fuse, handler, hdr, req); } case FUSE_GETATTR: { /* getattr_in -> attr_out */ const struct fuse_getattr_in *req = data; return handle_getattr(fuse, handler, hdr, req); } case FUSE_SETATTR: { /* setattr_in -> attr_out */ const struct fuse_setattr_in *req = data; return handle_setattr(fuse, handler, hdr, req); } // case FUSE_READLINK: // case FUSE_SYMLINK: case FUSE_MKNOD: { /* mknod_in, bytez[] -> entry_out */ const struct fuse_mknod_in *req = data; const char *name = ((const char*) data) + sizeof(*req); return handle_mknod(fuse, handler, hdr, req, name); } case FUSE_MKDIR: { /* mkdir_in, bytez[] -> entry_out */ const struct fuse_mkdir_in *req = data; const char *name = ((const char*) data) + sizeof(*req); return handle_mkdir(fuse, handler, hdr, req, name); } case FUSE_UNLINK: { /* bytez[] -> */ const char* name = data; return handle_unlink(fuse, handler, hdr, name); } case FUSE_RMDIR: { /* bytez[] -> */ const char* name = data; return handle_rmdir(fuse, handler, hdr, name); } case FUSE_RENAME: { /* rename_in, oldname, newname -> */ const struct fuse_rename_in *req = data; const char *old_name = ((const char*) data) + sizeof(*req); const char *new_name = old_name + strlen(old_name) + 1; return handle_rename(fuse, handler, hdr, req, old_name, new_name); } // case FUSE_LINK: case FUSE_OPEN: { /* open_in -> open_out */ const struct fuse_open_in *req = data; return handle_open(fuse, handler, hdr, req); } case FUSE_READ: { /* read_in -> byte[] */ const struct fuse_read_in *req = data; return handle_read(fuse, handler, hdr, req); } case FUSE_WRITE: { /* write_in, byte[write_in.size] -> write_out */ const struct fuse_write_in *req = data; const void* buffer = (const __u8*)data + sizeof(*req); return handle_write(fuse, handler, hdr, req, buffer); } case FUSE_STATFS: { /* getattr_in -> attr_out */ return handle_statfs(fuse, handler, hdr); } case FUSE_RELEASE: { /* release_in -> */ const struct fuse_release_in *req = data; return handle_release(fuse, handler, hdr, req); } case FUSE_FSYNC: { const struct fuse_fsync_in *req = data; return handle_fsync(fuse, handler, hdr, req); } // case FUSE_SETXATTR: // case FUSE_GETXATTR: // case FUSE_LISTXATTR: // case FUSE_REMOVEXATTR: case FUSE_FLUSH: { return handle_flush(fuse, handler, hdr); } case FUSE_OPENDIR: { /* open_in -> open_out */ const struct fuse_open_in *req = data; return handle_opendir(fuse, handler, hdr, req); } case FUSE_READDIR: { const struct fuse_read_in *req = data; return handle_readdir(fuse, handler, hdr, req); } case FUSE_RELEASEDIR: { /* release_in -> */ const struct fuse_release_in *req = data; return handle_releasedir(fuse, handler, hdr, req); } // case FUSE_FSYNCDIR: case FUSE_INIT: { /* init_in -> init_out */ const struct fuse_init_in *req = data; return handle_init(fuse, handler, hdr, req); } default: { TRACE("[%d] NOTIMPL op=%d uniq=%llx nid=%llx\n", handler->token, hdr->opcode, hdr->unique, hdr->nodeid); return -ENOSYS; } } }
static int link_netlink(struct nlmsghdr *nlm) { int len; struct rtattr *rta, *hwaddr; struct ifinfomsg *ifi; char ifn[IF_NAMESIZE + 1]; struct interface *ifp; len = link_route(nlm); if (len != 0) return len; len = link_addr(nlm); if (len != 0) return len; if (nlm->nlmsg_type != RTM_NEWLINK && nlm->nlmsg_type != RTM_DELLINK) return 0; len = nlm->nlmsg_len - sizeof(*nlm); if ((size_t)len < sizeof(*ifi)) { errno = EBADMSG; return -1; } ifi = NLMSG_DATA(nlm); if (ifi->ifi_flags & IFF_LOOPBACK) return 1; rta = (struct rtattr *)(void *)((char *)ifi +NLMSG_ALIGN(sizeof(*ifi))); len = NLMSG_PAYLOAD(nlm, sizeof(*ifi)); *ifn = '\0'; hwaddr = NULL; while (RTA_OK(rta, len)) { switch (rta->rta_type) { case IFLA_WIRELESS: /* Ignore wireless messages */ if (nlm->nlmsg_type == RTM_NEWLINK && ifi->ifi_change == 0) return 1; break; case IFLA_IFNAME: strlcpy(ifn, RTA_DATA(rta), sizeof(ifn)); break; case IFLA_ADDRESS: hwaddr = rta; break; } rta = RTA_NEXT(rta, len); } if (nlm->nlmsg_type == RTM_DELLINK) { handle_interface(-1, ifn); return 1; } /* Virtual interfaces may not get a valid hardware address * at this point. * To trigger a valid hardware address pickup we need to pretend * that that don't exist until they have one. */ if (ifi->ifi_flags & IFF_MASTER && !hwaddr) { handle_interface(-1, ifn); return 1; } /* Check for interface name change */ if (handle_rename(ifi->ifi_index, ifn)) return 1; /* Check for a new interface */ ifp = find_interface(ifn); if (ifp == NULL) { /* If are listening to a dev manager, let that announce * the interface rather than the kernel. */ if (dev_listening() < 1) handle_interface(1, ifn); return 1; } /* Re-read hardware address and friends */ if (!(ifi->ifi_flags & IFF_UP) && hwaddr) { len = l2addr_len(ifi->ifi_type); if (hwaddr->rta_len == RTA_LENGTH(len)) handle_hwaddr(ifn, RTA_DATA(hwaddr), len); } handle_carrier(ifi->ifi_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN, ifi->ifi_flags, ifn); return 1; }