void rescue(void) { int i, nblank = 0; File *f; char *c; char buf[256]; if(rescuing++) return; io = -1; for(i=0; i<file.nused; i++) { f = file.filepptr[i]; if(f==cmd || f->nc==0 || !fileisdirty(f)) continue; if(io == -1) { sprint(buf, "%s/sam.save", home); io = create(buf, 1, 0777); if(io<0) return; } if(f->name.s[0]) { c = Strtoc(&f->name); strncpy(buf, c, sizeof buf-1); buf[sizeof buf-1] = 0; free(c); } else sprint(buf, "nameless.%d", nblank++); fprint(io, "#!%s '%s' $* <<'---%s'\n", SAMSAVECMD, buf, buf); addr.r.p1 = 0, addr.r.p2 = f->nc; writeio(f); fprint(io, "\n---%s\n", (char *)buf); } }
void writef(File *f) { Posn n; char *name; int i, samename, newfile; ulong dev; uvlong qid; long mtime, appendonly, length; newfile = 0; samename = Strcmp(&genstr, &f->name) == 0; name = Strtoc(&f->name); i = statfile(name, &dev, &qid, &mtime, 0, 0); if(i == -1) newfile++; else if(samename && (f->dev!=dev || f->qidpath!=qid || f->mtime<mtime)){ f->dev = dev; f->qidpath = qid; f->mtime = mtime; warn_S(Wdate, &genstr); free(name); return; } if(genc) free(genc); genc = Strtoc(&genstr); if((io=create(genc, 1, 0666L)) < 0) error_r(Ecreate, genc); dprint("%s: ", genc); if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0){ free(name); error(Eappend); } n = writeio(f); if(f->name.s[0]==0 || samename){ if(addr.r.p1==0 && addr.r.p2==f->b.nc) f->cleanseq = f->seq; state(f, f->cleanseq==f->seq? Clean : Dirty); } if(newfile) dprint("(new file) "); if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n') warn(Wnotnewline); closeio(n); if(f->name.s[0]==0 || samename){ if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){ f->dev = dev; f->qidpath = qid; f->mtime = mtime; checkqid(f); } } free(name); }
void writef(File *f) { Rune c; Posn n; char *name; int i, samename, newfile; ulong dev, qid; long mtime, appendonly, length; newfile = 0; samename = Strcmp(&genstr, &f->name) == 0; name = Strtoc(&f->name); i = statfile(name, &dev, &qid, &mtime, 0, 0); if(i == -1) newfile++; else if(samename && (f->dev!=dev || f->qid!=qid || f->date<mtime)){ f->dev = dev; f->qid = qid; f->date = mtime; warn_S(Wdate, &genstr); return; } if(genc) free(genc); genc = Strtoc(&genstr); if((io=create(genc, 1, 0666L)) < 0) error_s(Ecreate, genc); dprint("%s: ", genc); if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0) error(Eappend); n = writeio(f); if(f->name.s[0]==0 || samename) state(f, addr.r.p1==0 && addr.r.p2==f->nrunes? Clean : Dirty); if(newfile) dprint("(new file) "); if(addr.r.p2>0 && Fchars(f, &c, addr.r.p2-1, addr.r.p2) && c!='\n') warn(Wnotnewline); closeio(n); if(f->name.s[0]==0 || samename){ if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){ f->dev = dev; f->qid = qid; f->date = mtime; checkqid(f); } } }
void rescue(void) { if (rescuing++) return; if (io){ fclose(io); io = NULL; } for (int i = 0; i < file.nused; i++){ char buf[FILENAME_MAX + 1] = {0}; File *f = file.filepptr[i]; if (f == cmd || f->nrunes == 0 || f->state != Dirty) continue; snprintf(buf, FILENAME_MAX, "%s/sam.save", home); if ((io = fopen(buf, "w")) == NULL) continue; fprintf(io, "samsave() {\n" " echo \"${1}?\"\n" " read yn < /dev/tty\n" " case \"${yn}\" in\n" " [Yy]*) cat > \"${1}\"\n" " esac\n" "}\n"); if(f->name.s[0]){ char *c = Strtoc(&f->name); snprintf(buf, FILENAME_MAX, "%s", c); free(c); }else snprintf(buf, FILENAME_MAX, "nameless.%d", i); fprintf(io, "samsave %s <<'---%s'\n", buf, buf); addr.r.p1 = 0, addr.r.p2 = f->nrunes; writeio(f); fprintf(io, "\n---%s\n", (char *)buf); flushio(); } }
void rescue(void) { int i, nblank = 0; File *f; char *c; char buf[256]; if(rescuing++) return; io = -1; for(i=0; i<file.nused; i++) { f = file.filepptr[i]; if(f==cmd || f->nrunes==0 || f->state!=Dirty) continue; if(io == -1) { snprintf(buf, sizeof(buf) - 1, "%s/sam.save", home); io = creat(buf, 0700); if(io<0) return; dprintf(io, "samsave() {\n" " echo \"${1}?\"\n" " read yn < /dev/tty\n" " case \"${yn}\" in\n" " [Yy]*) cat > \"${1}\"\n" " esac\n" "}\n"); } if(f->name.s[0]) { c = Strtoc(&f->name); strncpy(buf, c, sizeof buf-1); buf[sizeof buf-1] = 0; free(c); } else snprintf(buf, sizeof(buf) - 1, "nameless.%d", nblank++); dprintf(io, "samsave %s <<'---%s'\n", buf, buf); addr.r.p1 = 0, addr.r.p2 = f->nrunes; writeio(f); dprintf(io, "\n---%s\n", (char *)buf); } }
int plan9(File *f, int type, String *s, int nest) { long l; int m; int volatile pid; int fd; int retcode; int pipe1[2], pipe2[2]; if(s->s[0]==0 && plan9cmd.s[0]==0) error(Enocmd); else if(s->s[0]) Strduplstr(&plan9cmd, s); if(downloaded){ samerr(errfile); remove(errfile); } if(type!='!' && pipe(pipe1)==-1) error(Epipe); if(type=='|') snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1); if((pid=fork()) == 0){ setname(f); if(downloaded){ /* also put nasty fd's into errfile */ fd = create(errfile, 1, 0666L); if(fd < 0) fd = create("/dev/null", 1, 0666L); dup(fd, 2); close(fd); /* 2 now points at err file */ if(type == '>') dup(2, 1); else if(type=='!'){ dup(2, 1); fd = open("/dev/null", 0); dup(fd, 0); close(fd); } } if(type != '!') { if(type=='<' || type=='|') dup(pipe1[1], 1); else if(type == '>') dup(pipe1[0], 0); close(pipe1[0]); close(pipe1[1]); } if(type == '|'){ if(pipe(pipe2) == -1) exits("pipe"); if((pid = fork())==0){ /* * It's ok if we get SIGPIPE here */ close(pipe2[0]); io = pipe2[1]; if(retcode=!setjmp(mainloop)){ /* assignment = */ char *c; for(l = 0; l<plan9buf.nc; l+=m){ m = plan9buf.nc-l; if(m>BLOCKSIZE-1) m = BLOCKSIZE-1; bufread(&plan9buf, l, genbuf, m); genbuf[m] = 0; c = Strtoc(tmprstr(genbuf, m+1)); Write(pipe2[1], c, strlen(c)); free(c); } } exits(retcode? "error" : 0); } if(pid==-1){ fprint(2, "Can't fork?!\n"); exits("fork"); } dup(pipe2[0], 0); close(pipe2[0]); close(pipe2[1]); } if(type=='<'){ close(0); /* so it won't read from terminal */ open("/dev/null", 0); } execl(SHPATH, SH, "-c", Strtoc(&plan9cmd), (char *)0); exits("exec"); } if(pid == -1) error(Efork); if(type=='<' || type=='|'){ int nulls; if(downloaded && addr.r.p1 != addr.r.p2) outTl(Hsnarflen, addr.r.p2-addr.r.p1); snarf(f, addr.r.p1, addr.r.p2, &snarfbuf, 0); logdelete(f, addr.r.p1, addr.r.p2); close(pipe1[1]); io = pipe1[0]; f->tdot.p1 = -1; f->ndot.r.p2 = addr.r.p2+readio(f, &nulls, 0, FALSE); f->ndot.r.p1 = addr.r.p2; closeio((Posn)-1); }else if(type=='>'){ close(pipe1[0]); io = pipe1[1]; bpipeok = 1; writeio(f); bpipeok = 0; closeio((Posn)-1); } retcode = waitfor(pid); if(type=='|' || type=='<') if(retcode!=0) warn(Wbadstatus); if(downloaded) checkerrs(); if(!nest) dprint("!\n"); return retcode; }