📄 file.c
字号:
return ret;#elif FILEPOS_BITS < FULL_BITS /* ztofull puts the value into native byte order */ pos = ztolong(zpos); /* on some hosts, FILEPOS is not a scalar */ memset(&ret, 0, sizeof(FILEPOS)); memcpy((void *)&ret, (void *)&pos, sizeof(pos)); return ret;#else /* FILEPOS_BITS > FULL_BITS */ if (!zgtmaxfull(zpos)) { /* ztofull puts the value into native byte order */ pos = ztofull(zpos); memset(&ret, 0, sizeof(FILEPOS)); memcpy((void *)&ret, (void *)&pos, sizeof(pos)); return ret; } /* * copy (and swap if needed) lower part of the ZVALUE as needed */ if (zpos.len >= FILEPOS_BITS/BASEB) { /* copy the lower FILEPOS_BITS of the ZVALUE */ memcpy(&tmp, zpos.v, sizeof(FILEPOS)); } else { /* copy what bits we can into the temp value */ memset(&tmp, 0, sizeof(FILEPOS)); memcpy(&tmp, zpos.v, zpos.len*BASEB/8); } /* swap into native byte order */ SWAP_HALF_IN_FILEPOS(&ret, &tmp); /* * return our result */ return ret;#endif /* FILEPOS_BITS <= FULL_BITS */}/* * get_open_pos - get a an open file position * * given: * fp open file stream * res where to place the file position (ZVALUE) * * returns: * 0 res points to the file position * -1 error */static intget_open_pos(FILE *fp, ZVALUE *res){ FILEPOS pos; /* current file position */ /* * get the file position */ if (f_tell(fp, &pos) < 0) { /* cannot get file position, return -1 */ return -1; } /* * update file position and return success */ *res = filepos2z(pos); return 0;}/* * getloc - get the current position of the file * * given: * id file id of the file * loc pointer to result * * returns: * 0 able to get file position * -1 unable to get file position */intgetloc(FILEID id, ZVALUE *res){ FILEIO *fiop; /* file structure */ FILE *fp; /* * convert id to stream */ fiop = findid(id, -1); if (fiop == NULL) { /* file not open */ return -1; } fp = fiop->fp; if (fp == NULL) { math_error("Bogus internal file pointer!"); /*NOTREACHED*/ } /* * return result */ return get_open_pos(fp, res);}intftellid(FILEID id, ZVALUE *res){ FILEIO *fiop; FILEPOS fpos; /* current file position */ /* get FILEIO */ fiop = findid(id, -1); if (fiop == NULL) return -2; /* get the file position */ if (f_tell(fiop->fp, &fpos) < 0) return -3; /* convert file position to ZVALUE */ *res = filepos2z(fpos); return 0;}intfseekid(FILEID id, ZVALUE offset, int whence){ FILEIO *fiop; /* FILEIO of file */ FILEPOS off; /* offset as a FILEPOS */ ZVALUE cur, tmp; /* current or end of file location */ int ret = 0; /* return code */ /* setup */ fiop = findid(id, -1); if (fiop == NULL) return -2; /* seek depending on whence */ switch (whence) { case 0: /* construct seek position, off = offset */ if (zisneg(offset)) return -3; off = z2filepos(offset); /* seek there */ ret = f_seek_set(fiop->fp, &off); break; case 1: /* construct seek position, off = cur+offset */ f_tell(fiop->fp, &off); cur = filepos2z(off); zadd(cur, offset, &tmp); zfree(cur); if (zisneg(tmp)) { zfree(tmp); return -3; } off = z2filepos(tmp); zfree(tmp); /* seek there */ ret = f_seek_set(fiop->fp, &off); break; case 2: /* construct seek position, off = len+offset */ if (get_open_siz(fiop->fp, &cur) < 0) return -4; zadd(cur, offset, &tmp); zfree(cur); if (zisneg(tmp)) { zfree(tmp); return -3; } off = z2filepos(tmp); zfree(tmp); /* seek there */ ret = f_seek_set(fiop->fp, &off); break; default: return -5; } return ret;}/* * set_open_pos - set a an open file position * * given: * fp open file stream * zpos file position (ZVALUE) to set * * returns: * 0 res points to the file position * -1 error * * NOTE: Due to fsetpos limitation, position is set relative to only * the beginning of the file. */static intset_open_pos(FILE *fp, ZVALUE zpos){ FILEPOS pos; /* current file position */ /* * convert ZVALUE to file position */ pos = z2filepos(zpos); /* * set the file position */ if (f_seek_set(fp, &pos) < 0) { /* cannot set file position, return -1 */ return -1; } /* * return sucess */ return 0;}/* * setloc - set the current position of the file * * given: * id file id of the file * zpos file position (ZVALUE) to set * * returns: * 0 able to set file position * -1 unable to set file position */intsetloc(FILEID id, ZVALUE zpos){ FILEIO *fiop; /* file structure */ FILE *fp; /* * firewall */ if ((id == FILEID_STDIN) || (id == FILEID_STDOUT) || (id == FILEID_STDERR)) { math_error("Cannot fseek stdin, stdout, or stderr"); /*NOTREACHED*/ } /* * convert id to stream */ fiop = findid(id, -1); if (fiop == NULL) { /* file not open */ return -1; } fp = fiop->fp; if (fp == NULL) { math_error("Bogus internal file pointer!"); /*NOTREACHED*/ } fiop->action = 0; /* * return result */ return set_open_pos(fp, zpos);}/* * off_t2z - convert an off_t into a ZVALUE * * given: * siz file size * * returns: * file size as a ZVALUE *//*ARGSUSED*/static ZVALUEoff_t2z(off_t siz){ ZVALUE ret; /* ZVALUE file size to return */ /* * store off_t in a ZVALUE as a positive value */ ret.len = OFF_T_BITS/BASEB; ret.v = alloc(ret.len); zclearval(ret); SWAP_HALF_IN_OFF_T(ret.v, &siz); ret.sign = 0; ztrim(&ret); /* * return our result */ return ret;}/* * dev2z - convert a stat.st_dev into a ZVALUE * * given: * dev device * * returns: * file size as a ZVALUE */static ZVALUEdev2z(dev_t dev){ ZVALUE ret; /* ZVALUE file size to return */ /* * store off_t in a ZVALUE as a positive value */ ret.len = DEV_BITS/BASEB; ret.v = alloc(ret.len); zclearval(ret); SWAP_HALF_IN_DEV(ret.v, &dev); ret.sign = 0; ztrim(&ret); /* * return our result */ return ret;}/* * inode2z - convert a stat.st_ino into a ZVALUE * * given: * inode file size * * returns: * file size as a ZVALUE *//*ARGSUSED*/static ZVALUEinode2z(ino_t inode){ ZVALUE ret; /* ZVALUE file size to return */ /* * store off_t in a ZVALUE as a positive value */ ret.len = INODE_BITS/BASEB; ret.v = alloc(ret.len); zclearval(ret); SWAP_HALF_IN_INODE(ret.v, &inode); ret.sign = 0; ztrim(&ret); /* * return our result */ return ret;}/* * get_open_siz - get a an open file size * * given: * fp open file stream * res where to place the file size (ZVALUE) * * returns: * 0 res points to the file size * -1 error */intget_open_siz(FILE *fp, ZVALUE *res){ struct stat buf; /* file status */ /* * get the file size */ if (fstat(fileno(fp), &buf) < 0) { /* stat error */ return -1; } /* * update file size and return success */ *res = off_t2z(buf.st_size); return 0;}/* * getsize - get the current size of the file * * given: * id file id of the file * res pointer to result * * returns: * 0 able to get file size * EOF system error * other nonzero file not open or other problem */intgetsize(FILEID id, ZVALUE *res){ FILEIO *fiop; /* file structure */ FILE *fp; /* * convert id to stream */ fiop = findid(id, -1); if (fiop == NULL) { /* file not open */ return 1; } fp = fiop->fp; if (fp == NULL) { return 2; } /* * return result */ return get_open_siz(fp, res);}/* * getdevice - get the device of the file * * given: * id file id of the file * dev pointer to the result * * returns: * 0 able to get device * -1 unable to get device */intget_device(FILEID id, ZVALUE *dev){ FILEIO *fiop; /* file structure */ /* * convert id to stream */ fiop = findid(id, -1); if (fiop == NULL) { /* file not open */ return -1; } /* * return result */ *dev = dev2z(fiop->dev); return 0;}/* * getinode - get the inode of the file * * given: * id file id of the file * inode pointer to the result * * returns: * 0 able to get inode * -1 unable to get inode */intget_inode(FILEID id, ZVALUE *inode){ FILEIO *fiop; /* file structure */ /* * convert id to stream */ fiop = findid(id, -1); if (fiop == NULL) { /* file not open */ return -1; } /* * return result */ *inode = inode2z(fiop->inode); return 0;}static off_tfilesize(FILEIO *fiop){ struct stat sbuf; /* return length */ if (fstat(fileno(fiop->fp), &sbuf) < 0) { math_error("bad fstat"); /*NOTREACHED*/ } return sbuf.st_size;}ZVALUEzfilesize(FILEID id){ FILEIO *fiop; off_t len; /* file length */ ZVALUE ret; /* file size as a ZVALUE return value */ /* file FILEIO */ fiop = findid(id, -1); if (fiop == NULL) { /* return neg value for non-file error */ itoz(-1, &ret); return ret; } /* get length */ len = filesize(fiop); ret = off_t2z(len); return ret;}voidshowfiles(void){ BOOL listed[MAXFILES]; FILEIO *fiop; FILE *fp; struct stat sbuf; ino_t inodes[MAXFILES]; off_t sizes[MAXFILES]; int i, j; for (i = 0; i < idnum; i++) { listed[i] = FALSE; fiop = &files[ioindex[i]]; fp = fiop->fp; if (fstat(fileno(fp), &sbuf) < 0) { printf("Bad fstat for file %d\n", (int) fiop->id); sizes[i] = -1; } else { inodes[i] = sbuf.st_ino; sizes[i] = sbuf.st_size; } } for (i = 0; i < idnum; i++) { if (listed[i]) continue; fiop = &files[ioindex[i]]; printf("\t"); printid(fiop->id, PRINT_UNAMBIG); if (sizes[i] == -1) { math_chr('\n'); continue; } printf(" size = %lld\n", (long long int)sizes[i]); for (j = i + 1; j < idnum; j++) { if (listed[j] || sizes[j] == -1) continue; if (inodes[j] == inodes[i]) { listed[j] = TRUE; fiop = &files[ioindex[j]]; printf("\t = "); printid(fiop->id, PRINT_UNAMBIG); printf("\n"); } } } printf("\tNumber open = %d\n", idnum); printf("\tLastid = %d\n", (int) lastid);}/* * getscanfield - scan a field separated by some characters * * given: * fp FILEID to scan * skip * width max field width * scannum Number of characters in scanset * scanptr string of characters considered separators * strptr pointer to where the new field pointer may be found */static voidgetscanfield(FILE *fp, BOOL skip, unsigned int width, int scannum, char *scanptr, char **strptr){ char *str; /* current string */ unsigned long len; /* current length of string */ unsigned long totlen; /* total length of string */ char buf[READSIZE]; /* temporary buffer */ int c; char *b; BOOL comp; /* Use complement of scanset */ unsigned int chnum; totlen = 0; str = NULL; comp = (scannum < 0); if (comp) scannum = -scannum; chnum = 0; for (;;) { len = 0; b = buf; for(;;) { c = fgetc(fp); if (c == EOF || c == '\0') break; chnum++; if(scannum && ((memchr(scanptr,c,scannum)==NULL) ^ comp)) break; if (!skip) { *b++ = c; len++; if (len >= READSIZE) break; } if (chnum == width) break; } if (!skip) { if (totlen) str = (char *) realloc(str, totlen + len + 1); else str = (char *) malloc(len + 1); if (str == NULL) { math_error("Out of memory for scanning"); /*NOTREACHED*/ } if (len) memcpy(&str[totlen], buf, len); totlen += len; } if (len < READSIZE) break; } if (!(width && chnum == width) && c != '\0') ungetc(c, fp); if (!skip) { str[totlen] = '\0'; *strptr = str; }}/* * getscanwhite - scan a field separated by whitespace * * given: * fp FILEID to scan * skip * width max field width * scannum Number of characters in scanset * strptr pointer to where the new field pointer may be found */static voidgetscanwhite(FILE *fp, BOOL skip, unsigned int width, int scannum, char **strptr){ char *str; /* current string */ unsigned long len; /* current length of string */ unsigned long totlen; /* total length of string */ char buf[READSIZE]; /* temporary buffer */ int c; char *b; BOOL comp; /* Use complement of scanset */ unsigned int chnum; totlen = 0; str = NULL; comp = (scannum < 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -