예제 #1
0
파일: history.c 프로젝트: att/ast
//
// Copy command <command> from history file to s1. At most <size> characters copied. If s1==0 the
// number of lines for the command is returned. Set line=linenumber for emacs copy and only this
// line of command will be copied. Set line < 0 for full command copy.
//
// Return -1 if there is no history file.
//
int hist_copy(char *s1, int size, int command, int line) {
    int c;
    History_t *hp = shgd->hist_ptr;
    int count = 0;
    char *s1max = s1 + size;

    if (!hp) return -1;
    hist_seek(hp, command);
    while ((c = sfgetc(hp->histfp)) && c != EOF) {
        if (c == '\n') {
            if (count++ == line) {
                break;
            } else if (line >= 0) {
                continue;
            }
        }
        if (s1 && (line < 0 || line == count)) {
            if (s1 >= s1max) {
                *--s1 = 0;
                break;
            }
            *s1++ = c;
        }
    }
    sfseek(hp->histfp, (off_t)0, SEEK_END);
    if (s1 == 0) return count;
    if (count && (c = *(s1 - 1)) == '\n') s1--;
    *s1 = '\0';
    return count;
}
예제 #2
0
파일: texcept.c 프로젝트: att/ast
static ssize_t readfunc(Sfio_t *f, void *buf, size_t n, Sfdisc_t *disc) {
    UNUSED(buf);
    UNUSED(n);
    UNUSED(disc);

    if (sfgetc(f) >= 0) terror("Can't access stream here!");
    return 0;
}
예제 #3
0
int
pzfile(Pz_t* pz)
{
	unsigned char*	s;
	int		i;
	int		j;
	size_t		n;

	/*
	 * 0 or more nul's mean clean EOF
	 */

	while (!(i = sfgetc(pz->io)));
	if (pz->disc->errorf)
		(*pz->disc->errorf)(pz, pz->disc, -1, "%s: pzfile: i=%02x", pz->path, i);
	if (i == -1)
		return 0;
	if (i == PZ_MARK_TAIL)
	{
		/*
		 * file trailer
		 */

		while ((n = sfgetu(pz->io)) && !sferror(pz->io) && !sfeof(pz->io) && (s = (unsigned char*)sfreserve(pz->io, n, 0)))
			if (pz->disc->eventf && (*pz->disc->eventf)(pz, PZ_TAILREAD, s, n, pz->disc) < 0)
				return -1;
		if ((i = sfgetc(pz->io)) == -1)
			return 0;
	}
	j = sfgetc(pz->io);
	if (pz->disc->errorf)
		(*pz->disc->errorf)(pz, pz->disc, -1, "%s: pzfile: i=%02x j=%02x", pz->path, i, j);
	if (i == PZ_MAGIC_1 && j == PZ_MAGIC_2)
	{
		/*
		 * next file header
		 */

		sfungetc(pz->io, j);
		sfungetc(pz->io, i);
		return pzopen(pz->disc, (char*)pz, PZ_AGAIN) ? 1 : -1;
	}
	if (pz->disc->errorf)
		(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data corrupted", pz->path);
	return -1;
}
예제 #4
0
static struct argnod *r_arg(Shell_t *shp)
{
	register struct argnod *ap=0, *apold, *aptop=0;
	register long l;
	Stk_t		*stkp=shp->stk;
	while((l=sfgetu(infile))>0)
	{
		ap = (struct argnod*)stkseek(stkp,(unsigned)l+ARGVAL);
		if(!aptop)
			aptop = ap;
		else
			apold->argnxt.ap = ap;
		if(--l > 0)
		{
			sfread(infile,ap->argval,(size_t)l);
			ccmaps(ap->argval, l, CC_ASCII, CC_NATIVE);
		}
		ap->argval[l] = 0;
		ap->argchn.cp = 0;
		ap->argflag = sfgetc(infile);
#if 0
		if((ap->argflag&ARG_MESSAGE) && *ap->argval)
		{
			/* replace international messages */
			sh_endword(shp,1);
			ap->argflag &= ~ARG_MESSAGE;
			if(!(ap->argflag&(ARG_MAC|ARG_EXP)))
				ap = sh_endword(shp,0);
			else
			{
				ap = (struct argnod*)stkfreeze(stkp,0);
				if(ap->argflag==0)
					ap->argflag = ARG_RAW;
			}
		}
		else
#endif
			ap = (struct argnod*)stkfreeze(stkp,0);
		if(*ap->argval==0 && (ap->argflag&ARG_EXP))
			ap->argchn.ap = (struct argnod*)r_tree(shp);
		else if(*ap->argval==0 && (ap->argflag&~(ARG_APPEND|ARG_MESSAGE|ARG_QUOTED|ARG_ARRAY))==0)
		{
			struct fornod *fp = (struct fornod*)getnode(shp->stk,fornod);
			fp->fortyp = sfgetu(infile);
			fp->fortre = r_tree(shp);
			fp->fornam = ap->argval+1;
			ap->argchn.ap = (struct argnod*)fp;
		}
		apold = ap;
	}
	if(ap)
		ap->argnxt.ap = 0;
	return(aptop);
}
예제 #5
0
파일: tungetc.c 프로젝트: att/ast
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    Sfio_t *f;
    char *str, *alpha, *s;
    char buf[128];
    int n;

    str = "0123456789";
    alpha = "abcdefghijklmnop";

    if (!(f = sfopen(NULL, alpha, "s"))) terror("Opening stream");

    for (n = 9; n >= 0; --n) {
        if (sfungetc(f, n + '0') != n + '0') terror("Ungetc");
    }

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || sfvalue(f) != 10) terror("Peek stream1");
    if (strncmp(s, str, 10) != 0) terror("Bad data1");

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || sfvalue(f) != (ssize_t)strlen(alpha)) {
        terror("Peek stream2");
    }
    if (strncmp(s, alpha, strlen(alpha)) != 0) terror("Bad data2");

    sfseek(f, (Sfoff_t)0, 0);
    for (n = 9; n >= 0; --n) {
        if (sfungetc(f, n + '0') != n + '0') terror("Ungetc2");
    }
    if (sfgetc(f) != '0') terror("Sfgetc");
    sfseek(f, (Sfoff_t)0, 0);
    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || sfvalue(f) != (ssize_t)strlen(alpha)) {
        terror("Peek stream3");
    }
    if (strncmp(s, alpha, strlen(alpha)) != 0) terror("Bad data2");

    sfseek(f, (Sfoff_t)0, 0);
    if (sfungetc(f, '0') != '0') terror("Ungetc3");

    strcpy(buf, "0123456789\n");
    if (!(f = sfopen(f, buf, "s+"))) terror("Reopening  string");
    if (sfungetc(f, '\n') != '\n') terror("Can't unget new-line2");
    if (sfungetc(f, 'd') != 'd') terror("Can't unget d");
    if (sfungetc(f, 'c') != 'c') terror("Can't unget c");
    if (sfungetc(f, '\n') != '\n') terror("Can't unget new-line");
    if (sfungetc(f, 'b') != 'b') terror("Can't unget b");
    if (sfungetc(f, 'a') != 'a') terror("Can't unget a");

    if (!(s = sfgetr(f, '\n', 1)) || strcmp(s, "ab") != 0) terror("Did not get ab");
    if (!(s = sfgetr(f, '\n', 1)) || strcmp(s, "cd") != 0) terror("Did not get cd");
    if (!(s = sfgetr(f, '\n', 1)) || strcmp(s, "0123456789") != 0) terror("Did not get 0123456789");

    texit(0);
}
예제 #6
0
파일: extoken.c 프로젝트: aosm/graphviz
static int
lex(register Expr_t* ex)
{
	register int	c;

	for (;;)
	{
		if ((c = ex->input->peek))
			ex->input->peek = 0;
		else if (ex->input->pp)
		{
			if (!(c = *ex->input->pp++))
			{
				ex->input->pp = 0;
				continue;
			}
		}
		else if (ex->input->sp)
		{
			if (!(c = *ex->input->sp++))
			{
				if (!expop(ex))
					continue;
				else trace(ex, -1, "expop sp FAIL", 0);
				ex->input->sp--;
			}
		}
		else if (ex->input->fp)
		{
			if ((c = sfgetc(ex->input->fp)) == EOF)
			{
				if (!expop(ex))
					continue;
				else trace(ex, -1, "expop fp FAIL", 0);
				c = 0;
			}
			else if ((ex->disc->flags & EX_INTERACTIVE) && c == '\n' && ex->input->next && !ex->input->next->next && ex->input->nesting <= 0)
			{
				error_info.line++;
				expop(ex);
				trace(ex, -1, "expop sp FORCE", 0);
				c = 0;
			}
		}
		else c = 0;
		if (c == '\n')
			setcontext(ex);
		else if (c)
			putcontext(ex, c);
		/* trace(ex, -3, "ex--lex", c); */
		return c;
	}
}
예제 #7
0
파일: tsetfd.c 프로젝트: ISLEcode/kornshell
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);
}
예제 #8
0
파일: tsetfd.c 프로젝트: gwowen/seismicunix
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);
}
예제 #9
0
파일: nvtree.c 프로젝트: ISLEcode/kornshell
static int read_tree(Namval_t* np, Sfio_t *iop, int n, Namfun_t *dp)
{
	Sfio_t	*sp;
	char	*cp;
	int	c;
	if(n>=0)
		return(-1);
	while((c = sfgetc(iop)) &&  isblank(c));
	sfungetc(iop,c);
	sfprintf(sh.strbuf,"%s=%c",nv_name(np),0);
	cp = sfstruse(sh.strbuf);
	sp = sfopen((Sfio_t*)0,cp,"s");
	sfstack(iop,sp);
	c=sh_eval(iop,SH_READEVAL);
	return(c);
}
예제 #10
0
tmain()
{	Sfio_t	*f;
	int	i, c;

	if(!(f = sftmp(8)))
		terror("Can't open temp file");

	for(i = 0; i < 10000; ++i)
		if(sfputc(f,(i%26)+'a') < 0)
			terror("Writing %c",(i%26)+'a');

	sfseek(f,(Sfoff_t)0,0);

	for(i = 0; i < 10000; ++i)
		if((c = sfgetc(f)) != ((i%26)+'a'))
			terror("Input=%#o, Expect=%c",c,(i%26)+'a');

	texit(0);
}
예제 #11
0
파일: actions.c 프로젝트: ellert/graphviz
/*
 * Read single line from stream.
 * Return "" on EOF.
 */
char *readLine(Expr_t * ex, int fd)
{
    Sfio_t *sp;
    int c;
    Sfio_t *tmps;
    char *line;

    if (fd < 0 || fd >= elementsof(ex->file) || !((sp = ex->file[fd]))) {
	exerror("readL: %d: invalid descriptor", fd);
	return "";
    }
    tmps = sfstropen();
    while (((c = sfgetc(sp)) > 0) && (c != '\n'))
	sfputc(tmps, c);
    if (c == '\n')
	sfputc(tmps, c);
    line = exstring(ex, sfstruse(tmps));
    sfclose(tmps);
    return line;
}
예제 #12
0
파일: history.c 프로젝트: att/ast
void hist_list(History_t *hp, Sfio_t *outfile, off_t offset, int last, const char *nl) {
    int oldc = 0;
    int c;

    if (offset < 0 || !hp) {
        sfputr(outfile, sh_translate(e_unknown), '\n');
        return;
    }
    sfseek(hp->histfp, offset, SEEK_SET);
    while ((c = sfgetc(hp->histfp)) != EOF) {
        if (c && oldc == '\n') {
            sfputr(outfile, nl, -1);
        } else if (last && (c == 0 || (c == '\n' && oldc == last))) {
            return;
        } else if (oldc) {
            sfputc(outfile, oldc);
        }
        oldc = c;
        if (c == 0) return;
    }
    return;
}
예제 #13
0
파일: stream.c 프로젝트: ChappedSky/hancock
/* is there stuff left?  if not, go to next file */
static int advFile(generalStream_s *gs)
{
  if (gs->fpLen == -1) {
    int c = sfgetc(gs->fp);
    if (c == EOF)
      return 0;
    sfungetc(gs->fp, c);
    return 1;
  } else {
    if (sftell(gs->fp) == gs->fpLen) {
      while (++gs->count < gs->numFilesinStream) {
	HRSclosefile(gs->fp);
	gs->fp = HRSopenfile(gs->fileNames[gs->count], "r");
	gs->fpLen = sfsize(gs->fp);
	if (gs->fpLen != 0)
	  return 1;
      }
      return 0;
    }

    return 1;
  }
  
}
예제 #14
0
파일: tmode.c 프로젝트: att/ast
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);
}
예제 #15
0
파일: terrno.c 프로젝트: jiayuehua/sfio
MAIN()
{
  Sfio_t* fw;
  Sfio_t* fr;
  int fds[2];
  int lseek_errno;
  int rv;

  if(!(fw = sfopen(NIL(Sfio_t*), tstfile(0), "w")) )
    terror("Can't create temp file %s to write", tstfile(0));
  if(!(fr = sfopen(NIL(Sfio_t*), tstfile(0), "r")) )
    terror("Can't open temp file %s to read", tstfile(0));

  sfseek(fr, (Sfoff_t)0, SEEK_END);
  if(sfgetc(fr) >= 0 || !sfeof(fr))
    terror("Should have seen eof");

  errno = 0;
  if((rv = sfwrite(fr, "a", 1)) == 1)
    terror("sfwrite returns %d, expecting 1", rv);
  if(errno != EBADF)
    twarn("Wrong errno %d after sfwrite(%d), expecting %d",errno,rv,EBADF);

  /* on some system (eg, apple), lseek does not set errno for this case */
  errno = 0;
  lseek(sffileno(fw), (off_t)(-2), SEEK_SET);
  lseek_errno = errno;
  lseek(sffileno(fw), (off_t)0, SEEK_SET);
  errno = 0;

  if(sfseek(fw, (Sfoff_t)(-2), SEEK_SET) != (Sfoff_t)(-1) )
    terror("sfseek should have failed");
  if(errno != lseek_errno)
    twarn("Wrong errno %d after sfseek, expecting %d", errno, lseek_errno);

  errno = 0;
  if(sfseek(fw, (Sfoff_t)0, SEEK_SET|SEEK_CUR|SEEK_END) >= 0)
    terror("sfseek should not have succeeded");
  if(errno != EINVAL)
    twarn("Wrong errno %d after sfseek, expecting %d", errno, EINVAL);

  if(pipe(fds) < 0)
    terror("Can't create pipes");

  if(!(fw = sfnew(fw, NIL(Void_t*), (size_t)SF_UNBOUND, fds[1], SF_WRITE)) )
    terror("Can't create stream for pipe");

  errno = 0;
  if(sfseek(fw, (Sfoff_t)0, SEEK_SET) >= 0)
    terror("sfseek should have failed on a pipe");
  if(errno != ESPIPE)
    twarn("Wrong errno %d after sfseek, expecting %d", ESPIPE);

  close(sffileno(fw));
  errno = 0;
  if(sfseek(fw, (Sfoff_t)0, SEEK_END) >= 0)
    terror("sfseek should have failed on a closed file descriptor");
  if(errno != EBADF)
    twarn("Wrong errno %d after sfseek, expecting %d", EBADF);

  TSTEXIT(0);
}
예제 #16
0
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);
}
예제 #17
0
파일: texcept.c 프로젝트: att/ast
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);
}
예제 #18
0
파일: tmode.c 프로젝트: jiayuehua/sfio
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);
}
예제 #19
0
파일: tflags.c 프로젝트: ISLEcode/kornshell
tmain()
{
	Sfio_t*	f;

	if(!(f = sfopen(NIL(Sfio_t*),"ab","sr")) )
		terror("Can't open stream");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet");
	if(sfgetc(f) != 'a')
		terror("Got wrong data");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet2");
	if(sfgetc(f) != 'b')
		terror("Got wrong data2");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet3");
	if(sfgetc(f) >= 0)
		terror("Got wrong data2");
	if(!sfeof(f))
		terror("Should be eof now");
	if(sfseek(f,(Sfoff_t)(-1),2) != 1)
		terror("Seek error");
	if(sfeof(f))
		terror("Shouldn't be eof any more");

	if(!(f = sfopen(NIL(Sfio_t*), tstfile("sf", 0), "w+")) )
		terror("Can't open stream2");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet2");
	if(sfwrite(f,"ab",2) != 2)
		terror("Can't write data");
	if(sfseek(f,(Sfoff_t)0,0) != 0)
		terror("Can't seek back");
	if(sfgetc(f) != 'a')
		terror("Got wrong data3");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet4");
	if(sfgetc(f) != 'b')
		terror("Got wrong data4");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet5");
	if(sfgetc(f) >= 0)
		terror("Got wrong data5");
	if(!sfeof(f))
		terror("Should be eof now2");
	if(sfseek(f,(Sfoff_t)(-1),2) != 1)
		terror("Seek error2");
	if(sfeof(f))
		terror("Shouldn't be eof any more2");

	if(!(f = sfopen(NIL(Sfio_t*), tstfile("sf", 0),"w+")) )
		terror("Reopening %s", tstfile("sf", 0));
	sfwrite(f,"1234567890",10);
	sfseek(f,(Sfoff_t)0,0);

	if(sfopen(sfstdout, tstfile("sf", 1), "w") != sfstdout)
		terror("Opening %s", tstfile("sf", 1));

	if(sfmove(f,sfstdout,(Sfoff_t)(-1),-1) != 10)
		terror("sfmove failed");
	if(!sfeof(f))
		terror("f should be eof");
	if(sferror(sfstdout))
		terror("sfstdout should not be in error");

	texit(0);
}
예제 #20
0
파일: tstack.c 프로젝트: att/ast
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    Sfio_t *f1, *f2, *f3, *f;
    char *s, *s1, *s2, *s3, *s4;
    int n;
    int fd[2];

    if (!(f1 = sfopen(NULL, tstfile("sf", 0), "w+"))) terror("Opening file1");
    if (!(f2 = sfopen(NULL, tstfile("sf", 0), "w+"))) terror("Opening file2");
    Fclose = f2;
    sfdisc(f1, &Disc);
    sfdisc(f2, &Disc);
    sfstack(f1, f2);
    if ((n = sfgetc(f1)) >= 0 || !sfeof(f1)) terror("There should be no data n=%d", n);
    if (sfstacked(f1)) terror("There should be no stack");
    Fclose = f1;
    if (sfclose(f1) < 0) terror("Can't close f1");
    tcleanup();

    s1 = "1234567890";
    s2 = "abcdefghijklmnopqrstuvwxyz";
    s3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    s4 = "!@#$%^&*()_-+={}[]~`':;?/><,|";

    if (!(f1 = sfopen(NULL, s1, "s")) || !(f2 = sfopen(NULL, s2, "s")) ||
        !(f3 = sfopen(NULL, s3, "s"))) {
        terror("Opening strings");
    }

    sfdisc(sfstdin, &Disc);
    sfclose(sfstdin);
    if (sffileno(sfstdin) != 0) terror("Bad fd for stdin");

    if (!(f = sfopen(NULL, tstfile("sf", 0), "w+"))) terror("Opening file");
    if (sfwrite(f, "0123456789", 10) != 10) terror("Write file");
    if (sfseek(f, (Sfoff_t)0, 0) != 0) terror("Seek file");

    if (sfstack(sfstdin, f) != sfstdin) terror("Stacking on stdin2");
    if (sfopen(sfstdout, "/dev/null", "w") != sfstdout) terror("Opening sfstdout");
    if (sfmove(sfstdin, sfstdout, (Sfoff_t)SF_UNBOUND, -1) != 10 || !sfeof(sfstdin) ||
        sferror(sfstdout)) {
        terror("Bad sfmove");
    }

    tcleanup();

    if (!(f = sftmp(0))) terror("Opening temp file");
    if (sfputr(f, s4, -1) != (ssize_t)strlen(s4)) terror("Writing s4");
    sfseek(f, (Sfoff_t)0, 0);

#if FIX_THIS_TEST_2008_08_11
    if (sfstack(f, f3) != f) terror("Stacking s3");
    if (sfstack(f, f2) != f) terror("Stacking s2");
    if (sfstack(f, f1) != f) terror("Stacking s1");

    sfsprintf(str, sizeof(str), "%s%s%s%s", s1, s2, s3, s4);
    if ((ss = sfgetr(f, '\n', 1)))
        terror("There shouldn't have been any new-line");
    else {
        if (!(ss = sfgetr(f, '\n', -1))) terror("Reading streams");
        n = sfvalue(f);
        if (ss[n]) ss[n] = 0;
    }

    if (strcmp(ss, str) != 0) terror("Expect=%s Got=%s", str, ss);
#endif

    if (!(f1 = sfopen(NULL, s1, "s")) || !(f2 = sfopen(NULL, s2, "s")) ||
        !(f3 = sfopen(NULL, s3, "s"))) {
        terror("Opening strings2");
    }
    sfseek(f, (Sfoff_t)0, 0);

    if (sfstack(f, f3) != f || sfstack(f, f2) != f || sfstack(f, f1) != f) {
        terror("Stacking streams2");
    }

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || s != s1) terror("Sfpeek1");

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || s != s2) terror("Sfpeek2");

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || s != s3) terror("Sfpeek3");

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || strncmp(s, s4, strlen(s4)) != 0) terror("Sfpeek4");

    /* test to see if hidden read data still accessible */
    if (pipe(fd) < 0) terror("Can't create pipe");
    if (!(f1 = sfnew(0, NULL, (size_t)SF_UNBOUND, fd[0], SF_READ | SF_WRITE))) {
        terror("Can't create stream");
    }

    if (write(fd[1], "0123", 4) != 4) terror("Can't write to pipe");
    if (sfgetc(f1) != '0') terror("sfgetc failed");

    /* hack to create hidden reserved buffer */
    f1->file = fd[1];
    if (sfwrite(f1, "4", 1) != 1) terror("Can't write to stream");
    sfsync(f1);
    f1->file = fd[0];
    close(fd[1]);

    /* now stack stream */
    if (!(f2 = sfopen(0, "abcd\n", "s"))) terror("Can't open string stream");

    sfstack(f2, f1);

    if (!(s = sfgetr(f2, '\n', 1))) terror("sfgetr failed");

    if (strcmp(s, "1234abcd") != 0) terror("sfgetr got wrong data");

    texit(0);
}
예제 #21
0
int
astquery(int quit, const char* format, ...)
{
	va_list		ap;
	register int	n;
	register int	c;
	Sfio_t*		ip;
	Sfio_t*		op;

	static Sfio_t*	rfp;
	static Sfio_t*	wfp;

	va_start(ap, format);
	if (!format)
		return 0;
	if (!rfp)
	{
		c = errno;
		if (isatty(sffileno(sfstdin)))
			rfp = sfstdin;
		else if (!(rfp = sfopen(NiL, "/dev/tty", "r")))
			return -1;
		if (isatty(sffileno(sfstderr)))
			wfp = sfstderr;
		else if (!(wfp = sfopen(NiL, "/dev/tty", "w")))
			return -1;
		errno = c;
	}
	if (quit & ERROR_PROMPT)
	{
		quit &= ~ERROR_PROMPT;
		ip = rfp;
		op = wfp;
	}
	else
	{
		ip = sfstdin;
		op = sfstderr;
	}
	sfsync(sfstdout);
	sfvprintf(op, format, ap);
	sfsync(op);
	for (n = c = sfgetc(ip);; c = sfgetc(ip))
		switch (c)
		{
		case EOF:
			n = c;
			/*FALLTHROUGH*/
		case '\n':
			switch (n)
			{
			case EOF:
			case 'q':
			case 'Q':
				if (quit >= 0)
					exit(quit);
				return -1;
			case '1':
			case 'y':
			case 'Y':
			case '+':
				return 0;
			}
			return 1;
		}
	va_end(ap);
	/*NOTREACHED*/
}
예제 #22
0
파일: ncsl.c 프로젝트: ISLEcode/kornshell
static int
ncsl(register Sfio_t* sp)
{
	register int		c;
	register int		data;
	register unsigned long	line;
	int			quote;

	line = 0;
	data = 0;
 again:
	for (;;) switch (c = sfgetc(sp))
	{
	case EOF:
		return(line);
	case ' ':
	case '\f':
	case '\t':
		break;
	case '\n':
	newline:
		if (data)
		{
			if (data > 0) line++;
			data = 0;
		}
		break;
	case '/':
		if (data < 0) goto again;
		switch (c = sfgetc(sp))
		{
		case '/':
			for (;;) switch (c = sfgetc(sp))
			{
			case EOF:
				goto again;
			case '\n':
				goto newline;
			default:
				if (JUNK(c))
				{
					data = -1;
					goto again;
				}
				break;
			}
			break;
		case '*':
			for (;;) switch (c = sfgetc(sp))
			{
			case EOF:
			case '*':
				for (;;)
				{
					switch (c = sfgetc(sp))
					{
					case EOF:
					case '/':
						goto again;
					case '*':
						continue;
					default:
						if (JUNK(c))
						{
							data = -1;
							goto again;
						}
						break;
					}
					break;
				}
				break;
			default:
				if (JUNK(c))
				{
					data = -1;
					goto again;
				}
				break;
			}
			break;
		case EOF:
			break;
		default:
			if (!data) data = 1;
			sfungetc(sp, c);
			break;
		}
		break;
	case '"':
	case '\'':
		if (data < 0) goto again;
		data = 1;
		quote = c;
		for (;;) switch (c = sfgetc(sp))
		{
		case EOF:
			goto again;
		case '"':
		case '\'':
			if (c == quote) goto again;
			break;
		case '\n':
			goto newline;
		case '\\':
			switch (c = sfgetc(sp))
			{
			case EOF:
				goto again;
			case '\n':
				line++;
				continue;
			}
			/*FALLTHROUGH*/
		default:
			if (JUNK(c))
			{
				data = -1;
				goto again;
			}
			break;
		}
		break;
	default:
		if (JUNK(c)) data = -1;
		else if (!data) data = 1;
		break;
	}
	/*NOTREACHED*/
}
예제 #23
0
int
pzheadread(register Pz_t* pz)
{
	register int		i;
	register int		n;
	register unsigned char*	s;
	size_t			m;
	Pzpart_t*		pp;

	if (pz->flags & PZ_HEAD)
		return 0;

	/*
	 * check the header magic
	 */

	if (s = (unsigned char*)sfreserve(pz->io, 4, 1))
	{
		i = s[0];
		n = s[1];
	}
	else
		i = n = 0;
	if (pz->disc->errorf)
		(*pz->disc->errorf)(pz, pz->disc, -1, "%s: pzheadread: f=%08x i=%02x n=%02x partition=%s%s", pz->path, pz->flags, i, n, pz->disc->partition, s ? "" : " (nil)");
	if (i != PZ_MAGIC_1 || n != PZ_MAGIC_2 || s[2] == 0 || s[3] >= 10)
	{
		sfread(pz->io, s, 0);
		if (pz->flags & PZ_SPLIT)
			return 0;
		if (pz->flags & PZ_DISC)
		{
			pz->flags &= ~PZ_POP;
			return -1;
		}
		if (!(pz->flags & (PZ_READ|PZ_WRITE|PZ_STAT)) && (m = pz->prefix.count))
		{
			if (pz->prefix.terminator >= 0)
			{
				while (m-- > 0)
				{
					if (!sfgetr(pz->io, pz->prefix.terminator, 0))
					{
						if (pz->disc->errorf)
							(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix record%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
						return -1;
					}
				}
			}
			else if (!sfreserve(pz->io, m, 0))
			{
				if (pz->disc->errorf)
					(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix byte%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
				return -1;
			}
		}
		if (!(n = pz->row))
		{
			if ((pz->flags & PZ_ACCEPT) || !sfsize(pz->io))
				n = 1;
			else if ((n = pzfixed(pz, pz->io, NiL, 0)) <= 0 && pz->disc->partition)
			{
				pz->flags |= PZ_ROWONLY;
				if (!pzpartition(pz, pz->disc->partition))
					n = pz->row;
				pz->flags &= ~PZ_ROWONLY;
			}
		}
		if (n <= 0)
		{
			if (!(pz->flags & PZ_DELAY) && (pz->disc->partition || !(pz->flags & PZ_FORCE)))
			{
				if (pz->disc->errorf)
					(*pz->disc->errorf)(pz, pz->disc, 2, "%s: unknown input format", pz->path);
				return -1;
			}
			pz->flags |= PZ_UNKNOWN;
			n = 1;
		}
		if (!(pp = vmnewof(pz->vm, 0, Pzpart_t, 1, 0)))
			return -1;
		pz->major = PZ_MAJOR;
		pz->minor = PZ_MINOR;
		pp->name = "";
		pp->row = n;
		return pzpartinit(pz, pp, NiL);
	}
	sfread(pz->io, s, 2);
	pz->flags &= ~PZ_FORCE;
	pz->major = sfgetc(pz->io);
	pz->minor = sfgetc(pz->io);
	switch (pz->major)
	{
	case 1:
		if (pz->minor <= 2)
			goto noway;
		break;
	case 2:
		pz->win = sfgetu(pz->io);
		break;
	default:
		goto noway;
	}
	pz->flags |= PZ_HEAD;
	return pzpartread(pz);
 noway:
	if (pz->disc->errorf)
		(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data %d.%d not supported by implementation %d.%d", pz->path, pz->major, pz->minor, PZ_MAJOR, PZ_MINOR);
	return -1;
}
예제 #24
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);
}
예제 #25
0
파일: tpoll.c 프로젝트: ISLEcode/kornshell
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);
}
예제 #26
0
static void
flatten(const char* path, Sfio_t* ip, Sfio_t* op)
{
	register int	c;
	register int	q;
	register int	p;
	register int	b;
	register char*	s;

	char		tag[256];

	b = p = 0;
	for (;;)
	{
		switch (c = sfgetc(ip))
		{
		case EOF:
			break;
		case '<':
			q = 0;
			s = tag;
			for (;;)
			{
				switch (c = sfgetc(ip))
				{
				case EOF:
					return;
				case '>':
					sfungetc(ip, c);
					break;
				default:
					if (isspace(c))
						break;
					if (s < &tag[sizeof(tag)-1])
						*s++ = islower(c) ? toupper(c) : c;
					continue;
				}
				break;
			}
			*s = 0;
			q = 0;
			for (;;)
			{
				switch (c = sfgetc(ip))
				{
				case EOF:
					return;
				case '\'':
				case '"':
					if (q == c)
						q = 0;
					else if (q == 0)
						q = c;
					continue;
				case '>':
					if (q == 0)
						break;
					continue;
				default:
					continue;
				}
				break;
			}
			s = tag;
			if (s[0] == 'T' && s[1] == 'D' && s[2] == 0)
				p = 1;
			else if (s[0] == '/' && s[1] == 'T')
			{
				if (s[2] == 'D' && s[3] == 0)
				{
					b = p = 0;
					sfputc(op, ';');
				}
				else if (s[2] == 'R' && s[3] == 0)
					sfputc(op, '\n');
			}
			continue;
		default:
			if (p)
			{
				if (isspace(c))
				{
					if (b)
						continue;
					b = 1;
					c = ' ';
				}
				else
					b = 0;
				sfputc(op, c);
			}
			continue;
		}
		break;
	}
}
예제 #27
0
파일: tflags.c 프로젝트: gwowen/seismicunix
MAIN()
{
	Sfio_t*	f;

	if(!(f = sfopen(NIL(Sfio_t*),"ab","sr")) )
		terror("Can't open stream\n");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet\n");
	if(sfgetc(f) != 'a')
		terror("Got wrong data\n");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet2\n");
	if(sfgetc(f) != 'b')
		terror("Got wrong data2\n");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet3\n");
	if(sfgetc(f) >= 0)
		terror("Got wrong data2\n");
	if(!sfeof(f))
		terror("Should be eof now\n");
	if(sfseek(f,(Sfoff_t)(-1),2) != 1)
		terror("Seek error\n");
	if(sfeof(f))
		terror("Shouldn't be eof any more\n");

	if(!(f = sfopen(NIL(Sfio_t*), tstfile(0), "w+")) )
		terror("Can't open stream2\n");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet2\n");
	if(sfwrite(f,"ab",2) != 2)
		terror("Can't write data\n");
	if(sfseek(f,(Sfoff_t)0,0) != 0)
		terror("Can't seek back\n");
	if(sfgetc(f) != 'a')
		terror("Got wrong data3\n");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet4\n");
	if(sfgetc(f) != 'b')
		terror("Got wrong data4\n");
	if(sfeof(f) || sferror(f))
		terror("Can't be eof or error yet5\n");
	if(sfgetc(f) >= 0)
		terror("Got wrong data5\n");
	if(!sfeof(f))
		terror("Should be eof now2\n");
	if(sfseek(f,(Sfoff_t)(-1),2) != 1)
		terror("Seek error2\n");
	if(sfeof(f))
		terror("Shouldn't be eof any more2\n");

	if(!(f = sfopen(NIL(Sfio_t*), tstfile(0),"w+")) )
		terror("Reopening %s\n", tstfile(0));
	sfwrite(f,"1234567890",10);
	sfseek(f,(Sfoff_t)0,0);

	if(sfopen(sfstdout, tstfile(1), "w") != sfstdout)
		terror("Opening %s\n", tstfile(1));

	if(sfmove(f,sfstdout,(Sfoff_t)(-1),-1) != 10)
		terror("sfmove failed\n");
	if(!sfeof(f))
		terror("f should be eof\n");
	if(sferror(sfstdout))
		terror("sfstdout should not be in error\n");

	TSTEXIT(0);
}
예제 #28
0
int
pzinflate(register Pz_t* pz, Sfio_t* op)
{
	register Pzpart_t*	pp;
	register int		i;
	register int		j;
	register int		k;
	register size_t		n;
	register size_t		m;
	register unsigned char*	pat;
	ssize_t			r;
	Pzwrite_f		writef;

	if (!(pz->flags & PZ_READ))
	{
		if (pz->disc->errorf)
			(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: cannot inflate -- not open for read", pz->path);
		return -1;
	}
	if (pz->flags & PZ_SPLIT)
		return pzssplit(pz);
	if (pz->flags & PZ_FORCE)
	{
		if (writef = pz->disc->writef)
		{
			n = pz->part->row;
			do
			{
				if (!(pat = (unsigned char*)sfreserve(pz->io, n, 0)))
				{
					if (sfvalue(pz->io))
					{
						if (pz->disc->errorf)
							(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data corrupted", pz->path);
						return -1;
					}
					break;
				}
			} while ((r = (*writef)(pz, op, pat, pz->disc)) >= 0);
			if (r < 0)
				return -1;
		}
		else if (sfmove(pz->io, op, SF_UNBOUND, -1) < 0 || sferror(pz->io))
		{
			if (pz->disc->errorf)
				(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data corrupted", pz->path);
			return -1;
		}
		if (sfsync(op))
		{
			if (pz->disc->errorf)
				(*pz->disc->errorf)(pz, pz->disc, 2, "%s: output write error", pz->path);
			return -1;
		}
		return 0;
	}

	/*
	 * copy the prefix
	 */

	if (pz->prefix.count)
	{
		if (!pz->prefix.skip && pz->prefix.data && sfwrite(op, pz->prefix.data, pz->prefix.count) != pz->prefix.count)
		{
			if (pz->disc->errorf)
				(*pz->disc->errorf)(pz, pz->disc, 2, "%s: output write error", pz->path);
			return -1;
		}
		pz->prefix.count = 0;
	}
	if ((pz->split.flags & (PZ_SPLIT_INFLATE|PZ_SPLIT_PART)) == PZ_SPLIT_INFLATE)
		i = pzsinflate(pz, op);
	else
	{
		/*
		 * inflate each file
		 */

		do
		{
			/*
			 * inflate each window
			 */

			pp = pz->part;
			pat = pz->pat;
			while (m = sfgetu(pz->io))
			{
				/*
				 * hi frequency data in pz->buf
				 */

				if (pp->nmap)
				{
					if (m > pz->win || (m % pp->nmap) || sfread(pz->io, pz->buf, m) != m)
					{
						if (pz->disc->errorf)
							(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
						return -1;
					}
					n = m / pp->nmap;
					m = 0;
					j = 0;
					k = 0;
					for (i = 0; i < pp->nmap; i++)
					{
						if (i > 0 && pp->lab[i] == pp->lab[i - 1])
							j++;
						else
							j = m;
						if (!pp->value || pp->value[i] < 0)
							pp->mix[k++] = pz->buf + j;
						m += n;
					}
				}
				else if (m != 1)
				{
					if (pz->disc->errorf)
						(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
					return -1;
				}

				/*
				 * lo frequency
				 */

				m = sfgetu(pz->io);
				if (m < pp->row || sfread(pz->io, pat, pp->row) != pp->row)
				{
					if (pz->disc->errorf)
						(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
					return -1;
				}
				m -= pp->row;
				if (sfread(pz->io, pz->nxt = pz->val, m) != m)
				{
					if (pz->disc->errorf)
						(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: data corrupted", pz->path);
					return -1;
				}

				/*
				 * restore lo+hi on op
				 */

				if (restore(pz, pp, pz->io, op, pat, pz->wrk, pp->row, k, pp->map, pp->mix, pp->inc))
					return -1;
			}
			if (!(pz->flags & PZ_SECTION))
			{
				if ((k = sfgetc(pz->io)) == PZ_MARK_PART)
				{
					if ((m = sfgetu(pz->io)) && !sferror(pz->io) && !sfeof(pz->io) && (pat = (unsigned char*)sfreserve(pz->io, m, 0)))
						sfwrite(op, pat, m);
				}
				else if (k != EOF)
					sfungetc(pz->io, k);
			}
			if (sferror(op))
			{
				if (pz->disc->errorf)
					(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "write error");
				return -1;
			}
		} while ((i = !(pz->flags & PZ_SECTION)) && (i = pzfile(pz)) > 0);
	}
	if (i >= 0 && !(pz->split.flags & PZ_SPLIT_PART) && sfsync(op))
	{
		if (pz->disc->errorf)
			(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "write error");
		return -1;
	}
	return i;
}