static void write_obj(FILE *file, WObj *obj, int lvl) { WWsSplit *split; int tls, brs; if(WOBJ_IS(obj, WFrame)){ indent(file, lvl); fprintf(file, "frame %d\n", ((WFrame*)obj)->frame_id); return; } if(!WOBJ_IS(obj, WWsSplit)) return; split=(WWsSplit*)obj; tls=tree_size(split->tl, split->dir); brs=tree_size(split->br, split->dir); indent(file, lvl); if(split->dir==HORIZONTAL) fprintf(file, "hsplit %d, %d {\n", tls, brs); else fprintf(file, "vsplit %d, %d {\n", tls, brs); write_obj(file, split->tl, lvl+1); write_obj(file, split->br, lvl+1); indent(file, lvl); fprintf(file, "}\n"); }
int SCOPE post_wait4(const struct syscall_regs * regs) { write_eax(regs); uintptr_t stat_addr = regs->ecx; uintptr_t ru = regs->esi; write_obj(stat_addr); if (stat_addr != 0) write_mem(stat_addr, sizeof(int)); write_obj(ru); if (ru != 0) write_mem(ru, sizeof(struct rusage)); return 0; }
int SCOPE pre_exit_group(const struct syscall_regs * regs) { /* save ebx */ write_obj(regs->ebx); return 0; }
int write_obj(int fd, object *obj_ptr, char perm_only ) { int n, cnt, cnt2=0, error=0; otag *op; n = write(fd, obj_ptr, sizeof(object)); if(n < sizeof(object)) merror("write_obj", FATAL); cnt = count_obj(obj_ptr, perm_only); n = write(fd, &cnt, sizeof(int)); if(n < sizeof(int)) merror("write_obj", FATAL); if(cnt > 0) { op = obj_ptr->first_obj; while(op) { if(!perm_only || (perm_only && (F_ISSET(op->obj, OPERMT)))) { if(write_obj(fd, op->obj, perm_only) < 0) error = 1; cnt2++; } op = op->next_tag; } } if(cnt != cnt2 || error) return(-1); else return(0); }
static int simple_cat(void) { uint16_t type; void *data; int i, rc; for(i=0; i<infile_cnt; i++) { while((rc = scamper_file_read(infiles[i], filter, &type, &data)) == 0) { /* EOF */ if(data == NULL) break; if(write_obj(type, data) != 0) { return -1; } } /* error when reading the input file */ if(rc != 0) { return -1; } scamper_file_close(infiles[i]); infiles[i] = NULL; } return 0; }
int SCOPE post_rt_sigprocmask(const struct syscall_regs * regs) { write_eax(regs); if (regs->eax == 0) { int how = regs->ebx; int set = regs->ecx; int oset = regs->edx; int sigsetsize = regs->esi; write_obj(sigsetsize); if (sigsetsize != sizeof(k_sigset_t)) { INJ_WARNING("sigsetsize %d != %d\n", sigsetsize, sizeof(k_sigset_t)); return 0; } if (set) { k_sigset_t mask; __dup_mem(&mask, set, sigsetsize); sigdelsetmask(&mask, sigmask(SIGKILL)|sigmask(SIGSTOP)); if (how == SIG_BLOCK) { sigorsets(&state_vector.sigmask, &state_vector.sigmask, &mask); } else if (how == SIG_UNBLOCK) { signandsets(&state_vector.sigmask, &state_vector.sigmask, &mask); } else { /* SIG_SETMASK */ state_vector.sigmask = mask; } } write_obj(oset); if (oset) { if (set == 0) { k_sigset_t mask; __dup_mem(&mask, oset, sigsetsize); state_vector.sigmask = mask; } write_mem(oset, sigsetsize); } } return 0; }
static int sort_cat(void) { heap_t *heap = NULL; sort_struct_t *ss = NULL; sort_struct_t *s; int i; if((heap = heap_alloc(sort_struct_cmp)) == NULL) { goto err; } if((ss = malloc(sizeof(sort_struct_t) * infile_cnt)) == NULL) { goto err; } memset(ss, 0, sizeof(sort_struct_t) * infile_cnt); /* * start by filling all file slots with the first data object from * each file */ for(i=0; i<infile_cnt; i++) { ss[i].file = i; if(sort_cat_fill(heap, &ss[i]) != 0) { goto err; } } /* * now, read each object off the heap in their appropriate priority and * replace each heap object with another from the file until there is * nothing left. */ while((s = (sort_struct_t *)heap_remove(heap)) != NULL) { if(write_obj(s->type, s->data) != 0) { goto err; } if(sort_cat_fill(heap, s) != 0) { goto err; } } heap_free(heap, NULL); free(ss); return 0; err: if(heap != NULL) heap_free(heap, NULL); if(ss != NULL) free(ss); return -1; }
int SCOPE post_rt_sigaction(const struct syscall_regs * regs) { write_eax(regs); int signo = regs->ebx; if ((signo == SIGKILL) || (signo == SIGSTOP)) return 0; if ((signo < 1) || (signo > K_NSIG)) return 0; /* rt_sigaction should not fail... */ ASSERT(regs->eax >= 0, regs, "rt_sigaction failed, we cannot handle...\n"); uintptr_t act = regs->ecx; uintptr_t oact = regs->edx; int sigsetsize = regs->esi; write_obj(sigsetsize); write_obj(oact); write_obj(act); /* we need copy modified act back */ struct k_sigaction * s = &state_vector.sigactions[regs->ebx]; if (act != 0) __upd_mem(act, s, sizeof(*s)); if (sigsetsize != sizeof(k_sigset_t)) { INJ_WARNING("esi (%d) != %d\n", sigsetsize, sizeof(k_sigset_t)); return 0; } if (oact != 0) { /* we modify the result */ struct k_sigaction d; __dup_mem(&d, oact, sizeof(d)); if (d.sa_handler == (void*)wrapped_sighandler) { struct k_sigaction * p = &(state_vector.sigactions[regs->ebx]); d = *p; __upd_mem(oact, &d, sizeof(d)); } write_mem(oact, sizeof(struct k_sigaction)); } return 0; }
bool write_objset(SerialOut &out, const ObjectSet& list) { auto len = static_cast<uint32_t>(list.size()); out.out_.Write((const char*)&len, sizeof(len)); for (auto &obj : list) { if (!write_obj(out, obj)) return false; } return out.out_; }
int SCOPE post_time(const struct syscall_regs * regs) { write_eax(regs); write_obj(regs->ebx); if (regs->ebx != 0) write_mem(regs->ebx, sizeof(time_t)); return 0; }
int SCOPE post_nanosleep(const struct syscall_regs * regs) { write_eax(regs); uintptr_t o = regs->ecx; write_obj(o); if (o != 0) write_mem(o, sizeof(struct k_timespec)); return 0; }
int SCOPE post_gettimeofday(const struct syscall_regs * regs) { write_eax(regs); if (regs->eax >= 0) { uintptr_t TP, TZP; TP = regs->ebx; TZP = regs->ecx; write_obj(TP); write_obj(TZP); if (TP != 0) write_mem(TP, sizeof(struct k_timeval)); if (TZP != 0) write_mem(TZP, sizeof(struct k_timezone)); } return 0; }
static void write_internal(ScmObj port, ScmObj obj, enum ScmOutputType otype) { DECLARE_INTERNAL_FUNCTION("write"); ENSURE_PORT(port); SCM_ENSURE_LIVE_PORT(port); if (!(SCM_PORT_FLAG(port) & SCM_PORTFLAG_OUTPUT)) ERR_OBJ("output port required but got", port); write_obj(port, obj, otype); scm_port_flush(port); }
int SCOPE post__newselect(const struct syscall_regs * regs) { write_eax(regs); int n = regs->ebx; uint32_t inp = regs->ecx; uint32_t outp = regs->edx; uint32_t exp = regs->esi; write_obj(n); write_obj(inp); write_obj(outp); write_obj(exp); int fd_bytes = FDS_BYTES(n); if (inp != 0) write_mem(inp, fd_bytes); if (outp != 0) write_mem(outp, fd_bytes); if (exp != 0) write_mem(exp, fd_bytes); return 0; }
void write_mesh(const std::string &filename, const MatrixXu &F, const MatrixXf &V, const MatrixXf &N, const MatrixXf &Nf, const MatrixXf &UV, const MatrixXf &C, const ProgressCallback &progress) { std::string extension; if (filename.size() > 4) extension = str_tolower(filename.substr(filename.size()-4)); if (extension == ".ply") write_ply(filename, F, V, N, Nf, UV, C, progress); else if (extension == ".obj") write_obj(filename, F, V, N, Nf, UV, C, progress); else throw std::runtime_error("write_mesh: Unknown file extension \"" + extension + "\" (.ply/.obj are supported)"); }
bool write_mesh(const PolygonMesh& mesh, const std::string& filename) { // extract file extension std::string::size_type dot(filename.rfind(".")); if (dot == std::string::npos) return false; std::string ext = filename.substr(dot+1, filename.length()-dot-1); std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); // extension determines reader if(ext=="obj") { return write_obj(mesh, filename); } // we didn't find a writer module return false; }
static void dodo_write_workspaces(FILE *file) { WWorkspace *ws; int i=0; FOR_ALL_TYPED(current_screen, ws, WWorkspace){ i++; if(ws->name==NULL){ warn("Not saving workspace %d -- no name", i); continue; } if(ws->splitree==NULL){ warn("Empty workspace -- this cannot happen"); continue; } fprintf(file, "workspace \"%s\" {\n", ws->name); write_obj(file, ws->splitree, 1); fprintf(file, "}\n"); }
static void write_obj(ScmObj port, ScmObj obj, enum ScmOutputType otype) { ScmObj sym; #if SCM_USE_SRFI38 if (INTERESTINGP(obj)) { scm_intobj_t index = get_shared_index(obj); if (index > 0) { /* defined datum */ scm_format(port, SCM_FMT_RAW_C, "#~ZU#", (size_t)index); return; } if (index < 0) { /* defining datum, with the new index negated */ scm_format(port, SCM_FMT_RAW_C, "#~ZU=", (size_t)-index); /* Print it; the next time it'll be defined. */ } } #endif switch (SCM_TYPE(obj)) { #if SCM_USE_INT case ScmInt: scm_format(port, SCM_FMT_RAW_C, "~MD", SCM_INT_VALUE(obj)); break; #endif case ScmCons: if (ERROBJP(obj)) write_errobj(port, obj, otype); else write_list(port, obj, otype); break; case ScmSymbol: scm_port_puts(port, SCM_SYMBOL_NAME(obj)); break; #if SCM_USE_CHAR case ScmChar: write_char(port, obj, otype); break; #endif #if SCM_USE_STRING case ScmString: write_string(port, obj, otype); break; #endif case ScmFunc: scm_port_puts(port, (SCM_SYNTAXP(obj)) ? "#<syntax " : "#<subr "); sym = scm_symbol_bound_to(obj); if (TRUEP(sym)) scm_display(port, sym); else scm_format(port, SCM_FMT_RAW_C, "~P", (void *)obj); scm_port_put_char(port, '>'); break; #if SCM_USE_HYGIENIC_MACRO case ScmMacro: scm_port_puts(port, "#<macro "); write_obj(port, SCM_HMACRO_RULES(obj), otype); scm_port_puts(port, ">"); break; case ScmFarsymbol: write_farsymbol(port, obj, otype); break; case ScmSubpat: if (SCM_SUBPAT_PVARP(obj)) { #if SCM_DEBUG_MACRO scm_port_puts(port, "#<pvar "); write_obj(port, SCM_SUBPAT_OBJ(obj), otype); scm_format(port, SCM_FMT_RAW_C, " ~MD>", SCM_SUBPAT_PVAR_INDEX(obj)); #else /* not SCM_DEBUG_MACRO */ write_obj(port, SCM_SUBPAT_OBJ(obj), otype); #endif /* not SCM_DEBUG_MACRO */ } else { SCM_ASSERT(SCM_SUBPAT_REPPATP(obj)); write_obj(port, SCM_SUBPAT_REPPAT_PAT(obj), otype); #if SCM_DEBUG_MACRO scm_format(port, SCM_FMT_RAW_C, " ..[~MD]..", SCM_SUBPAT_REPPAT_PVCOUNT(obj)); #else scm_port_puts(port, " ..."); #endif } break; #endif /* SCM_USE_HYGIENIC_MACRO */ case ScmClosure: #if SCM_USE_LEGACY_MACRO if (SYNTACTIC_CLOSUREP(obj)) scm_port_puts(port, "#<syntactic closure "); else #endif scm_port_puts(port, "#<closure "); write_obj(port, SCM_CLOSURE_EXP(obj), otype); scm_port_put_char(port, '>'); break; #if SCM_USE_VECTOR case ScmVector: write_vector(port, obj, otype); break; #endif case ScmPort: write_port(port, obj, otype); break; #if SCM_USE_CONTINUATION case ScmContinuation: scm_format(port, SCM_FMT_RAW_C, "#<continuation ~P>", (void *)obj); break; #endif case ScmValuePacket: scm_port_puts(port, "#<values "); write_obj(port, SCM_VALUEPACKET_VALUES(obj), otype); #if SCM_USE_VALUECONS #if SCM_USE_STORAGE_FATTY /* SCM_VALUEPACKET_VALUES() changes the type destructively */ SCM_ENTYPE(obj, ScmValuePacket); #else /* SCM_USE_STORAGE_FATTY */ #error "valuecons is not supported on this storage implementation" #endif /* SCM_USE_STORAGE_FATTY */ #endif /* SCM_USE_VALUECONS */ scm_port_put_char(port, '>'); break; case ScmConstant: write_constant(port, obj, otype); break; #if SCM_USE_SSCM_EXTENSIONS case ScmCPointer: scm_format(port, SCM_FMT_RAW_C, "#<c_pointer ~P>", SCM_C_POINTER_VALUE(obj)); break; case ScmCFuncPointer: scm_format(port, SCM_FMT_RAW_C, "#<c_func_pointer ~P>", (void *)(uintptr_t)SCM_C_FUNCPOINTER_VALUE(obj)); break; #endif case ScmRational: case ScmReal: case ScmComplex: default: SCM_NOTREACHED; } }
void lbfs_write (file_cache *fe, uint64 size, fattr3 fa, ref<server> srv, AUTH *a, write_obj::cb_t cb) { vNew write_obj (fe, size, fa, srv, a, cb); }
static void write_string(ScmObj port, ScmObj obj, enum ScmOutputType otype) { #if SCM_USE_MULTIBYTE_CHAR ScmCharCodec *codec; ScmMultibyteString mbs; size_t len; #else scm_int_t i, len; #endif const ScmSpecialCharInfo *info; const char *str; scm_ichar_t c; DECLARE_INTERNAL_FUNCTION("write"); str = SCM_STRING_STR(obj); switch (otype) { case AS_WRITE: scm_port_put_char(port, '\"'); /* opening doublequote */ #if SCM_USE_MULTIBYTE_CHAR if (scm_current_char_codec != scm_port_codec(port)) { /* Since the str does not have its encoding information, here * assumes that scm_current_char_codec is that. And then SigScheme * does not have an encoding conversion mechanism, puts it * as-is. */ scm_port_puts(port, str); } else { len = strlen(str); codec = scm_port_codec(port); SCM_MBS_INIT2(mbs, str, len); while (SCM_MBS_GET_SIZE(mbs)) { c = SCM_CHARCODEC_READ_CHAR(codec, mbs); #else /* SCM_USE_MULTIBYTE_CHAR */ len = SCM_STRING_LEN(obj); for (i = 0; i < len; i++) { c = str[i]; #endif /* SCM_USE_MULTIBYTE_CHAR */ for (info = scm_special_char_table; info->esc_seq; info++) { if (c == info->code) { scm_port_puts(port, info->esc_seq); goto continue2; } } scm_port_put_char(port, c); continue2: ; } #if SCM_USE_MULTIBYTE_CHAR } #endif scm_port_put_char(port, '\"'); /* closing doublequote */ break; case AS_DISPLAY: scm_port_puts(port, str); break; default: SCM_NOTREACHED; } } #endif /* SCM_USE_STRING */ static void write_list(ScmObj port, ScmObj lst, enum ScmOutputType otype) { ScmObj car; #if SCM_USE_SRFI38 size_t necessary_close_parens; scm_intobj_t index; #endif DECLARE_INTERNAL_FUNCTION("write"); #if SCM_USE_SRFI38 necessary_close_parens = 1; cheap_recursion: #endif SCM_ASSERT(CONSP(lst)); scm_port_put_char(port, '('); FOR_EACH (car, lst) { write_obj(port, car, otype); if (!CONSP(lst)) break; scm_port_put_char(port, ' '); #if SCM_USE_SRFI38 /* See if the next pair is shared. Note that the case * where the first pair is shared is handled in * write_obj(). */ index = get_shared_index(lst); if (index > 0) { /* defined datum */ scm_format(port, SCM_FMT_RAW_C, ". #~ZU#", (size_t)index); goto close_parens_and_return; } if (index < 0) { /* defining datum, with the new index negated */ scm_format(port, SCM_FMT_RAW_C, ". #~ZU=", (size_t)-index); necessary_close_parens++; goto cheap_recursion; } #endif }
static bool db_store(DB *db, const string& filename) { bool mkgzip = ends_with_gz(filename); uniq<SerialOut> sout(SerialOut::Open(db, filename, mkgzip)); if (mkgzip) db->config_.Log(Message, "writing compressed database\n"); else db->config_.Log(Message, "writing database\n"); SerialOut &out(*sout); if (!sout || !out.out_) { db->config_.Log(Error, "failed to open file %s for writing\n", filename.c_str()); return false; } Header hdr; memset(&hdr, 0, sizeof(hdr)); memcpy(hdr.magic, depdb_magic, sizeof(hdr.magic)); hdr.version = 1; // flags: if (db->ignore_file_rules_.size()) hdr.flags |= DBFlags::IgnoreRules; if (db->package_library_path_.size()) hdr.flags |= DBFlags::PackageLDPath; if (db->base_packages_.size()) hdr.flags |= DBFlags::BasePackages; if (db->strict_linking_) hdr.flags |= DBFlags::StrictLinking; if (db->assume_found_rules_.size()) hdr.flags |= DBFlags::AssumeFound; if (db->contains_filelists_) hdr.flags |= DBFlags::FileLists; // Figure out which database format version this will be if (db->contains_pkgbase_) hdr.version = 13; else if (db->contains_check_depends_) hdr.version = 12; else if (db->contains_make_depends_) hdr.version = 10; else if (db->contains_package_depends_) hdr.version = 10; // used to be 4 else if (hdr.flags & DBFlags::FileLists) hdr.version = 7; else if (hdr.flags & DBFlags::AssumeFound) hdr.version = 6; else if (db->contains_groups_) hdr.version = 5; else if (hdr.flags) hdr.version = 2; // okay // ver8 introduces faster refs... if (hdr.version < 8) hdr.version = 8; // ver9 contains interpreter data if (hdr.version < 9) hdr.version = 9; out.version_ = hdr.version; out <= hdr; out <= db->name_; if (!write_stringlist(out, db->library_path_)) return false; out <= (uint32_t)db->packages_.size(); for (auto &pkg : db->packages_) { if (!write_pkg(out, pkg, hdr.version, hdr.flags)) return false; } uint32_t cnt_found = 0, cnt_missing = 0; { out <= (uint32_t)db->objects_.size(); for (auto &obj : db->objects_) { if (!write_obj(out, obj)) return false; if (!obj->req_found_.empty()) ++cnt_found; if (!obj->req_missing_.empty()) ++cnt_missing; } } out <= cnt_found; for (Elf *obj : db->objects_) { if (obj->req_found_.empty()) continue; if (!write_obj(out, obj)) return false; if (!write_objset(out, obj->req_found_)) return false; } out <= cnt_missing; for (Elf *obj : db->objects_) { if (obj->req_missing_.empty()) continue; if (!write_obj(out, obj)) return false; if (!write_stringset(out, obj->req_missing_)) return false; } if (hdr.flags & DBFlags::IgnoreRules) { if (!write_stringset(out, db->ignore_file_rules_)) return false; } if (hdr.flags & DBFlags::AssumeFound) { if (!write_stringset(out, db->assume_found_rules_)) return false; } if (hdr.flags & DBFlags::PackageLDPath) { out <= (uint32_t)db->package_library_path_.size(); for (auto iter : db->package_library_path_) { out <= iter.first; if (!write_stringlist(out, iter.second)) return false; } } if (hdr.flags & DBFlags::BasePackages) { if (!write_stringset(out, db->base_packages_)) return false; } return out.out_; }
static void dump(FILE *f, HASHTAB t, OBJ ob, int *labct, OBJ *ep) { if (is_structured(ob)){ int sz = _size(_header(ob)), fs = _flags(_header(ob)), i; intptr_t flds; OBJ *data; if (_tstRc(_header(ob),1)) { write_obj(f,mkExclCell(fs,sz),ep); if (*ep) return; } else { HASHENTRY e; /* check if object already dumped */ i = (WORD)ob % HASHSIZE; for (e = t->tab[i]; e; e = e->next) { if (e->obj == ob) { write_obj(f,mkRefToCell(e->label),ep); return; } } /* first time dumping a shared cell */ write_obj(f,mkSharedCell(fs,sz),ep); if (*ep) return; /* create new entry in hashtab and assign label to it, since we might have to visit it again. */ e = newEntry(); e->label = (*labct)++; write_obj(f,mkRefToCell(e->label),ep); if (*ep) return; e->obj = ob; e->next = t->tab[i]; t->tab[i] = e; } /* calculate no of fields */ if (sz % flat_offset_ssize == big_escape_ssize){ flds = unpack_word(((BCELL)ob)->size); write_obj(f,(OBJ)flds,ep); if (*ep) return; data = _bdata(ob); } else { flds = sz % flat_offset_ssize; data = _data(ob); } if (sz >= flat_offset_ssize) { if (fs & (1 << byte_flat_sflag)){ /* write 2 words and rest as char stream */ unsigned char * cdata = (unsigned char*)(data+2); int cflds = (flds-2) * sizeof(OBJ); write_obj(f,data[0],ep); write_obj(f,data[1],ep); for (i = 0; i < cflds && !*ep; i++) { if (putc(cdata[i],f) != cdata[i]){ get_unix_failure(errno,*ep); } } } else { /* write fields as coded longwords */ for (i = 0; i < flds && !*ep; i++) { write_obj(f,data[i],ep); } } } else { /* recursivly dump fields. */ for (i = 0; i < flds && !*ep; i++) { dump(f,t,data[i],labct,ep); } } } else { write_obj(f,ob,ep); } }
int write_rom(int fd, room *rom_ptr, char perm_only ) { int n, cnt, error=0; xtag *xp; ctag *cp; otag *op; char pcontain; n = write(fd, rom_ptr, sizeof(room)); if(n < sizeof(room)) merror("write_rom", FATAL); cnt = count_ext(rom_ptr); n = write(fd, &cnt, sizeof(int)); if(n < sizeof(int)) merror("write_rom", FATAL); xp = rom_ptr->first_ext; while(xp) { n = write(fd, xp->ext, sizeof(exit_)); if(n < sizeof(exit_)) merror("write_rom", FATAL); xp = xp->next_tag; } cnt = count_mon(rom_ptr, perm_only); n = write(fd, &cnt, sizeof(int)); if(n < sizeof(int)) merror("write_rom", FATAL); cp = rom_ptr->first_mon; while(cp) { if(!perm_only || (perm_only && F_ISSET(cp->crt, MPERMT))) if(write_crt(fd, cp->crt, 0) < 0) error = 1; cp = cp->next_tag; } cnt = count_ite(rom_ptr, perm_only); n = write(fd, &cnt, sizeof(int)); if(n < sizeof(int)) merror("write_rom", FATAL); op = rom_ptr->first_obj; while(op) { if(!perm_only || (perm_only && (F_ISSET(op->obj, OPERMT)))){ if (F_ISSET(op->obj,OCONTN) && (F_ISSET(op->obj, OPERMT))) pcontain = ALLITEMS; else pcontain = perm_only; if(write_obj(fd, op->obj, pcontain) < 0) error = 1; } op = op->next_tag; } if(!rom_ptr->short_desc) cnt = 0; else cnt = strlen(rom_ptr->short_desc) + 1; n = write(fd, &cnt, sizeof(int)); if(n < sizeof(int)) merror("write_rom", FATAL); if(cnt) { n = write(fd, rom_ptr->short_desc, cnt); if(n < cnt) merror("write_rom", FATAL); } if(!rom_ptr->long_desc) cnt = 0; else cnt = strlen(rom_ptr->long_desc) + 1; n = write(fd, &cnt, sizeof(int)); if(n < sizeof(int)) merror("write_rom", FATAL); if(cnt) { n = write(fd, rom_ptr->long_desc, cnt); if(n < cnt) merror("write_rom", FATAL); } if(!rom_ptr->obj_desc) cnt = 0; else cnt = strlen(rom_ptr->obj_desc) + 1; n = write(fd, &cnt, sizeof(int)); if(n < sizeof(int)) merror("write_rom", FATAL); if(cnt) { n = write(fd, rom_ptr->obj_desc, cnt); if(n < cnt) merror("write_rom", FATAL); } if(error) return(-1); else return(0); }