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); }
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"); }
/* * 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; } }
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; }