MAIN() { char buf[1024], *s; Sfio_t* f; f = sfnew(NIL(Sfio_t*),NIL(Void_t*),(size_t)SF_UNBOUND,-1,SF_WRITE|SF_STRING); sfsetbuf(sfstdout,buf,sizeof(buf)); sfsetbuf(sfstderr,buf,sizeof(buf)); sfset(sfstdout,SF_SHARE,0); sfset(sfstderr,SF_SHARE,0); if(!sfpool(sfstdout,f,SF_SHARE) || !sfpool(sfstderr,f,SF_SHARE) ) terror("Pooling\n"); if(sfputr(sfstdout,"01234",-1) != 5) terror("Writing to stderr\n"); if(sfputr(sfstderr,"56789",-1) != 5) terror("Writing to stdout\n"); if(sfputc(f,'\0') < 0) terror("Writing to string stream\n"); sfseek(f,(Sfoff_t)0,0); if(!(s = sfreserve(f,SF_UNBOUND,1)) ) terror("Peeking\n"); sfwrite(f,s,0); if(strcmp(s,"0123456789") != 0) terror("Data is wrong\n"); TSTEXIT(0); }
MAIN() { char *s = "1234567890\n"; Sfoff_t n, i; Sfio_t *f; char buf[1024]; char* addr; if(sfopen(sfstdout,tstfile(0),"w+") != sfstdout) terror("Opening output file\n"); for(i = 0; i < 10000; ++i) if(sfputr(sfstdout,s,-1) < 0) terror("Writing data\n"); if(!(f = sfopen((Sfio_t*)0,tstfile(1),"w"))) terror("Opening output file \n"); sfseek(sfstdout,(Sfoff_t)0,0); if((n = sfmove(sfstdout,f,(Sfoff_t)SF_UNBOUND,'\n')) != i) terror("Move %d lines, Expect %d\n",n,i); sfseek(sfstdout,(Sfoff_t)0,0); sfseek(f,(Sfoff_t)0,0); sfsetbuf(sfstdout,buf,sizeof(buf)); if((n = sfmove(sfstdout,f,(Sfoff_t)SF_UNBOUND,'\n')) != i) terror("Move %d lines, Expect %d\n",n,i); sfopen(sfstdin,tstfile(0),"r"); sfopen(sfstdout,tstfile(1),"w"); sfmove(sfstdin,sfstdout,(Sfoff_t)SF_UNBOUND,-1); if(!sfeof(sfstdin)) terror("Sfstdin is not eof\n"); if(sferror(sfstdin)) terror("Sfstdin is in error\n"); if(sferror(sfstdout)) terror("Sfstdout is in error\n"); sfseek(sfstdin,(Sfoff_t)0,0); sfseek(sfstdout,(Sfoff_t)0,0); sfsetbuf(sfstdin,buf,sizeof(buf)); addr = (char*)sbrk(0); sfmove(sfstdin,sfstdout,(Sfoff_t)((unsigned long)(~0L)>>1),-1); if((ssize_t)((char*)sbrk(0)-addr) > 256*1024) terror("Too much space allocated in sfmove\n"); if(!sfeof(sfstdin)) terror("Sfstdin is not eof2\n"); if(sferror(sfstdin)) terror("Sfstdin is in error2\n"); if(sferror(sfstdout)) terror("Sfstdout is in error2\n"); TSTEXIT(0); }
static int savenpacoords (char *dir) { Sfio_t *fp; loc_t *locp; int loci; int npanxxi; npa_t *npap; int npai, npa; SUmessage (1, "savenpacoords", "saving file %s/npa.coords", dir); if (!(fp = sfopen (NULL, sfprints ("%s/npa.coords", dir), "w"))) { SUwarning (1, "savenpacoords", "open failed for %s/npa.coords", dir); return -1; } sfsetbuf (fp, NULL, 1048576); for (loci = 0; loci < locn; loci++) { locp = locs[loci]; for (npanxxi = 0; npanxxi < locp->npanxxn; npanxxi++) { npa = locp->npanxxs[npanxxi]->npanxx / 1000; xs[npa] += locp->x, ys[npa] += locp->y, ns[npa]++; } } for (npai = 0; npai < npan; npai++) { npap = npas[npai]; if (ns[npap->npa] > 0) sfprintf ( fp, "%03d %d %d\n", npap->npa, (int) (xs[npap->npa] / (double) ns[npap->npa]), (int) (ys[npap->npa] / (double) ns[npap->npa]) ); } sfclose (fp); return 0; }
tmain() { char buf[100]; Sfio_t *fp; int i; char *s; if(!(fp = sftmp(8))) terror("Can't open temp file"); sfset(fp,SF_LINE,1); for(i = 0; i < 1000; ++i) { sfsprintf(buf,sizeof(buf),"Number: %d",i); if(sfputr(fp,buf,'\n') <= 0) terror("Writing %s",buf); } sfseek(fp,(Sfoff_t)0,0); for(i = 0; i < 1000; ++i) { sfsprintf(buf,sizeof(buf),"Number: %d",i); if(!(s = sfgetr(fp,'\n',1))) terror("Reading %s",buf); if(strcmp(s,buf) != 0) terror("Input=%s, Expect=%s",s,buf); } sfseek(fp,(Sfoff_t)0,0); s = sfgetr(fp,'\0',1); if(s) terror("Expecting a null string"); s = sfgetr(fp,'\0',-1); if(!s) terror("Expecting a non-null string"); if(sfvalue(fp) != sfsize(fp)) terror("Wrong size"); sfclose(fp); if(!(fp = sfnew(0, buf, 12, 1, SF_WRITE)) ) terror("Opening a test stream"); sfsetbuf(fp, buf, 12); sfset(fp, SF_LINE, 0); sfdisc(fp, &Disc); if(sfputr(fp, "0123456789", '\n') != 11) terror("Sfputr failed1"); if(sfputr(fp, "0", -1) != 1) terror("Sfputr failed2"); if(sfputr(fp, "1", -1) != 1) terror("Sfputr failed3"); texit(0); }
tmain() { UNUSED(argc); UNUSED(argv); char buf[1024]; sfsetbuf(sfstdout, buf, sizeof(buf)); sfset(sfstdout, SF_LINE, 0); if (sfdisc(sfstdout, &seekable) != &seekable) terror("Can't set discipline"); if (sfseek(sfstdout, (Sfoff_t)0, 0) < 0) terror("Sfstdout should be seekable"); if (sfwrite(sfstdout, "123\n", 4) != 4) terror("Can't write"); if (sfwrite(sfstdout, "123\n", 4) != 4) terror("Can't write"); if (sfdisc(sfstdout, NULL) != &seekable) terror("Can't pop discipline"); if (buffer != buf || size != 8 || count != 1) terror("Wrong calls to write"); texit(0); }
static int savelocstates (char *dir) { Sfio_t *fp; loc_t *locp; int loci; SUmessage (1, "savelocstates", "saving file %s/npanxxloc.states", dir); if (!(fp = sfopen (NULL, sfprints ("%s/npanxxloc.states", dir), "w"))) { SUwarning ( 1, "savelocstates", "open failed for %s/npanxxloc.states", dir ); return -1; } sfsetbuf (fp, NULL, 1048576); for (loci = 0; loci < locn; loci++) { locp = locs[loci]; sfprintf (fp, "%d %s\n", loci, locp->npanxxs[0]->state); } sfclose (fp); return 0; }
static int savelocmap (char *dir) { Sfio_t *fp; loc_t *locp; int loci; int npanxxi; SUmessage (1, "savelocmap", "saving file %s/npanxxloc.map", dir); if (!(fp = sfopen (NULL, sfprints ("%s/npanxx2loc.map", dir), "w"))) { SUwarning ( 1, "savelocmap", "open failed for %s/npanxxloc.map", dir ); return -1; } sfsetbuf (fp, NULL, 1048576); for (loci = 0; loci < locn; loci++) { locp = locs[loci]; for (npanxxi = 0; npanxxi < locp->npanxxn; npanxxi++) sfprintf (fp, "%06d %d\n", locp->npanxxs[npanxxi]->npanxx, loci); } sfclose (fp); return 0; }
int main (int argc, char **argv) { int norun; char *mapnamep, mapmode, *onamep, *classp; int keytype, keylen, valtype, vallen, dictincr, itemincr; AGGRfile_t *iafp, *oafp; char file[PATH_MAX]; Sfio_t *fp; AGGRreaggr_t *reaggrs; int reaggrn, reaggrl; int count, rejcount; char *line, *s; unsigned char *ikeyp, *okeyp; char *avs[10]; int avn; int ret; if (AGGRinit () == -1) SUerror ("aggrreaggr", "init failed"); mapnamep = NULL, mapmode = 0; onamep = "reaggr.aggr"; classp = "aggrreaggr"; keytype = AGGR_TYPE_STRING; keylen = -1; valtype = -1, vallen = -1; dictincr = 1, itemincr = 1; norun = 0; for (;;) { switch (optget (argv, usage)) { case -100: onamep = opt_info.arg; continue; case -101: classp = opt_info.arg; continue; case -102: if (AGGRparsetype (opt_info.arg, &keytype, &keylen) == -1) SUerror ("aggrreaggr", "bad argument for -kt option"); continue; case -103: if (AGGRparsetype (opt_info.arg, &valtype, &vallen) == -1) SUerror ("aggrreaggr", "bad argument for -vt option"); continue; case -104: dictincr = opt_info.num; continue; case -105: itemincr = opt_info.num; continue; case -114: mapnamep = opt_info.arg; mapmode = 'a'; continue; case -115: mapnamep = opt_info.arg; mapmode = 'b'; continue; case -999: SUwarnlevel++; continue; case '?': SUusage (0, "aggrreaggr", opt_info.arg); norun = 1; continue; case ':': SUusage (1, "aggrreaggr", opt_info.arg); norun = 2; continue; } break; } if (norun) return norun - 1; argc -= opt_info.index, argv += opt_info.index; if (argc != 1) SUerror ("aggrreaggr", "no input file name specified"); if (!mapnamep) SUerror ("aggrreaggr", "no map file name specified"); if (!(iafp = AGGRopen (argv[0], AGGR_RWMODE_RD, 1, TRUE))) SUerror ("aggrreaggr", "open failed"); if (valtype == -1) { valtype = AGGR_TYPE_FLOAT; vallen = ( iafp->hdr.vallen / AGGRtypelens[iafp->hdr.valtype] ) * AGGRtypelens[valtype]; } if (!(oafp = AGGRcreate ( onamep, 1, 1, keytype, valtype, classp, keylen, vallen, dictincr, itemincr, 1, TRUE ))) SUerror ("aggrreaggr", "create failed"); if (strcmp (mapnamep, "-") == 0) fp = sfstdin; else { if (access (mapnamep, R_OK) == 0) strcpy (file, mapnamep); else if (!pathaccess ( getenv ("PATH"), "../lib/aggr", mapnamep, R_OK, file, PATH_MAX )) SUerror ("aggrreaggr", "cannot find map file"); if (!(fp = sfopen (NULL, file, "r"))) SUerror ("aggrreaggr", "sfopen failed"); } sfsetbuf (fp, NULL, 1048576); if (iafp->ad.keylen != -1) if (!(ikeyp = vmalloc (Vmheap, iafp->ad.keylen))) SUerror ("aggrreaggr", "vmalloc failed"); if (oafp->ad.keylen != -1) if (!(okeyp = vmalloc (Vmheap, oafp->ad.keylen))) SUerror ("aggrreaggr", "vmalloc failed"); if (!(reaggrs = vmalloc (Vmheap, 100 * sizeof (AGGRreaggr_t)))) SUerror ("aggrreaggr", "vmalloc failed"); reaggrn = 100, reaggrl = 0; count = 0, rejcount = 0; switch (mapmode) { case 'a': while ((line = sfgetr (fp, '\n', 1))) { count++; if ((avn = tokscan (line, &s, " %v ", avs, 10)) < 1 || avn > 2) { SUwarning (1, "aggrreaggr", "bad line %d", count); rejcount++; continue; } if (reaggrl >= reaggrn) { if (!(reaggrs = vmresize ( Vmheap, reaggrs, reaggrn * 2 * sizeof (AGGRreaggr_t), VM_RSCOPY ))) SUerror ("aggrreaggr", "vmresize failed"); reaggrn *= 2; } if (_aggrdictscankey (iafp, avs[0], &ikeyp) == -1) { SUwarning (1, "aggrreaggr", "bad key at line %d", count); rejcount++; continue; } reaggrs[reaggrl].okeyp = copy (iafp, ikeyp); if (_aggrdictscankey (oafp, avs[1], &okeyp) == -1) { SUwarning (1, "aggrreaggr", "bad key at line %d", count); rejcount++; continue; } reaggrs[reaggrl].nkeyp = copy (oafp, okeyp); if (avn == 3) reaggrs[reaggrl].nitemi = atoi (avs[2]); else reaggrs[reaggrl].nitemi = -1; reaggrl++; if (count % 10000 == 0) SUmessage ( 1, "aggrreaggr", "processed %d lines, dropped %d", count, rejcount ); } break; case 'b': while (1) { if (reaggrl >= reaggrn) { if (!(reaggrs = vmresize ( Vmheap, reaggrs, reaggrn * 2 * sizeof (AGGRreaggr_t), VM_RSCOPY ))) SUerror ("aggrreaggr", "vmresize failed"); reaggrn *= 2; } if (iafp->ad.keylen == -1) { if (!(ikeyp = (unsigned char *) sfgetr (fp, 0, 1))) { if (sfvalue (fp) != 0) SUerror ("aggrreaggr", "bad entry %d", reaggrl); else break; } } else { if ((ret = sfread (fp, ikeyp, iafp->ad.keylen)) == 0) break; else if (ret != iafp->ad.keylen) SUerror ("aggrreaggr", "bad entry %d", reaggrl); SWAPKEY (ikeyp, iafp->hdr.keytype, iafp->ad.keylen); } reaggrs[reaggrl].okeyp = copy (iafp, ikeyp); if (oafp->ad.keylen == -1) { if (!(okeyp = (unsigned char *) sfgetr (fp, 0, 1))) { if (sfvalue (fp) != 0) SUerror ("aggrreaggr", "bad entry %d", reaggrl); else break; } } else { if ((ret = sfread (fp, okeyp, oafp->ad.keylen)) == 0) break; else if (ret != oafp->ad.keylen) SUerror ("aggrreaggr", "bad entry %d", reaggrl); } reaggrs[reaggrl].nkeyp = copy (oafp, okeyp); count++; reaggrs[reaggrl].nitemi = -1; reaggrl++; if (count % 10000 == 0) SUmessage ( 1, "aggrreaggr", "processed %d lines, dropped %d", count, rejcount ); } break; } SUmessage ( rejcount > 0 ? 0 : 1, "aggrreaggr", "processed %d lines, dropped %d", count, rejcount ); if (AGGRreaggr (iafp, reaggrs, reaggrl, oafp) == -1) SUerror ("aggrreaggr", "reaggr failed"); if (AGGRminmax (oafp, TRUE) == -1) SUerror ("aggrreaggr", "minmax failed"); if (AGGRclose (oafp) == -1) SUerror ("aggrreaggr", "close failed"); if (AGGRterm () == -1) SUerror ("aggrreaggr", "term failed"); return 0; }
tmain() { Sfio_t *f; int n, i; char buf[50], *s, *string = "111\n222\n333"; f = sfopen(NIL(Sfio_t*),string,"s"); if(!(s = sfgetr(f,'\n',SF_STRING|SF_LOCKR)) || strcmp(s,"111") != 0) terror("sfgetr failed1"); if(sfgetr(f,'\n',0) != NIL(char*)) terror("sfgetr should have failed because of locking"); sfread(f,s,1); if(!(s = sfgetr(f,'\n',SF_STRING)) || strcmp(s,"222") != 0) terror("sfgetr failed2"); if((s = sfgetr(f,'\n',0)) != NIL(char*)) terror("sfgetr should have failed because of partial record"); if(!(s = sfgetr(f,0,SF_LASTR)) ) terror("sfgetr should have succeeded getting partial record"); /* test type == -1 and type == 1 modes */ sfseek(f,(Sfoff_t)0,0); if(!(s = sfgetr(f,'\n',1)) || strcmp(s,"111") != 0) terror("sfgetr failed in compatible mode"); if(!(s = sfgetr(f,'\n',SF_STRING|SF_LOCKR)) || strcmp(s,"222") != 0) terror("sfgetr failed3"); if(sfgetr(f,'\n',1) ) terror("sfgetr should have failed due to locking"); sfread(f,s,0); if(sfgetr(f,'\n',1) ) terror("sfgetr should have failed because record is incomplete"); if(!(s = sfgetr(f,0,-1)) || strcmp(s,"333") != 0) terror("sfgetr failed in getting last partial record"); if(!(f = sftmp(0)) ) terror("Can't open temporary stream"); for(n = 0; n < 10; ++n) /* each record is 100 bytes */ { for(i = 0; i < 100; ++i) sfputc(f, 'a'); sfputc(f,'\n'); } sfseek(f,(Sfoff_t)0,0); sfsetbuf(f, buf, 50); if(!(s = sfgetr(f, '\n', 1))) terror("Can't get a record"); n = 80; sfmaxr(n, 1); /* set maximum record size */ if((i = sfmaxr(0, 0)) != n) terror("maxr is %d, expected %d", i, n); if((s = sfgetr(f, '\n', 1)) != 0) terror("Shouldn't have gotten a record"); n = 0; sfmaxr(n, 1); /* no record size limit */ if((i = sfmaxr(0, 0)) != n) terror("maxr is %d, expected %d", i, n); if(!(s = sfgetr(f, '\n', 1))) terror("Can't get a record"); if(!(s = sfgetr(f, '\n', 1))) terror("Can't get a record"); texit(0); }
tmain() { UNUSED(argc); UNUSED(argv); Sfio_t *f, *f2; char buf[1024]; char rbuf[4 * 1024]; off_t o; int i; if (!(f = sfopen(NULL, tstfile("sf", 0), "w"))) terror("Can't open file"); sfset(f, SF_IOCHECK, 1); Disc.exceptf = except; if (!sfdisc(f, &Disc)) terror("Pushing discipline failed"); sfdisc(f, &Disc); if (Type != SF_DPUSH) terror("Did not get push event"); /* this is to test sfraise(NULL,...) */ if (!(f2 = sfopen(NULL, tstfile("sf", 0), "w"))) terror("Can't open file"); sfdisc(f2, &Disc); Sfn = 0; if (sfraise(0, SF_WRITE, 0) < 0) terror("sfraise failed"); if (Sfn != 2) terror("Didn't get right event count"); sfdisc(f, NULL); if (Type != SF_DPOP) terror("Did not get pop event"); sfwrite(f, "123", 3); sfsync(f); if (Type != SF_SYNC) terror("Did not get sync event"); sfwrite(f, "123", 3); sfpurge(f); if (Type != SF_PURGE) terror("Did not get purge event"); sfclose(f); if (Type != SF_CLOSING) terror("Did not get close event"); sfclose(f); if (Type != SF_FINAL) terror("Did not get final event"); if (!(f = sfopen(NULL, tstfile("sf", 0), "r"))) terror("Can't open file"); Disc2.readf = readfunc; Disc2.exceptf = except3; sfdisc(f, &Disc2); if (sfgetc(f) >= 0) terror("There should be no data here"); if (Type != SF_LOCKED) terror("Did not get lock event"); /* test to see if sfclose() preserves seek location */ if (!(f = sftmp(0))) terror("Can't create temp file"); sfsetbuf(f, buf, sizeof(buf)); for (i = 0; i < sizeof(rbuf); ++i) rbuf[i] = i; sfwrite(f, rbuf, sizeof(rbuf)); sfset(f, SF_WRITE, 0); Disc.exceptf = except2; sfdisc(f, &Disc); sfseek(f, (Sfoff_t)0, 0); if (sfread(f, rbuf, 4) != 4) terror("reading 4 bytes"); for (i = 0; i < 4; ++i) { if (rbuf[i] != i) terror("wrong 4 bytes"); } sfsync(f); if ((o = lseek(sffileno(f), (off_t)0, SEEK_CUR)) != 4) { terror("Wrong seek location %lld", (Sfoff_t)o); } if ((i = dup(sffileno(f))) < 0) terror("Can't dup file descriptor"); if ((o = lseek(i, (off_t)0, SEEK_CUR)) != 4) terror("Wrong seek location %lld", (Sfoff_t)o); sfclose(f); if ((o = lseek(i, (off_t)0, SEEK_CUR)) != 4) terror("Wrong seek location %lld", (Sfoff_t)o); texit(0); }
/* * This routine will turn the sftmp() file into a real /tmp file or pipe */ void sh_subtmpfile(int pflag) { Shell_t *shp = &sh; int fds[2]; Sfoff_t off; register struct checkpt *pp = (struct checkpt*)shp->jmplist; register struct subshell *sp = subshell_data->pipe; if(sfset(sfstdout,0,0)&SF_STRING) { register int fd; /* save file descriptor 1 if open */ if((sp->tmpfd = fd = fcntl(1,F_DUPFD,10)) >= 0) { fcntl(fd,F_SETFD,FD_CLOEXEC); shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX; close(1); shp->fdstatus[1] = IOCLOSE; } else if(errno!=EBADF) { ((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT; shp->toomany = 1; errormsg(SH_DICT,ERROR_system(1),e_toomany); } if(shp->subshare || !pflag) { sfdisc(sfstdout,SF_POPDISC); if((fd=sffileno(sfstdout))>=0) { shp->fdstatus[fd] = IOREAD|IOWRITE; sfsync(sfstdout); if(fd==1) fcntl(1,F_SETFD,0); else { sfsetfd(sfstdout,1); shp->fdstatus[1] = shp->fdstatus[fd]; shp->fdstatus[fd] = IOCLOSE; } goto skip; } } } if(sp && (shp->fdstatus[1]==IOCLOSE || (!shp->subshare && !(shp->fdstatus[1]&IONOSEEK)))) { struct stat statb,statx; int fd; sh_pipe(fds); sp->pipefd = fds[0]; sh_fcntl(sp->pipefd,F_SETFD,FD_CLOEXEC); /* write the data to the pipe */ if(off = sftell(sfstdout)) { write(fds[1],sfsetbuf(sfstdout,(Void_t*)sfstdout,0),(size_t)off); sfpurge(sfstdout); } if((sfset(sfstdout,0,0)&SF_STRING) || fstat(1,&statb)<0) statb.st_ino = 0; sfclose(sfstdout); if((sh_fcntl(fds[1],F_DUPFD, 1)) != 1) errormsg(SH_DICT,ERROR_system(1),e_redirect); sh_close(fds[1]); if(statb.st_ino) for(fd=0; fd < 10; fd++) { if(fd==1 || ((shp->fdstatus[fd]&(IONOSEEK|IOSEEK|IOWRITE))!=(IOSEEK|IOWRITE)) || fstat(fd,&statx)<0) continue; if(statb.st_ino==statx.st_ino && statb.st_dev==statx.st_dev) { sh_close(fd); fcntl(1,F_DUPFD, fd); } } skip: sh_iostream(shp,1); sfset(sfstdout,SF_SHARE|SF_PUBLIC,1); sfpool(sfstdout,shp->outpool,SF_WRITE); if(pp && pp->olist && pp->olist->strm == sfstdout) pp->olist->strm = 0; } }
FILE* fileopen(char* file, char* mode) { FILE* fp; int n; int ignore = 0; int mask = 0; int regular = 0; int verbose = 0; for (;; mode++) { switch (*mode) { case 'E': verbose = 1; continue; case 'I': ignore = 1; continue; case 'M': mask = 1; continue; case 'R': regular = 1; continue; case 'X': if (!(file = expand(file, 1))) return 0; continue; } break; } if (fp = filestd(file, mode)) return fp; if (mask) n = umask(~MAILMODE); fp = fopen(file, mode); if (mask) { umask(n); if (state.readonly && streq(mode, "w")) chmod(file, S_IRUSR); } if (fp) { if (fstat(fileno(fp), &state.openstat)) { fclose(fp); if (verbose) note(SYSTEM, "%s", file); return 0; } if (S_ISDIR(state.openstat.st_mode)) { fclose(fp); errno = EISDIR; if (verbose) note(SYSTEM, "%s", file); return 0; } if (regular && !S_ISREG(state.openstat.st_mode)) { fclose(fp); errno = EFTYPE; if (verbose) note(SYSTEM, "%s", file); return 0; } if (!ignore) register_file(fp, 0); fcntl(fileno(fp), F_SETFD, 1); #if 0 && MORE_DISCIPLINE sfsetbuf(fp, (void*)fp, SF_UNBOUND); #endif } else if (verbose) note(SYSTEM, "%s", file); return fp; }
main() { int n, fd; Sfio_t *f; char *s, buf[1024]; int fdv[100]; buf[0] = 0; sfsetbuf(sfstdout,buf,sizeof(buf)); if(!sfstdout->pool) terror("No pool\n"); sfdisc(sfstdout,&Disc); sfset(sfstdout,SF_SHARE,0); sfputr(sfstdout,"123456789",0); if(strcmp(buf,"123456789") != 0) terror("Setting own buffer for stdout\n"); if(sfpurge(sfstdout) < 0) terror("Purging sfstdout\n"); if((fd = creat("xxx",0666)) < 0) terror("Creating xxx\n"); if(write(fd,buf,sizeof(buf)) != sizeof(buf)) terror("Writing to xxx\n"); if(lseek(fd,0L,0) < 0) terror("Seeking back to origin\n"); if(!(f = sfnew((Sfio_t*)0,buf,sizeof(buf),fd,SF_WRITE))) terror("Making stream\n"); if(!(s = sfreserve(f,SF_UNBOUND,1)) || s != buf) terror("sfreserve1 returns the wrong pointer\n"); sfwrite(f,s,0); #define NEXTFD 12 if((fd+NEXTFD) < (sizeof(fdv)/sizeof(fdv[0])) ) { struct stat st; int i; for(i = 0; i < fd+NEXTFD; ++i) fdv[i] = fstat(i,&st); } if((n = sfsetfd(f,fd+NEXTFD)) != fd+NEXTFD) terror("Try to set file descriptor to %d but get %d\n",fd+NEXTFD,n); if((fd+NEXTFD) < (sizeof(fdv)/sizeof(fdv[0])) ) { struct stat st; int i; for(i = 0; i < fd+NEXTFD; ++i) if(i != fd && fdv[i] != fstat(i,&st)) terror("Fd %d changes status after sfsetfd %d->%d\n", i, fd, fd+NEXTFD); } if(!(s = sfreserve(f,SF_UNBOUND,1)) || s != buf) terror("sfreserve2 returns the wrong pointer\n"); sfwrite(f,s,0); if(sfsetbuf(f,NIL(Void_t*),(size_t)SF_UNBOUND) != buf) terror("sfsetbuf didnot returns last buffer\n"); sfsetbuf(f,buf,sizeof(buf)); if(sfreserve(f,SF_UNBOUND,1) != buf || sfvalue(f) != sizeof(buf) ) terror("sfreserve3 returns the wrong value\n"); sfwrite(f,s,0); system("rm xxx >/dev/null 2>&1"); return 0; }
int hist_expand(const char *ln, char **xp) { int off, /* stack offset */ q, /* quotation flags */ p, /* flag */ c, /* current char */ flag=0; /* HIST_* flags */ Sfoff_t n, /* history line number, counter, etc. */ i, /* counter */ w[2]; /* word range */ char *sp, /* stack pointer */ *cp, /* current char in ln */ *str, /* search string */ *evp, /* event/word designator string, for error msgs */ *cc=0, /* copy of current line up to cp; temp ptr */ hc[3], /* default histchars */ *qc="\'\"`"; /* quote characters */ Sfio_t *ref=0, /* line referenced by event designator */ *tmp=0, /* temporary line buffer */ *tmp2=0;/* temporary line buffer */ Histloc_t hl; /* history location */ static Namval_t *np = 0; /* histchars variable */ static struct subst sb = {0,0}; /* substition strings */ static Sfio_t *wm=0; /* word match from !?string? event designator */ if(!wm) wm = sfopen(NULL, NULL, "swr"); hc[0] = '!'; hc[1] = '^'; hc[2] = 0; if((np = nv_open("histchars",sh.var_tree,0)) && (cp = nv_getval(np))) { if(cp[0]) { hc[0] = cp[0]; if(cp[1]) { hc[1] = cp[1]; if(cp[2]) hc[2] = cp[2]; } } } /* save shell stack */ if(off = staktell()) sp = stakfreeze(0); cp = (char*)ln; while(cp && *cp) { /* read until event/quick substitution/comment designator */ if((*cp != hc[0] && *cp != hc[1] && *cp != hc[2]) || (*cp == hc[1] && cp != ln)) { if(*cp == '\\') /* skip escaped designators */ stakputc(*cp++); else if(*cp == '\'') /* skip quoted designators */ { do stakputc(*cp); while(*++cp && *cp != '\''); } stakputc(*cp++); continue; } if(hc[2] && *cp == hc[2]) /* history comment designator, skip rest of line */ { stakputc(*cp++); stakputs(cp); DONE(); } n = -1; str = 0; flag &= HIST_EVENT; /* save event flag for returning later */ evp = cp; ref = 0; if(*cp == hc[1]) /* shortcut substitution */ { flag |= HIST_QUICKSUBST; goto getline; } if(*cp == hc[0] && *(cp+1) == hc[0]) /* refer to line -1 */ { cp += 2; goto getline; } switch(c = *++cp) { case ' ': case '\t': case '\n': case '\0': case '=': case '(': stakputc(hc[0]); continue; case '#': /* the line up to current position */ flag |= HIST_HASH; cp++; n = staktell(); /* terminate string and dup */ stakputc('\0'); cc = strdup(stakptr(0)); stakseek(n); /* remove null byte again */ ref = sfopen(ref, cc, "s"); /* open as file */ n = 0; /* skip history file referencing */ break; case '-': /* back reference by number */ if(!isdigit(*(cp+1))) goto string_event; cp++; case '0': /* reference by number */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; while(isdigit(*cp)) n = n * 10 + (*cp++) - '0'; if(c == '-') n = -n; break; case '$': n = -1; case ':': break; case '?': cp++; flag |= HIST_QUESTION; string_event: default: /* read until end of string or word designator/modifier */ str = cp; while(*cp) { cp++; if((!(flag&HIST_QUESTION) && (*cp == ':' || isspace(*cp) || *cp == '^' || *cp == '$' || *cp == '*' || *cp == '-' || *cp == '%') ) || ((flag&HIST_QUESTION) && (*cp == '?' || *cp == '\n'))) { c = *cp; *cp = '\0'; } } break; } getline: flag |= HIST_EVENT; if(str) /* !string or !?string? event designator */ { /* search history for string */ hl = hist_find(shgd->hist_ptr, str, shgd->hist_ptr->histind, flag&HIST_QUESTION, -1); if((n = hl.hist_command) == -1) n = 0; /* not found */ } if(n) { if(n < 0) /* determine index for backref */ n = shgd->hist_ptr->histind + n; /* search and use history file if found */ if(n > 0 && hist_seek(shgd->hist_ptr, n) != -1) ref = shgd->hist_ptr->histfp; } if(!ref) { /* string not found or command # out of range */ c = *cp; *cp = '\0'; errormsg(SH_DICT, ERROR_ERROR, "%s: event not found", evp); *cp = c; DONE(); } if(str) /* string search: restore orig. line */ { if(flag&HIST_QUESTION) *cp++ = c; /* skip second question mark */ else *cp = c; } /* colon introduces either word designators or modifiers */ if(*(evp = cp) == ':') cp++; w[0] = 0; /* -1 means last word, -2 means match from !?string? */ w[1] = -1; /* -1 means last word, -2 means suppress last word */ if(flag & HIST_QUICKSUBST) /* shortcut substitution */ goto getsel; n = 0; while(n < 2) { switch(c = *cp++) { case '^': /* first word */ if(n == 0) { w[0] = w[1] = 1; goto skip; } else goto skip2; case '$': /* last word */ w[n] = -1; goto skip; case '%': /* match from !?string? event designator */ if(n == 0) { if(!str) { w[0] = 0; w[1] = -1; ref = wm; } else { w[0] = -2; w[1] = sftell(ref) + hl.hist_char; } sfseek(wm, 0, SEEK_SET); goto skip; } default: skip2: cp--; n = 2; break; case '*': /* until last word */ if(n == 0) w[0] = 1; w[1] = -1; skip: flag |= HIST_WORDDSGN; n = 2; break; case '-': /* until last word or specified index */ w[1] = -2; flag |= HIST_WORDDSGN; n = 1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* specify index */ if((*evp == ':') || w[1] == -2) { w[n] = c - '0'; while(isdigit(c=*cp++)) w[n] = w[n] * 10 + c - '0'; flag |= HIST_WORDDSGN; if(n == 0) w[1] = w[0]; n++; } else n = 2; cp--; break; } } if(w[0] != -2 && w[1] > 0 && w[0] > w[1]) { c = *cp; *cp = '\0'; errormsg(SH_DICT, ERROR_ERROR, "%s: bad word specifier", evp); *cp = c; DONE(); } /* no valid word designator after colon, rewind */ if(!(flag & HIST_WORDDSGN) && (*evp == ':')) cp = evp; getsel: /* open temp buffer, let sfio do the (re)allocation */ tmp = sfopen(NULL, NULL, "swr"); /* push selected words into buffer, squash whitespace into single blank or a newline */ n = i = q = 0; while((c = sfgetc(ref)) > 0) { if(isspace(c)) { flag |= (c == '\n' ? HIST_NEWLINE : 0); continue; } if(n >= w[0] && ((w[0] != -2) ? (w[1] < 0 || n <= w[1]) : 1)) { if(w[0] < 0) sfseek(tmp, 0, SEEK_SET); else i = sftell(tmp); if(i > 0) sfputc(tmp, flag & HIST_NEWLINE ? '\n' : ' '); flag &= ~HIST_NEWLINE; p = 1; } else p = 0; do { cc = strchr(qc, c); q ^= cc ? 1<<(int)(cc - qc) : 0; if(p) sfputc(tmp, c); } while((c = sfgetc(ref)) > 0 && (!isspace(c) || q)); if(w[0] == -2 && sftell(ref) > w[1]) break; flag |= (c == '\n' ? HIST_NEWLINE : 0); n++; } if(w[0] != -2 && w[1] >= 0 && w[1] >= n) { c = *cp; *cp = '\0'; errormsg(SH_DICT, ERROR_ERROR, "%s: bad word specifier", evp); *cp = c; DONE(); } else if(w[1] == -2) /* skip last word */ sfseek(tmp, i, SEEK_SET); /* remove trailing newline */ if(sftell(tmp)) { sfseek(tmp, -1, SEEK_CUR); if(sfgetc(tmp) == '\n') sfungetc(tmp, '\n'); } sfputc(tmp, '\0'); if(str) { if(wm) sfclose(wm); wm = tmp; } if(cc && (flag&HIST_HASH)) { /* close !# temp file */ sfclose(ref); flag &= ~HIST_HASH; free(cc); cc = 0; } evp = cp; /* selected line/words are now in buffer, now go for the modifiers */ while(*cp == ':' || (flag & HIST_QUICKSUBST)) { if(flag & HIST_QUICKSUBST) { flag &= ~HIST_QUICKSUBST; c = 's'; cp--; } else c = *++cp; sfseek(tmp, 0, SEEK_SET); tmp2 = sfopen(tmp2, NULL, "swr"); if(c == 'g') /* global substitution */ { flag |= HIST_GLOBALSUBST; c = *++cp; } if(cc = strchr(modifiers, c)) flag |= mod_flags[cc - modifiers]; else { errormsg(SH_DICT, ERROR_ERROR, "%c: unrecognized history modifier", c); DONE(); } if(c == 'h' || c == 'r') /* head or base */ { n = -1; while((c = sfgetc(tmp)) > 0) { /* remember position of / or . */ if((c == '/' && *cp == 'h') || (c == '.' && *cp == 'r')) n = sftell(tmp2); sfputc(tmp2, c); } if(n > 0) { /* rewind to last / or . */ sfseek(tmp2, n, SEEK_SET); /* end string there */ sfputc(tmp2, '\0'); } } else if(c == 't' || c == 'e') /* tail or suffix */ { n = 0; while((c = sfgetc(tmp)) > 0) { /* remember position of / or . */ if((c == '/' && *cp == 't') || (c == '.' && *cp == 'e')) n = sftell(tmp); } /* rewind to last / or . */ sfseek(tmp, n, SEEK_SET); /* copy from there on */ while((c = sfgetc(tmp)) > 0) sfputc(tmp2, c); } else if(c == 's' || c == '&') { cp++; if(c == 's') { /* preset old with match from !?string? */ if(!sb.str[0] && wm) sb.str[0] = strdup(sfsetbuf(wm, (Void_t*)1, 0)); cp = parse_subst(cp, &sb); } if(!sb.str[0] || !sb.str[1]) { c = *cp; *cp = '\0'; errormsg(SH_DICT, ERROR_ERROR, "%s%s: no previous substitution", (flag & HIST_QUICKSUBST) ? ":s" : "", evp); *cp = c; DONE(); } /* need pointer for strstr() */ str = sfsetbuf(tmp, (Void_t*)1, 0); flag |= HIST_SUBSTITUTE; while(flag & HIST_SUBSTITUTE) { /* find string */ if(cc = strstr(str, sb.str[0])) { /* replace it */ c = *cc; *cc = '\0'; sfputr(tmp2, str, -1); sfputr(tmp2, sb.str[1], -1); *cc = c; str = cc + strlen(sb.str[0]); } else if(!sftell(tmp2)) { /* not successfull */ c = *cp; *cp = '\0'; errormsg(SH_DICT, ERROR_ERROR, "%s%s: substitution failed", (flag & HIST_QUICKSUBST) ? ":s" : "", evp); *cp = c; DONE(); } /* loop if g modifier specified */ if(!cc || !(flag & HIST_GLOBALSUBST)) flag &= ~HIST_SUBSTITUTE; } /* output rest of line */ sfputr(tmp2, str, -1); if(*cp) cp--; } if(sftell(tmp2)) { /* if any substitions done, swap buffers */ if(wm != tmp) sfclose(tmp); tmp = tmp2; tmp2 = 0; } cc = 0; if(*cp) cp++; } /* flush temporary buffer to stack */ if(tmp) { sfseek(tmp, 0, SEEK_SET); if(flag & HIST_QUOTE) stakputc('\''); while((c = sfgetc(tmp)) > 0) { if(isspace(c)) { flag = flag & ~HIST_NEWLINE; /* squash white space to either a blank or a newline */ do flag |= (c == '\n' ? HIST_NEWLINE : 0); while((c = sfgetc(tmp)) > 0 && isspace(c)); sfungetc(tmp, c); c = (flag & HIST_NEWLINE) ? '\n' : ' '; if(flag & HIST_QUOTE_BR) { stakputc('\''); stakputc(c); stakputc('\''); } else stakputc(c); } else if((c == '\'') && (flag & HIST_QUOTE)) { stakputc('\''); stakputc('\\'); stakputc(c); stakputc('\''); } else stakputc(c); } if(flag & HIST_QUOTE) stakputc('\''); } } stakputc('\0'); done: if(cc && (flag&HIST_HASH)) { /* close !# temp file */ sfclose(ref); free(cc); cc = 0; } /* error? */ if(staktell() && !(flag & HIST_ERROR)) *xp = strdup(stakfreeze(1)); /* restore shell stack */ if(off) stakset(sp,off); else stakseek(0); /* drop temporary files */ if(tmp && tmp != wm) sfclose(tmp); if(tmp2) sfclose(tmp2); return (flag & HIST_ERROR ? HIST_ERROR : flag & HIST_FLAG_RETURN_MASK); }
tmain() { UNUSED(argc); UNUSED(argv); Sfio_t *f, *f2; char *s; int i, n; char buf[16 * 1024]; if (!(f = sfopen(NULL, tstfile("sf", 0), "w+"))) terror("Can't open file"); if (sfnputc(f, 'a', 1000) != 1000) terror("Writing"); if (sfseek(f, (Sfoff_t)0, 0) != 0) terror("Seeking"); if ((n = (int)sfsize(f)) != 1000) terror("Wrong size %d", n); if (!(f2 = sfnew(NULL, NULL, (size_t)SF_UNBOUND, sffileno(f), SF_WRITE))) { terror("Can't open stream"); } if (sfseek(f2, (Sfoff_t)1999, 0) != (Sfoff_t)1999) terror("Seeking2"); sfputc(f2, 'b'); sfsync(f2); if ((n = (int)sfsize(f2)) != 2000) terror("Wrong size2 %d", n); if ((n = (int)sfsize(f)) != 1000) terror("Wrong size3 %d", n); sfputc(f, 'a'); sfset(f, SF_SHARE, 1); if ((n = (int)sfsize(f)) != 2000) terror("Wrong size4 %d", n); if (!(f = sfopen(f, NULL, "srw"))) terror("Can't open string stream"); sfwrite(f, "0123456789", 10); if (sfsize(f) != 10) terror("String size is wrong1"); sfseek(f, (Sfoff_t)19, 0); if (sfsize(f) != 10) terror("String size is wrong2"); sfputc(f, 'a'); if (sfsize(f) != 20) terror("String size is wrong3"); sfseek(f, (Sfoff_t)0, 0); if (sfsize(f) != 20) terror("String size is wrong4"); sfseek(f, (Sfoff_t)0, 0); if (!(s = sfreserve(f, SF_UNBOUND, SF_LOCKR)) && sfvalue(f) != 20) { terror("String size is wrong5"); } sfread(f, s, 5); if (sfsize(f) != 20) terror("String size is wrong6"); sfwrite(f, "01234567890123456789", 20); if (sfsize(f) != 25) terror("String size is wrong7"); strcpy(buf, "0123456789"); if (!(f = sfopen(f, buf, "s+"))) terror("Can't open string stream2"); if (sfset(f, 0, 0) & SF_MALLOC) terror("SF_MALLOC should not have been set"); if (sfsize(f) != 10) terror("String size is wrong8"); sfread(f, buf, 5); if ((n = (int)sfwrite(f, "0123456789", 10)) != 5) terror("Write wrong amount %d", n); if (sfsize(f) != 10) terror("String size is wrong9"); if (!(f = sfopen(f, tstfile("sf", 0), "w"))) terror("Reopening file1"); for (i = 0; i < 10000; ++i) { if (sfputc(f, '0' + (i % 10)) != '0' + (i % 10)) terror("sfputc failed"); } if (!(f = sfopen(f, tstfile("sf", 0), "r+"))) terror("Reopening file2"); if (sfsize(f) != 10000) terror("Bad size of file1"); sfsetbuf(f, buf, 1024); for (i = 0; i < 20; ++i) { if (!sfreserve(f, 100, 0)) terror("Reserve failed"); } s = buf + 1024; for (i = 0; i < 20; ++i) s[i] = '0' + i % 10; sfseek(f, (Sfoff_t)(10000 - 10), 0); if (sfwrite(f, s, 20) != 20) terror("Write failed"); if (sfsize(f) != 10010) terror("Bad size of file2"); sfseek(f, (Sfoff_t)0, 0); for (i = 0; i < 10; ++i) { if (!(s = sfreserve(f, 1001, 0))) terror("Reserve failed2"); if (s[0] != '0' + i) terror("Bad data1"); } for (n = 0; n < 1001; ++n) { if (s[n] != ((n + i - 1) % 10 + '0')) terror("Bad data"); } /* test to see if a string stream extends ok during writes */ s = malloc(5); f = sfnew(NULL, (void *)s, 5, -1, SF_STRING | SF_READ | SF_WRITE | SF_MALLOC); if (!f) terror("Can't create string stream"); if (sfwrite(f, "01", 2) != 2) terror("Bad write to string stream"); if (sfwrite(f, "2345678", 7) != 7) terror("Bad write to string stream2"); if (sfputc(f, 0) != 0) terror("sfputc failed"); if (sfseek(f, (Sfoff_t)0, 0) != 0) terror("sfseek failed"); if ((n = (int)sfread(f, buf, 100)) != 10) terror("sfread gets wrong amount of data %d", n); if (strcmp(buf, "012345678") != 0) terror("Get wrong data"); texit(0); }
static int spliceline(Sfio_t* s, int op, void* val, Sfdisc_t* ad) { Splice_t* d = (Splice_t*)ad; register char* b; register int c; register int n; register int q; register int j; register char* e; char* buf; NoP(val); switch (op) { case SF_CLOSING: sfclose(d->sp); return 0; case SF_DPOP: free(d); return 0; case SF_READ: do { if (!(buf = sfgetr(d->sp, '\n', 0)) && !(buf = sfgetr(d->sp, '\n', -1))) return 0; n = sfvalue(d->sp); q = d->quote; j = 0; (*d->line)++; if (n > 1 && buf[n - 2] == '\\') { j = 1; n -= 2; if (q == '#') { n = 0; continue; } } else if (q == '#') { q = 0; n = 0; continue; } if (n > 0) { e = (b = buf) + n; while (b < e) { if ((c = *b++) == '\\') b++; else if (c == q) q = 0; else if (!q) { if (c == '\'' || c == '"') q = c; else if (c == '#' && (b == (buf + 1) || (c = *(b - 2)) == ' ' || c == '\t')) { if (buf[n - 1] != '\n') { q = '#'; n = b - buf - 2; } else if (n = b - buf - 1) buf[n - 1] = '\n'; break; } } } if (n > 0) { if (!j && buf[n - 1] != '\n' && (s->_flags & SF_STRING)) buf[n++] = '\n'; if (q && buf[n - 1] == '\n') buf[n - 1] = '\r'; } } } while (n <= 0); sfsetbuf(s, buf, n); d->quote = q; return 1; default: return 0; } }
MAIN() { int i, n, k; Sfoff_t o; char buf[1024], *s; char bigbuf[1024*8]; int fd[2]; Sfio_t* f; if(!(f = sfopen(0, tstfile(0), "w")) ) terror("Opening file to write"); if(sfwrite(f,"0123456789",10) != 10 || sfwrite(f,"abcdefgh",8) != 8) terror("Writing data"); if(!(f = sfopen(f, tstfile(0), "r")) ) terror("Opening file to read"); sfsetbuf(f, buf, sizeof(buf)); if(!(s = (char*)sfreserve(f,10,0)) ) terror("sfreserve failed"); if(strncmp(s,"0123456789",10) != 0) terror("Did not get correct data"); if((s = (char*)sfreserve(f,10,0)) ) terror("sfreserve should not have succeeded"); if(sfvalue(f) != 8) terror("sfreserve should have left the right unread record length"); if(!(s = (char*)sfreserve(f,4,0)) ) terror("sfreserve should return 4 bytes"); if(strncmp(s,"abcd",4) != 0) terror("Got wrong data"); if((s = (char*)sfreserve(f,10,0)) ) terror("sfreserve should not have succeeded2"); if(sfvalue(f) != 4) terror("sfreserve should have left 4 bytes length"); if(!(s = (char*)sfreserve(f,0,SF_LASTR)) ) terror("sfreserve should have returned last unread record"); if(strncmp(s,"efgh",4) != 0) terror("Record has wrong data"); sfclose(f); sfsetbuf(sfstdout,buf,sizeof(buf)); sfset(sfstdout,SF_SHARE|SF_PUBLIC,0); if((s = (char*)sfreserve(sfstdout,0,0)) != buf) terror("Wrong buffer\n"); if((n = sfwrite(sfstdout,"foobar",6)) != 6) terror("Write failed\n"); if((char*)sfreserve(sfstdout,0,0) != s+6) terror("Wrong reserved pointer\n"); sfpurge(sfstdout); if(sfopen(sfstdout, tstfile(0),"w") != sfstdout) terror("Opening file\n"); sfsetbuf(sfstdout,NIL(char*),0); if(!(s = sfreserve(sfstdout,0,1)) ) terror("Could not lock stdout\n"); if(sfputc(sfstdout,'1') >= 0) terror("stdout wasn't locked\n"); if(sfwrite(sfstdout,s,0) != 0) terror("stdout can't be unlocked\n"); sfsetbuf(sfstdout,NIL(char*),sizeof(buf)/2); for(i = 0; i < sizeof(buf); ++i) buf[i] = (i%26) + 'a'; n = 0; for(i = 0; i < 33; ++i) { if(!(s = sfreserve(sfstdout,sizeof(buf),1)) ) terror("Can't reserve write buffer\n"); memcpy(s,buf,sizeof(buf)); if(sfwrite(sfstdout,s,sizeof(buf)) != sizeof(buf) ) terror("Writing to file\n"); else n += sizeof(buf); } sfsync(sfstdout); if(sfopen(sfstdin, tstfile(0),"r") != sfstdin) terror("Opening file2\n"); sfsetbuf(sfstdin,NIL(char*),8*sizeof(buf)); if(sfsize(sfstdin) != n) terror("Wrong size for file\n"); i = 0; for(;;) { if(!(s = sfreserve(sfstdin,16*sizeof(buf),0)) ) break; else i += 16*sizeof(buf); } if(sfvalue(sfstdin) > 0) i += sfvalue(sfstdin); if(i != n) terror("Did not read data\n"); if(sfseek(sfstdin,(Sfoff_t)0,0) != 0) terror("sfseek failed0\n"); sfsetbuf(sfstdin,bigbuf,sizeof(bigbuf)); i = 0; for(;;) { if(!(s = sfreserve(sfstdin,16*sizeof(buf),0)) ) break; else i += 16*sizeof(buf); } if(sfvalue(sfstdin) > 0) i += sfvalue(sfstdin); if(i != n) terror("Did not read data2\n"); sfsetbuf(sfstdin,NIL(Void_t*),(size_t)SF_UNBOUND); if(sfopen(sfstdout, tstfile(0), "w") != sfstdout) terror("Can't open to write\n"); for(i = 0; i < 32; ++i) { for(k = 0; k < sizeof(bigbuf); ++k) bigbuf[k] = '0' + (k+i)%10; if(sfwrite(sfstdout,bigbuf,sizeof(bigbuf)) != sizeof(bigbuf)) terror("Writing to %s\n", tstfile(0)); } sfclose(sfstdout); if(sfopen(sfstdin, tstfile(0), "r") != sfstdin) terror("Opening to read\n"); sfsetbuf(sfstdin,NIL(Void_t*),8*1024); if(!(s = sfreserve(sfstdin,16*sizeof(bigbuf),0)) ) terror("sfreserve failed\n"); for(i = 0; i < 16; ++i) { for(k = 0; k < sizeof(bigbuf); ++k) if(*s++ != ('0' + (k+i)%10)) terror("Wrong data i=%d k=%d\n",i,k); } if((o = sfseek(sfstdin,-15*((Sfoff_t)sizeof(bigbuf)),1)) != sizeof(bigbuf)) terror("sfseek failed o=%lld\n", (Sflong_t)o); if(sfread(sfstdin,bigbuf,sizeof(bigbuf)) != sizeof(bigbuf) ) terror("sfread failed\n"); s = bigbuf; for(i = 1; i < 2; ++i) { for(k = 0; k < sizeof(bigbuf); ++k) if(*s++ != ('0' + (k+i)%10)) terror("Wrong data2 i=%d k=%d\n",i,k); } if(!(s = sfreserve(sfstdin,16*sizeof(bigbuf),1)) ) { sfsetbuf(sfstdin,NIL(Void_t*),16*sizeof(bigbuf)); if(!(s = sfreserve(sfstdin,16*sizeof(bigbuf),1)) ) terror("sfreserve failed2\n"); }