main() { Sfio_t* null; Sfio_t* f; char buf[256*1024], b[256*1024]; int k, n; if(!(null = sfopen(NIL(Sfio_t*),"/dev/null","w")) ) terror("Opening /dev/null"); sfsetbuf(null,NIL(char*),(size_t)SF_UNBOUND); if(!SFISNULL(null) ) terror("Not /dev/null?"); if(!(f = sfopen(NIL(Sfio_t*), Kpv[0], "w+")) ) terror("Creating %s", Kpv[0]); sfwrite(f,"1234",4); sfseek(f,(Sfoff_t)1,0); sfsync(f); sfsetfd(null,-1); sfsetfd(null,sffileno(f)); sfsync(null); sfseek(f,(Sfoff_t)0,0); if(sfread(f,buf,4) != 4 || strncmp(buf,"1234",4) != 0) terror("Bad data"); for(k = 0; k < sizeof(buf); ++k) buf[k] = 1; for(k = sizeof(buf)/4; k < sizeof(buf)/2; ++k) /* make a big hole */ buf[k] = 0; if(!(f = sfopen(f, Kpv[0], "w+")) ) terror("Creating %s", Kpv[0]); n = sizeof(buf)-127; if(sfwrite(f,buf,n) != n) terror("Writing large buffer"); sfseek(f,(Sfoff_t)0,0); if(sfread(f,b,n) != n) terror("Reading large buffer"); for(k = 0; k < n; ++k) if(b[k] != buf[k]) terror("Bad data"); rmkpv(); return 0; }
MAIN() { Sfio_t *f; int fd; off_t sk; if(!(f = sfopen((Sfio_t*)0,tstfile(0),"w+"))) terror("Opening file\n"); fd = sffileno(f); if(sfsetfd(f,-1) != -1 || sffileno(f) != -1) terror("setfd1\n"); if(sfputc(f,'a') >= 0) terror("sfputc\n"); if(sfsetfd(f,fd) != fd) terror("setfd2\n"); if(sfwrite(f,"123456789\n",10) != 10) terror("sfwrite\n"); sfseek(f,(Sfoff_t)0,0); if(sfgetc(f) != '1') terror("sfgetc1\n"); if(sfsetfd(f,-1) != -1 || sffileno(f) != -1) terror("setfd2\n"); if((sk = lseek(fd, (off_t)0, 1)) != (off_t)1) terror("Bad seek address %lld\n", (Sfoff_t)sk ); if(sfgetc(f) >= 0) terror("sfgetc2\n"); if(sfsetfd(f,fd) != fd) terror("setfd2\n"); if(sfgetc(f) != '2') terror("sfgetc3\n"); TSTEXIT(0); }
tmain() { Sfio_t *f; int fd; off_t sk; if(!(f = sfopen((Sfio_t*)0,tstfile("sf", 0),"w+"))) terror("Opening file"); fd = sffileno(f); if(sfsetfd(f,-1) != -1 || sffileno(f) != -1) terror("setfd1"); if(sfputc(f,'a') >= 0) terror("sfputc"); if(sfsetfd(f,fd) != fd) terror("setfd2"); if(sfwrite(f,"123456789\n",10) != 10) terror("sfwrite"); sfseek(f,(Sfoff_t)0,0); if(sfgetc(f) != '1') terror("sfgetc1"); if(sfsetfd(f,-1) != -1 || sffileno(f) != -1) terror("setfd2"); if((sk = lseek(fd, (off_t)0, 1)) != (off_t)1) terror("Bad seek address %lld", (Sfoff_t)sk ); if(sfgetc(f) >= 0) terror("sfgetc2"); if(sfsetfd(f,fd) != fd) terror("setfd2"); if(sfgetc(f) != '2') terror("sfgetc3"); texit(0); }
tmain() { Sfio_t *f; if (argc > 1) { if (sfopen(sfstdin, argv[1], "r") != sfstdin) terror("Can't reopen stdin"); sfmove(sfstdin, sfstdout, (Sfoff_t)(-1), -1); return 0; } if (!(f = sfopen(NULL, tstfile("sf", 0), "w"))) terror("Opening to write"); if (sfputc(f, 'a') != 'a') terror("sfputc"); if (sfgetc(f) >= 0) terror("sfgetc"); if (!(f = sfopen(f, tstfile("sf", 0), "r"))) terror("Opening to read"); if (sfgetc(f) != 'a') terror("sfgetc2"); if (sfputc(f, 'b') >= 0) terror("sfputc2"); if (!(f = sfopen(f, tstfile("sf", 0), "r+"))) terror("Opening to read/write"); if (sfgetc(f) != 'a') terror("sfgetc3"); if (sfputc(f, 'b') != 'b') terror("sfputc3"); if (sfclose(f) < 0) terror("sfclose"); if (!(f = sfpopen(NULL, sfprints("%s %s", argv[0], tstfile("sf", 0)), "r"))) terror("sfpopen"); if (sfgetc(f) != 'a') terror("sfgetc4"); if (sfgetc(f) != 'b') terror("sfgetc5"); if (sfgetc(f) >= 0) terror("sfgetc6"); if (!(f = sfopen(f, tstfile("sf", 0), "w"))) terror("sfopen"); if (sfputc(f, 'a') != 'a') terror("sfputc1"); sfsetfd(f, -1); if (sfputc(f, 'b') >= 0) terror("sfputc2"); if (sfclose(f) < 0) terror("sfclose"); if (!(f = sfopen(NULL, tstfile("sf", 0), "a+"))) terror("sfopen2"); sfset(f, SF_READ, 0); if (!sfreserve(f, 0, -1)) terror("Failed on buffer getting"); if (sfvalue(f) <= 0) terror("There is no buffer?"); texit(0); }
// // Copy the last <n> commands to a new file and make this the history file. // static History_t *hist_trim(History_t *hp, int n) { char *cp; int incmd = 1, c = 0; History_t *hist_new, *hist_old = hp; char *buff, *endbuff, *tmpname = NULL; off_t oldp, newp; struct stat statb; unlink(hist_old->histname); if (access(hist_old->histname, F_OK) >= 0) { // The unlink can fail on windows 95. int fd; char *last, *name = hist_old->histname; sh_close(sffileno(hist_old->histfp)); last = strrchr(name, '/'); if (last) { *last = 0; tmpname = ast_temp_file(name, "hist", &fd, 0); *last = '/'; } else { tmpname = ast_temp_file(".", "hist", &fd, 0); } if (!tmpname) { errormsg(SH_DICT, ERROR_exit(1), e_create, "hist"); __builtin_unreachable(); } close(fd); if (rename(name, tmpname) < 0) { free(tmpname); tmpname = name; } fd = open(tmpname, O_RDONLY | O_CLOEXEC); // What happens if this fails and returns -1? Coverity Scan #310940. (void)sfsetfd(hist_old->histfp, fd); if (tmpname == name) { free(tmpname); tmpname = NULL; } } hist_ptr = NULL; if (fstat(sffileno(hist_old->histfp), &statb) >= 0) { histinit = 1; histmode = statb.st_mode; } if (!sh_histinit(hp->histshell)) { // Use the old history file. hist_ptr = hist_old; return hist_ptr; } hist_new = hist_ptr; hist_ptr = hist_old; if (--n < 0) n = 0; newp = hist_seek(hist_old, ++n); while (1) { if (!incmd) { c = hist_ind(hist_new, ++hist_new->histind); hist_new->histcmds[c] = hist_new->histcnt; if (hist_new->histcnt > hist_new->histmarker + HIST_BSIZE / 2) { char locbuff[HIST_MARKSZ]; hist_marker(locbuff, hist_new->histind); sfwrite(hist_new->histfp, locbuff, HIST_MARKSZ); hist_new->histcnt += HIST_MARKSZ; hist_new->histmarker = hist_new->histcmds[hist_ind(hist_new, c)] = hist_new->histcnt; } oldp = newp; newp = hist_seek(hist_old, ++n); if (newp <= oldp) break; } if (!(buff = (char *)sfreserve(hist_old->histfp, SF_UNBOUND, 0))) break; *(endbuff = (cp = buff) + sfvalue(hist_old->histfp)) = 0; // Copy to null byte. incmd = 0; cp += strlen(cp) + 1; // point past the terminating null if (cp > endbuff) { incmd = 1; } else if (*cp == 0) { cp++; } if (cp > endbuff) cp = endbuff; c = cp - buff; hist_new->histcnt += c; sfwrite(hist_new->histfp, buff, c); } hist_cancel(hist_new); sfclose(hist_old->histfp); if (tmpname) { unlink(tmpname); free(tmpname); } free(hist_old); hist_ptr = hist_new; return hist_ptr; }
MAIN() { Sfio_t *f; if(argc > 1) { if(sfopen(sfstdin,argv[1],"r") != sfstdin) terror("Can't reopen stdin"); sfmove(sfstdin,sfstdout,(Sfoff_t)(-1),-1); return 0; } if(!(f = sfopen((Sfio_t*)0,tstfile(0),"w"))) terror("Opening to write\n"); if(sfputc(f,'a') != 'a') terror("sfputc\n"); if(sfgetc(f) >= 0) terror("sfgetc\n"); if(!(f = sfopen(f,tstfile(0),"r"))) terror("Opening to read\n"); if(sfgetc(f) != 'a') terror("sfgetc2\n"); if(sfputc(f,'b') >= 0) terror("sfputc2\n"); if(!(f = sfopen(f,tstfile(0),"r+"))) terror("Opening to read/write\n"); if(sfgetc(f) != 'a') terror("sfgetc3\n"); if(sfputc(f,'b') != 'b') terror("sfputc3\n"); if(sfclose(f) < 0) terror("sfclose\n"); if(!(f = sfpopen(NIL(Sfio_t*),sfprints("%s %s", argv[0], tstfile(0)),"r"))) terror("sfpopen\n"); if(sfgetc(f) != 'a') terror("sfgetc4\n"); if(sfgetc(f) != 'b') terror("sfgetc5\n"); if(sfgetc(f) >= 0) terror("sfgetc6\n"); if(!(f = sfopen(f,tstfile(0),"w")) ) terror("sfopen\n"); if(sfputc(f,'a') != 'a') terror("sfputc1\n"); sfsetfd(f,-1); if(sfputc(f,'b') >= 0) terror("sfputc2\n"); if(sfclose(f) < 0) terror("sfclose\n"); if(!(f = sfopen(NIL(Sfio_t*),tstfile(0),"a+")) ) terror("sfopen2\n"); sfset(f,SF_READ,0); if(!sfreserve(f,0,-1) ) terror("Failed on buffer getting\n"); if(sfvalue(f) <= 0) terror("There is no buffer?\n"); TSTEXIT(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; } }
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; }