+static inline int flags_writable(int open_flags)
+{
+ return open_flags & (O_RDWR | O_WRONLY);
+}
+
+static int alloc_fd(struct lookup_table_entry *lte, struct wimlib_fd **fd_ret)
+{
+ struct wimlib_fd *fds, *fd;
+ if (lte->num_opened_fds == lte->num_allocated_fds) {
+ if (lte->num_allocated_fds > 0xffff - 8)
+ return -ENFILE;
+
+ fds = CALLOC(lte->num_allocated_fds + 8, sizeof(struct wimlib_fd));
+ if (!fds)
+ return -ENOMEM;
+ memcpy(fds, lte->fds,
+ lte->num_allocated_fds * sizeof(struct wimlib_fd));
+ FREE(lte->fds);
+ lte->fds = fds;
+ }
+ fd = lte->fds;
+ while (1) {
+ if (!fd->lte) {
+ fd->hard_link_group = 0;
+ fd->staging_fd = -1;
+ fd->lte = lte;
+ *fd_ret = fd;
+ return 0;
+ }
+ fd++;
+ }
+}
+
+static int close_fd(struct wimlib_fd *fd)
+{
+ struct lookup_table_entry *lte = fd->lte;
+ wimlib_assert(lte);
+ wimlib_assert(lte->num_opened_fds);
+
+ u16 idx = fd - lte->fds;
+ if (lte->staging_file_name && fd->staging_fd != -1)
+ if (close(fd->staging_fd) != 0)
+ return -errno;
+ if (--lte->num_opened_fds == 0 && lte->refcnt == 0)
+ free_lookup_table_entry(lte);
+ fd->lte = NULL;
+ return 0;
+}
+