static void *_realloc(void *p, size_t s) { if (!p) return malloc(s, ZONE_NORMAL); if (s <= allocsize(p)) return p; BUG(); return NULL; }
void * realloc(void *ptr, size_t size) { void *p; size_t sz; p = malloc (size); if (!p) return (p); sz = allocsize (ptr); memcpy (p, ptr, (sz > size) ? size : sz); free (ptr); return (p); }
/* * Allocate space for a name. It first looks to see if it already * has an appropriate sized entry, and if not allocates a new one. */ char * savename(char *name) { struct strhdr *np; long len; char *cp; if (name == NULL) panic("bad name\n"); len = strlen(name); np = strtblhdr[len / STRTBLINCR].next; if (np != NULL) { strtblhdr[len / STRTBLINCR].next = np->next; cp = (char *)np; } else { cp = malloc(allocsize(len)); if (cp == NULL) panic("no space for string table\n"); } (void)strlcpy(cp, name, len + 1); return (cp); }
/* * dump a snapshot of the symbol table */ void dumpsymtable(char *filename, long checkpt) { struct entry *ep, *tep; ino_t i; struct entry temp, *tentry; long mynum = 1, stroff = 0; FILE *fp; struct symtableheader hdr; Vprintf(stdout, "Check pointing the restore\n"); if (Nflag) return; if ((fp = fopen(filename, "w")) == NULL) { warn("fopen"); panic("cannot create save file %s for symbol table\n", filename); } clearerr(fp); /* * Assign indices to each entry * Write out the string entries */ for (i = ROOTINO; i <= maxino; i++) { for (ep = lookupino(i); ep != NULL; ep = ep->e_links) { ep->e_index = mynum++; (void)fwrite(ep->e_name, sizeof(char), (int)allocsize(ep->e_namlen), fp); } } /* * Convert pointers to indexes, and output */ tep = &temp; stroff = 0; for (i = ROOTINO; i <= maxino; i++) { for (ep = lookupino(i); ep != NULL; ep = ep->e_links) { memcpy(tep, ep, sizeof(struct entry)); tep->e_name = (char *)stroff; stroff += allocsize(ep->e_namlen); tep->e_parent = (struct entry *)ep->e_parent->e_index; if (ep->e_links != NULL) tep->e_links = (struct entry *)ep->e_links->e_index; if (ep->e_sibling != NULL) tep->e_sibling = (struct entry *)ep->e_sibling->e_index; if (ep->e_entries != NULL) tep->e_entries = (struct entry *)ep->e_entries->e_index; if (ep->e_next != NULL) tep->e_next = (struct entry *)ep->e_next->e_index; (void)fwrite((char *)tep, sizeof(struct entry), 1, fp); } } /* * Convert entry pointers to indexes, and output */ for (i = 0; i < entrytblsize; i++) { if (entry[i] == NULL) tentry = NULL; else tentry = (struct entry *)entry[i]->e_index; (void)fwrite((char *)&tentry, sizeof(struct entry *), 1, fp); } hdr.volno = checkpt; hdr.maxino = maxino; hdr.entrytblsize = entrytblsize; hdr.stringsize = stroff; hdr.dumptime = dumptime; hdr.dumpdate = dumpdate; hdr.ntrec = ntrec; (void)fwrite((char *)&hdr, sizeof(struct symtableheader), 1, fp); if (ferror(fp)) { warn("fwrite"); panic("output error to file %s writing symbol table\n", filename); } (void)fclose(fp); }
* of similar lengths can use the same entry. The value of STRTBLINCR * is chosen so that every entry has at least enough space to hold * a "struct strtbl" header. Thus every entry can be linked onto an * apprpriate free list. * * NB. The macro "allocsize" below assumes that "struct strhdr" * has a size that is a power of two. */ struct strhdr { struct strhdr *next; }; #define STRTBLINCR (sizeof(struct strhdr)) #define allocsize(size) (((size) + 1 + STRTBLINCR - 1) & ~(STRTBLINCR - 1)) static struct strhdr strtblhdr[allocsize(NAME_MAX) / STRTBLINCR]; /* * Allocate space for a name. It first looks to see if it already * has an appropriate sized entry, and if not allocates a new one. */ char * savename(char *name) { struct strhdr *np; long len; char *cp; if (name == NULL) panic("bad name\n"); len = strlen(name);
void setsize(int new_len) { if (list_size < new_len) allocsize(new_len); num_elements = new_len; }