/* populates a hash table starting with the mount list */ static void mnt_populate(Hash_table *tbl) { struct mount_entry *head = read_file_system_list(false); struct mount_entry *next; union { const void *ptr; struct mount_entry *old_me; } exist; for ( ; head; head = next) { next = head->me_next; /* ensure we can me_free() without side effects when skipping */ head->me_next = NULL; /* we don't care about FS type at all */ if (head->me_type_malloced) { free(head->me_type); head->me_type_malloced = 0; } head->me_type = NULL; if (!mog_mnt_usable(head)) goto skip; /* mark the device as something we _might_ track util for */ mog_iou_active(head->me_dev); switch (hash_insert_if_absent(tbl, head, &exist.ptr)) { case 0: { /* chain entries if they have multiple st_dev */ struct mount_entry *me = exist.old_me; while (me->me_next) me = me->me_next; assert(me != head && "circular mount ref"); me->me_next = head; } continue; case 1: continue; default: mog_oom(); } assert(0 && "compiler bug?"); skip: me_free(head); } }
int run_event (const char *cmd, size_t argc, char *argv[]) { int r; struct entry *entry = NULL, *old_entry; if (argc != 3) { fprintf (stderr, _("use 'event <name> <eventset> <script>' to register an event handler\n")); goto error; } entry = calloc (1, sizeof *entry); if (entry == NULL) { perror ("calloc"); goto error; } entry->eh = -1; r = event_bitmask_of_event_set (argv[1], &entry->event_bitmask); if (r == -1) goto error; entry->name = strdup (argv[0]); if (entry->name == NULL) { perror ("strdup"); goto error; } entry->command = strdup (argv[2]); if (entry->command == NULL) { perror ("strdup"); goto error; } entry->eh = guestfs_set_event_callback (g, do_event_handler, entry->event_bitmask, 0, entry); if (entry->eh == -1) goto error; r = hash_insert_if_absent (event_handlers, entry, (const void **) &old_entry); if (r == -1) goto error; if (r == 0) { /* old_entry set to existing entry */ entry->next = old_entry->next; /* XXX are we allowed to update the old entry? */ old_entry->next = entry; } return 0; error: if (entry) { if (entry->eh >= 0) guestfs_delete_event_callback (g, entry->eh); free (entry->name); free (entry->command); free (entry); } return -1; }