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); }
static void filename(int c) { register char* p; register int sh = 0; ed.bytes = 0; ed.lines = 0; p = getrec(ed.buffer.line, '\n', REC_LINE); if (*p) { if (!isspace(*p)) error(2, "no space after command"); for (p++; isspace(*p); p++) ; if (!*p) error(2, "file name expected"); if (c != 'f') { if (*p == '!') { p++; sh = 1; } else if (*p == '\\' && *(p + 1) == '!') p++; } if (ed.restricted) { register char* s = p; if (sh) p--; else for (;;) { switch (*s++) { case 0: break; case '/': case '\n': case '\\': sh = 1; break; default: continue; } break; } if (sh) error(2, "%s: restricted file name", p); } if (!sh && (!*sfstrbase(ed.buffer.file) || c == 'e' || c == 'f')) { sfstrseek(ed.buffer.file, 0, SEEK_SET); sfputr(ed.buffer.file, p, 0); } if (c == 'f') return; } else if (c == 'f') return; else if (!*(p = sfstrbase(ed.buffer.file))) error(2, "file name expected"); if (c == 'e') { edit(); ed.addr2 = ed.zero; } if (sh) { if (!(ed.iop = sfpopen(NiL, p, (c == 'e' || c == 'r') ? "r" : "w"))) error(ERROR_SYSTEM|2, "%s: cannot execute shell command", p); p--; } else if (c == 'e' || c == 'r') { if (!(ed.iop = sfopen(NiL, p, "r"))) error(ERROR_SYSTEM|2, "%s: cannot read", p); } else if ((c != 'W' || !(ed.iop = sfopen(NiL, p, "a"))) && !(ed.iop = sfopen(NiL, p, "w"))) error(ERROR_SYSTEM|2, "%s: cannot write", p); error_info.file = p; }
int wordexp(const char *string, wordexp_t *wdarg, register int flags) { register Sfio_t *iop; register char *cp=(char*)string; register int c,quoted=0,literal=0,ac=0; int offset; char *savebase,**av; if(offset=staktell()) savebase = stakfreeze(0); if(flags&WRDE_REUSE) wordfree(wdarg); else if(!(flags&WRDE_APPEND)) { wdarg->we_wordv = 0; wdarg->we_wordc = 0; } if(flags&WRDE_UNDEF) stakwrite("set -u\n",7); if(!(flags&WRDE_SHOWERR)) stakwrite("exec 2> /dev/null\n",18); stakwrite("print -f \"%q\\n\" ",16); if(*cp=='#') stakputc('\\'); while(c = *cp++) { if(c=='\'' && !quoted) literal = !literal; else if(!literal) { if(c=='\\' && (!quoted || strchr("\\\"`\n$",c))) { stakputc('\\'); if(c= *cp) cp++; else c = '\\'; } else if(c=='"') quoted = !quoted; else if(c=='`' || (c=='$' && *cp=='(')) { if(flags&WRDE_NOCMD) { c=WRDE_CMDSUB; goto err; } /* only the shell can parse the rest */ stakputs(cp-1); break; } else if(!quoted && strchr("|&\n;<>"+ac,c)) { c=WRDE_BADCHAR; goto err; } else if(c=='(') /* allow | and & inside pattern */ ac=2; } stakputc(c); } stakputc(0); if(!(iop = sfpopen((Sfio_t*)0,stakptr(0),"r"))) { c = WRDE_NOSHELL; goto err; } stakseek(0); ac = 0; while((c=sfgetc(iop)) != EOF) { if(c=='\'') quoted = ! quoted; else if(!quoted && (c==' ' || c=='\n')) { ac++; c = 0; } stakputc(c); } if(c=sfclose(iop)) { if(c==3 || !(flags&WRDE_UNDEF)) c=WRDE_SYNTAX; else c=WRDE_BADVAL; goto err; } c = ac+2; if(flags&WRDE_DOOFFS) c += wdarg->we_offs; if(flags&WRDE_APPEND) av = (char**)realloc((void*)&wdarg->we_wordv[-1], (wdarg->we_wordc+c)*sizeof(char*)); else if(av = (char**)malloc(c*sizeof(char*))) { if(flags&WRDE_DOOFFS) memset((void*)av,0,(wdarg->we_offs+1)*sizeof(char*)); else av[0] = 0; } if(!av) return(WRDE_NOSPACE); c = staktell(); if(!(cp = (char*)malloc(sizeof(char*)+c))) { c=WRDE_NOSPACE; goto err; } ((struct list*)cp)->next = (struct list*)(*av); *av++ = (char*)cp; cp += sizeof(char*); wdarg->we_wordv = av; if(flags&WRDE_APPEND) av += wdarg->we_wordc; wdarg->we_wordc += ac; if(flags&WRDE_DOOFFS) av += wdarg->we_offs; memcpy((void*)cp,stakptr(offset),c); while(ac-- > 0) { *av++ = cp; sh_unquote(cp); while(c= *cp++); } *av = 0; c=0; err: if(offset) stakset(savebase,offset); else stakseek(0); return(c); }
static void shell(void) { register char* s; register char* f = 0; register int c; if (ed.given) squeeze(ed.dol > ed.zero); s = getrec(ed.buffer.line, '\n', 0); if (s[0] == '!' && !s[1]) { if (!*sfstrbase(ed.buffer.shell)) error(2, "no saved shell command"); f = sfstrbase(ed.buffer.file); } else if (!s[0]) error(2, "empty shell command"); else SWP(ed.buffer.shell, ed.buffer.line); s = sfstrbase(ed.buffer.shell); sfstrseek(ed.buffer.line, 0, SEEK_SET); sfputc(ed.buffer.line, '!'); while (c = *s++) { if (c == '\\') { if (*s != '%') sfputc(ed.buffer.line, c); sfputc(ed.buffer.line, *s++); } else if (c == '%') sfputr(ed.buffer.line, f = sfstrbase(ed.buffer.file), -1); else sfputc(ed.buffer.line, c); } if (ed.given) { if (!ed.tmpfile && !(ed.tmpfile = pathtemp(NiL, 0, NiL, error_info.id, NiL))) error(ERROR_SYSTEM|2, "cannot generate temp file name"); if (!(ed.iop = sfopen(NiL, ed.tmpfile, "w"))) error(ERROR_SYSTEM|2, "%s: cannot create temp file", ed.tmpfile); error_info.file = ed.tmpfile; if (ed.dol > ed.zero) putfile(); exfile(); ed.bytes = 0; ed.lines = 0; sfprintf(ed.buffer.line, " < %s", ed.tmpfile); if (!(s = sfstruse(ed.buffer.line))) error(ERROR_SYSTEM|3, "out of space"); if (!(ed.iop = sfpopen(NiL, s + 1, "r"))) error(ERROR_SYSTEM|2, "%s: cannot execute shell command", s); error_info.file = s; rdelete(ed.addr1, ed.addr2); append(getfile, ed.dot, NiL); exfile(); remove(ed.tmpfile); } else { if (!(s = sfstruse(ed.buffer.line))) error(ERROR_SYSTEM|3, "out of space"); s++; if (f) putrec(s); if (!(ed.iop = sfpopen(NiL, s, ""))) error(ERROR_SYSTEM|2, "%s: cannot execute shell command", s); if (sfclose(ed.iop)) { ed.iop = 0; error(ERROR_SYSTEM|2, "%s: shell command exit error", s); } if (ed.verbose) putrec("!"); } }
tmain() { Sfio_t *f, *g, *str, *fr, *fw, *sf[2]; int c; char *s; int fd[2]; if(argc > 1) { while((s = sfgetr(sfstdin, '\n', 1)) ) { sfputr(sfstdout, s, '\n'); sfsync(sfstdout); } texit(0); } if(!(str = sfopen(NIL(Sfio_t*),"abc","s")) ) terror("Opening string stream"); if(pipe(fd) < 0) terror("pipe failed"); if(!(fr = sfnew(NIL(Sfio_t*),NIL(Void_t*),(size_t)SF_UNBOUND, fd[0],SF_READ)) ) terror("Opening read pipe stream"); if(!(fw = sfnew(NIL(Sfio_t*),NIL(Void_t*),(size_t)SF_UNBOUND, fd[1],SF_WRITE)) ) terror("Opening write pipe stream"); sf[0] = fr; sf[1] = str; if((c = sfpoll(sf,2,0)) != 1 || sf[0] != str) terror("Only str should be available c=%d",c); sf[0] = fr; if(sfpoll(sf,1,0) != 0 ) terror("Pipe stream should not be ready"); sfputc(fw,'a'); sfsync(fw); sf[0] = fr; if(sfpoll(sf,1,0) != 1 ) terror("Pipe read should be ready"); if((c = sfgetc(fr)) != 'a') terror("Didn't get back right data"); sf[0] = fr; sf[1] = str; if(sfpoll(sf,2,0) != 1 || sf[0] != str) terror("Only str should be available2"); sf[0] = fw; sf[1] = str; if(sfpoll(sf,2,0) != 2) terror("Both str&pipe write should be available"); if(pipe(fd) < 0) terror("Can't create pipe"); if(!(fr = sfnew(fr,NIL(Void_t*),(size_t)SF_UNBOUND,fd[0],SF_READ)) ) terror("Can't create stream"); if(write(fd[1],"0123456789",10) != 10) terror("Can't write to pipe"); if(sfpoll(&fr,1,1000) != 1) terror("Data should be available"); s = sfprints("%s 1", argv[0]); if(!(f = sfpopen(0, s, "w+")) ) terror("Can't create read/write process"); /* this write does not flush yet */ if(sfwrite(f, "abc\n",4) != 4) terror("Writing to pipe"); if(sfpoll(&f, 1, 0) != 1) terror("Poll should succeed"); if(sfvalue(f)&SF_READ) /* data has not been flushed to the child yet */ terror("Read should not be ready"); if(!(sfvalue(f)&SF_WRITE) ) terror("Write should be ready"); if(sfsync(f) < 0) /* now flush data to the child process */ terror("Bad sync"); if(sfpoll(&f, 1, 1000) != 1) terror("Poll should succeed2"); if(!(sfvalue(f)&SF_READ) ) /* the child should have read and rewritten */ terror("Read should be ready"); if(!(sfvalue(f)&SF_WRITE) ) terror("Write should be ready"); if(!(s = sfgetr(f,'\n',1)) || strcmp(s, "abc") != 0) terror("Bad read"); #if _lib_socketpair if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) terror("socketpair failed"); if(!(f = sfnew(0,NIL(Void_t*),(size_t)SF_UNBOUND,fd[0],SF_READ|SF_WRITE)) ) terror("Can't create stream with socket file descriptor"); if(!(g = sfnew(0,NIL(Void_t*),(size_t)SF_UNBOUND,fd[1],SF_READ|SF_WRITE)) ) terror("Can't create stream with socket file descriptor"); /* turn off write-capability for f */ sfset(f,SF_WRITE,0); sf[0] = f; sf[1] = g; if(sfpoll(sf,2,0) != 1) terror("Exactly one stream should be ready!"); if(sf[0] != g) terror("Stream g should be ready"); if(sfvalue(g)&SF_READ) terror("Read should not be ready for g"); if(!(sfvalue(g)&SF_WRITE) ) terror("Write should be ready for g"); if(sfwrite(g, "abc\n", 4) != 4 || sfsync(g) < 0) terror("Writing to g socket"); if(sfpoll(sf, 2, 0) != 2) terror("Poll should succeed with both streams"); if(!(sfvalue(f)&SF_READ) ) terror("Read should be ready for f"); if(sfgetc(f) != 'a' ) terror("sfgetc failed"); /* turn back on write-capability for f */ sfset(f,SF_WRITE,1); if(sfwrite(f,"def\n",4) != 4 || sfsync(f) < 0) terror("Writing to f socket"); if(sfpoll(sf, 2, 0) != 2) terror("Poll should succeed for both streams"); if(!sfvalue(f)&SF_READ) terror("Read should be ready for f"); if(!sfvalue(g)&SF_READ) terror("Read should be ready for g"); if(!(s = sfgetr(f,'\n',1)) || strcmp(s,"bc") != 0) terror("f gets wrong data"); if(!(s = sfgetr(g,'\n',1)) || strcmp(s,"def") != 0) terror("g gets wrong data"); if(sfpoll(sf, 2, 0) != 2) terror("Poll should succeed for both streams"); if(sfvalue(f)&SF_READ) terror("Read should not be ready for f"); if(sfvalue(g)&SF_READ) terror("Read should not be ready for g"); #endif texit(0); }