/* B01902062 藍ĉŒşç‘‹ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "common.h" #include #include #include #include #include void* e_malloc (size_t size) { void* ptr; ptr = malloc (size); if (ptr == NULL) e_err_exit ("out of memory"); return ptr; } char* e_strcat (const char* s1, const char* s2) { int s1len = strlen (s1); int s2len = strlen (s2); char* newstr = e_malloc (sizeof (char) * (s1len + s2len + 1)); strcpy (newstr, s1); strcpy (newstr + s1len, s2); newstr[s1len + s2len] = '\0'; return newstr; } void e_err_exit (const char* a) { perror (a); exit (1); } ftab* ftab_create (int maxfd) { ftab* ft = e_malloc (sizeof (ftab)); ft->maxfd = maxfd; ft->flist = e_malloc (sizeof (fnode) * maxfd); memset (ft->flist, 0, sizeof (fnode) * maxfd); return ft; } fnode* ftab_insert (ftab* ft, dev_t fdev, ino_t fino, int fd) { fnode *search = ftab_search (ft, fdev, fino); if (search == NULL) { for (int i = 0; i < ft->maxfd; i++) { if (!(ft->flist[i].active)) { ft->flist[i].active = true; ft->flist[i].ref_count = 0; ft->flist[i].fdev = fdev; ft->flist[i].fino = fino; FD_ZERO (&(ft->flist[i].fset)); fnode_ref (&(ft->flist[i]), fd); return &(ft->flist[i]); } } return NULL; } else { fnode_ref (search, fd); return search; } } fnode* ftab_search (ftab* ft, dev_t fdev, ino_t fino) { for (int i = 0; i < ft->maxfd; i++) { if (ft->flist[i].active && ft->flist[i].fdev == fdev && ft->flist[i].fino == fino) { return &(ft->flist[i]); } } return NULL; } void ftab_free (ftab* ft) { free (ft->flist); free (ft); } fnode* fnode_ref (fnode* fn, int fd) { if (fd >= 0 && !FD_ISSET (fd, &fn->fset)) { fn->ref_count++; FD_SET (fd, &fn->fset); } return fn; } void fnode_unref (fnode* fn, ftab* ft) { fn->ref_count--; if (fn->ref_count <= 0) { for (int i = 0; i < ft->maxfd; i++) if (FD_ISSET (i, &fn->fset)) close (i); fn->active = false; } }