コード例 #1
0
ファイル: getpass.c プロジェクト: nathanmkaya/ksh-arch
extern char*	getpass(const char *prompt)
{
	struct termios told,tnew;
	Sfio_t *iop;
	static char *cp, passwd[32];
	void (*savesig)(int);
	if(!(iop = sfopen((Sfio_t*)0, "/dev/tty", "r")))
		return(0);
	if(tcgetattr(sffileno(iop),&told) < 0)
		return(0);
	interrupt = 0;
	tnew = told;
	tnew.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL);
	if(tcsetattr(sffileno(iop),TCSANOW,&tnew) < 0)
		return(0);
	savesig = signal(SIGINT, handler);
	sfputr(sfstderr,prompt,-1);
	if(cp = sfgetr(iop,'\n',1))
		strncpy(passwd,cp,sizeof(passwd)-1);
	tcsetattr(sffileno(iop),TCSANOW,&told);
	sfputc(sfstderr,'\n');
	sfclose(iop);
	signal(SIGINT, savesig);
	if(interrupt)
		kill(getpid(),SIGINT);
	return(cp?passwd:0);
}
コード例 #2
0
ファイル: fcin.c プロジェクト: att/ast
//
// Open stream <f> for fast character input.
//
int fcfopen(Sfio_t *f) {
    int n;
    char *buff;
    Fcin_t save;

    errno = 0;
    _Fcin.fcbuff = _Fcin.fcptr;
    _Fcin._fcfile = f;
    fcsave(&save);
    if (!(buff = (char *)sfreserve(f, SF_UNBOUND, SF_LOCKR))) {
        fcrestore(&save);
        _Fcin.fcchar = 0;
        _Fcin.fcptr = _Fcin.fcbuff = &_Fcin.fcchar;
        _Fcin.fclast = NULL;
        _Fcin._fcfile = NULL;
        return EOF;
    }
    n = sfvalue(f);
    fcrestore(&save);
    sfread(f, buff, 0);
    _Fcin.fcoff = sftell(f);
    buff = (char *)sfreserve(f, SF_UNBOUND, SF_LOCKR);
    _Fcin.fclast = (_Fcin.fcptr = _Fcin.fcbuff = (unsigned char *)buff) + n;
    if (sffileno(f) >= 0) *_Fcin.fclast = 0;
    return n;
}
コード例 #3
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);
}
コード例 #4
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);
}
コード例 #5
0
ファイル: thole.c プロジェクト: xosevp/zmailer
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;
}
コード例 #6
0
ファイル: history.c プロジェクト: att/ast
static int hist_exceptf(Sfio_t *fp, int type, Sfdisc_t *handle)
#endif
{
    UNUSED(data);
    History_t *hp = (History_t *)handle;

    if (type == SF_WRITE) {
        if (errno == ENOSPC || hp->histwfail++ >= 10) return 0;
        // Write failure could be NFS problem, try to re-open.
        int newfd = open(hp->histname, O_BINARY | O_APPEND | O_CREAT | O_RDWR | O_CLOEXEC,
                         S_IRUSR | S_IWUSR);
        int oldfd = sffileno(fp);
        sh_close(oldfd);
        if (newfd == -1) goto fail;

        if (sh_fcntl(newfd, F_DUPFD_CLOEXEC, oldfd) != oldfd) {
            close(newfd);
            goto fail;
        }

        (void)fcntl(oldfd, F_SETFD, FD_CLOEXEC);

        close(newfd);
        if (lseek(oldfd, 0, SEEK_END) < hp->histcnt) {
            int index = hp->histind;
            // The return value of this lseek() has historically been ignored. It is unclear if that
            // is correct. That is, is there any scenario in which this lseek() could fail but the
            // overall behavior of the shell still be correct if we ignore that failure? The void
            // cast is to silence Coverity CID #253581.
            (void)lseek(oldfd, 2, SEEK_SET);
            hp->histcnt = 2;
            hp->histind = 1;
            hp->histcmds[1] = 2;
            hist_eof(hp);
            hp->histmarker = hp->histcnt;
            hp->histind = index;
        }
        return 1;
    }
    return 0;

fail:
    errormsg(SH_DICT, 2, "History file write error-%d %s: file unrecoverable", errno, hp->histname);
    return -1;
}
コード例 #7
0
ファイル: tee.c プロジェクト: mikess/illumos-gate
static ssize_t
tee_write(Sfio_t* fp, const void* buf, size_t n, Sfdisc_t* handle)
{
    register const char*	bp;
    register const char*	ep;
    register int*		hp = ((Tee_t*)handle)->fd;
    register int		fd = sffileno(fp);
    register ssize_t	r;

    do
    {
        bp = (const char*)buf;
        ep = bp + n;
        while (bp < ep)
        {
            if ((r = write(fd, bp, ep - bp)) <= 0)
                return -1;
            bp += r;
        }
    } while ((fd = *hp++) >= 0);
    return n;
}
コード例 #8
0
ファイル: history.c プロジェクト: ISLEcode/kornshell
static History_t* hist_trim(History_t *hp, int n)
{
	register char *cp;
	register int incmd=1, c=0;
	register History_t *hist_new, *hist_old = hp;
	char *buff, *endbuff, *tmpname=0;
	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;
		close(sffileno(hist_old->histfp));
		tmpname = (char*)malloc(strlen(name)+14);
		if(last = strrchr(name,'/'))
		{
			*last = 0;
			pathtmp(tmpname,name,"hist",NIL(int*));
			*last = '/';
		}
コード例 #9
0
ファイル: path.c プロジェクト: nathanmkaya/ksh-arch
static pid_t _spawnveg(Shell_t *shp,const char *path, char* const argv[], char* const envp[], pid_t pgid)
{
	pid_t pid;
#ifdef SIGTSTP
	if(job.jobcontrol)
	{
		signal(SIGTTIN,SIG_DFL);
		signal(SIGTTOU,SIG_DFL);
	}
#endif /* SIGTSTP */

	while(1)
	{
		sh_stats(STAT_SPAWN);
#ifdef SPAWN_cwd
		{
			char *arg0 = argv[0], **av0= (char**)&argv[0];
			int fd;
			pid = spawnvex(path,argv,envp,shp->vex);
			*av0 = arg0;
			if(pid>0 && shp->comsub && (fd=sffileno(sfstdout))!=1 && fd>=0)
				spawnvex_add(shp->vex, fd, 1,0,0);
		}
#else
		pid = spawnveg(path,argv,envp,pgid);
#endif /* SPAWN_cwd */
		if(pid>=0 || errno!=EAGAIN)
			break;
	}
#ifdef SIGTSTP
	if(job.jobcontrol)
	{
		signal(SIGTTIN,SIG_IGN);
		signal(SIGTTOU,SIG_IGN);
	}
#endif /* SIGTSTP */
	return(pid);
}
コード例 #10
0
ファイル: edit.c プロジェクト: ISLEcode/kornshell
void	ed_setup(register Edit_t *ep, int fd, int reedit)
{
	Shell_t *shp = ep->sh;
	register char *pp;
	register char *last, *prev;
	char *ppmax;
	int myquote = 0, n;
	register int qlen = 1, qwid;
	char inquote = 0;
	ep->e_fd = fd;
	ep->e_multiline = sh_isoption(SH_MULTILINE)!=0;
#ifdef SIGWINCH
	if(!(shp->sigflag[SIGWINCH]&SH_SIGFAULT))
	{
		signal(SIGWINCH,sh_fault);
		shp->sigflag[SIGWINCH] |= SH_SIGFAULT;
	}
	pp = shp->st.trapcom[SIGWINCH];
	shp->st.trapcom[SIGWINCH] = 0;
	sh_fault(SIGWINCH);
	shp->st.trapcom[SIGWINCH] = pp;
	ep->sh->winch = 0;
#endif
#if SHOPT_EDPREDICT
	ep->hlist = 0;
	ep->nhlist = 0;
	ep->hoff = 0;
#endif /* SHOPT_EDPREDICT */
#if KSHELL
	ep->e_stkptr = stakptr(0);
	ep->e_stkoff = staktell();
	if(!(last = shp->prompt))
		last = "";
	shp->prompt = 0;
#else
	last = ep->e_prbuff;
#endif /* KSHELL */
	if(shp->gd->hist_ptr)
	{
		register History_t *hp = shp->gd->hist_ptr;
		ep->e_hismax = hist_max(hp);
		ep->e_hismin = hist_min(hp);
	}
	else
	{
		ep->e_hismax = ep->e_hismin = ep->e_hloff = 0;
	}
	ep->e_hline = ep->e_hismax;
	if(!sh_isoption(SH_VI) && !sh_isoption(SH_EMACS) && !sh_isoption(SH_GMACS))
		ep->e_wsize = MAXLINE;
	else
		ep->e_wsize = ed_window()-2;
	ep->e_winsz = ep->e_wsize+2;
	ep->e_crlf = 1;
	ep->e_plen = 0;
	pp = ep->e_prompt;
	ppmax = pp+PRSIZE-1;
	*pp++ = '\r';
	{
		register int c;
		while(prev = last, c = mbchar(last)) switch(c)
		{
			case ESC:
			{
				int skip=0;
				ep->e_crlf = 0;
				*pp++ = c;
				for(n=1; c = *last++; n++)
				{
					if(pp < ppmax)
						*pp++ = c;
					if(c=='\a' || c==ESC || c=='\r')
						break;
					if(skip || (c>='0' && c<='9'))
					{
						skip = 0;
						continue;
					}
					if(n>1 && c==';')
						skip = 1;
					else if(n>2 || (c!= '[' &&  c!= ']'))
						break;
				}
				if(c==0 || c==ESC || c=='\r')
					last--;
				qlen += (n+1);
				break;
			}
			case '\b':
				if(pp>ep->e_prompt+1)
					pp--;
				break;
			case '\r':
				if(pp == (ep->e_prompt+2)) /* quote char */
					myquote = *(pp-1);
				/*FALLTHROUGH*/

			case '\n':
				/* start again */
				ep->e_crlf = 1;
				qlen = 1;
				inquote = 0;
				pp = ep->e_prompt+1;
				break;

			case '\t':
				/* expand tabs */
				while((pp-ep->e_prompt)%TABSIZE)
				{
					if(pp >= ppmax)
						break;
					*pp++ = ' ';
				}
				break;

			case '\a':
				/* cut out bells */
				break;

			default:
				if(c==myquote)
				{
					qlen += inquote;
					inquote ^= 1;
				}
				if(pp < ppmax)
				{
					if(inquote)
						qlen++;
					else if(!is_print(c))
						ep->e_crlf = 0;
					if((qwid = last - prev) > 1)
						qlen += qwid - mbwidth(c);
					while(prev < last && pp < ppmax)
						*pp++ = *prev++;
				}
				break;
		}
	}
	if(pp-ep->e_prompt > qlen)
		ep->e_plen = pp - ep->e_prompt - qlen;
	*pp = 0;
	if(!ep->e_multiline && (ep->e_wsize -= ep->e_plen) < 7)
	{
		register int shift = 7-ep->e_wsize;
		ep->e_wsize = 7;
		pp = ep->e_prompt+1;
		strcpy(pp,pp+shift);
		ep->e_plen -= shift;
		last[-ep->e_plen-2] = '\r';
	}
	sfsync(sfstderr);
	if(fd == sffileno(sfstderr))
	{
		/* can't use output buffer when reading from stderr */
		static char *buff;
		if(!buff)
			buff = (char*)malloc(MAXLINE);
		ep->e_outbase = ep->e_outptr = buff;
		ep->e_outlast = ep->e_outptr + MAXLINE;
		return;
	}
	qlen = sfset(sfstderr,SF_READ,0);
	/* make sure SF_READ not on */
	ep->e_outbase = ep->e_outptr = (char*)sfreserve(sfstderr,SF_UNBOUND,SF_LOCKR);
	ep->e_outlast = ep->e_outptr + sfvalue(sfstderr);
	if(qlen)
		sfset(sfstderr,SF_READ,1);
	sfwrite(sfstderr,ep->e_outptr,0);
	ep->e_eol = reedit;
	if(ep->e_multiline)
	{
#ifdef _cmd_tput
		char *term;
		if(!ep->e_term)
			ep->e_term = nv_search("TERM",shp->var_tree,0);
		if(ep->e_term && (term=nv_getval(ep->e_term)) && strlen(term)<sizeof(ep->e_termname) && strcmp(term,ep->e_termname))
		{
			sh_trap(".sh.subscript=$(tput cuu1 2>/dev/null)",0);
			if(pp=nv_getval(SH_SUBSCRNOD))
				strncpy(CURSOR_UP,pp,sizeof(CURSOR_UP)-1);
			nv_unset(SH_SUBSCRNOD);
			strcpy(ep->e_termname,term);
		}
#endif
		ep->e_wsize = MAXLINE - (ep->e_plen+1);
	}
	if(ep->e_default && (pp = nv_getval(ep->e_default)))
	{
		n = strlen(pp);
		if(n > LOOKAHEAD)
			n = LOOKAHEAD;
		ep->e_lookahead = n;
		while(n-- > 0)
			ep->e_lbuf[n] = *pp++;
		ep->e_default = 0;
	}
}
コード例 #11
0
ファイル: nocrnl.c プロジェクト: braincat/uwin
main(int argc, char *argv[])
{
	register int n;
	register char *cp;
	Sfio_t *in, *out;

	error_info.id = argv[0];
	NoP(id[0]);
#if _AST_VERSION >= 20060701L
	cmdinit(argc, argv,0, NULL, 0);
#else
	cmdinit(argv,0, NULL, 0);
#endif
	while (n = optget(argv, " [file ...]")) switch (n)
	{
	    case ':':
		error(2, opt_info.arg);
		break;
	    case '?':
		error(ERROR_usage(2), opt_info.arg);
		break;
	}
	argv += opt_info.index;
	if(error_info.errors)
		error(ERROR_usage(2),optusage((char*)0));
	if(cp = *argv)
		argv++;
	do
	{
                if(!cp || strcmp(cp,"-")==0)
		{
                        in = sfstdin;
			out = sfstdout;
		}
		else
		{
			if(!(in = sfopen((Sfio_t*)0,cp,"rb")))
			{
				error(ERROR_system(0),"%s: cannot open for input",cp);
				error_info.errors = 1;
				continue;
			}

			if(!(out = sfopen((Sfio_t*)0,cp,"r+b")))
			{
				error(ERROR_system(0),"%s: cannot open for writing",cp);
				error_info.errors = 1;
				continue;
			}
		}
		nocrnl(in,out);
		if(in!=sfstdin)
			sfclose(in);
		if(out!=sfstdout)
		{
			sfsync(out);
			ftruncate(sffileno(out),sftell(out));
			sfclose(out);
		}
	}
	while(cp= *argv++);
	return(error_info.errors);
}
コード例 #12
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*/
}
コード例 #13
0
ファイル: subshell.c プロジェクト: apprisi/illumos-gate
/*
 * 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;
	}
}
コード例 #14
0
ファイル: shcomp.c プロジェクト: ISLEcode/kornshell
int main(int argc, char *argv[])
{
	Sfio_t *in, *out;
	Shell_t	*shp;
	Namval_t *np;
	Shnode_t *t;
	char *cp;
	int n, nflag=0, vflag=0, dflag=0;
	error_info.id = argv[0];
	while(n = optget(argv, usage )) switch(n)
	{
	    case 'D':
		dflag=1;
		break;
	    case 'v':
		vflag=1;
		break;
	    case 'n':
		nflag=1;
		break;
	    case ':':
		errormsg(SH_DICT,2,"%s",opt_info.arg);
		break;
	    case '?':
		errormsg(SH_DICT,ERROR_usage(2),"%s",opt_info.arg);
		break;
	}
	shp = sh_init(argc,argv,(Shinit_f)0);
	shp->shcomp = 1;
	argv += opt_info.index;
	argc -= opt_info.index;
	if(error_info.errors || argc>2)
		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
	if(cp= *argv)
	{
		argv++;
		in = sh_pathopen(cp);
	}
	else
		in = sfstdin;
	if(cp= *argv)
	{
		struct stat statb;
		if(!(out = sfopen((Sfio_t*)0,cp,"w")))
			errormsg(SH_DICT,ERROR_system(1),"%s: cannot create",cp);
		if(fstat(sffileno(out),&statb) >=0)
			chmod(cp,(statb.st_mode&~S_IFMT)|S_IXUSR|S_IXGRP|S_IXOTH);
	}
	else
		out = sfstdout;
	if(dflag)
	{
		sh_onoption(SH_DICTIONARY);
		sh_onoption(SH_NOEXEC);
	}
	if(nflag)
		sh_onoption(SH_NOEXEC);
	if(vflag)
		sh_onoption(SH_VERBOSE);
	if(!dflag)
		sfwrite(out,header,sizeof(header));
	shp->inlineno = 1;
#if SHOPT_BRACEPAT
        sh_onoption(SH_BRACEEXPAND);
#endif
	while(1)
	{
		stakset((char*)0,0);
		if(t = (Shnode_t*)sh_parse(shp,in,0))
		{
			if((t->tre.tretyp&(COMMSK|COMSCAN))==0 && t->com.comnamp && strcmp(nv_name((Namval_t*)t->com.comnamp),"alias")==0)
				sh_exec(t,0);
			if(!dflag && sh_tdump(out,t) < 0)
				errormsg(SH_DICT,ERROR_exit(1),"dump failed");
		}
		else if(sfeof(in))
			break;
		if(sferror(in))
			errormsg(SH_DICT,ERROR_system(1),"I/O error");
		if(t && ((t->tre.tretyp&COMMSK)==TCOM) && (np=t->com.comnamp) && (cp=nv_name(np)))
		{
			if(strcmp(cp,"exit")==0)
				break;
			/* check for exec of a command */
			if(strcmp(cp,"exec")==0)
			{
				if(t->com.comtyp&COMSCAN)
				{
					if(t->com.comarg->argnxt.ap)
						break;
				}
				else
				{
					struct dolnod *ap = (struct dolnod*)t->com.comarg;
					if(ap->dolnum>1)
						break;
				}
			}
		}
	}
	/* copy any remaining input */
	sfmove(in,out,SF_UNBOUND,-1);
	if(in!=sfstdin)
		sfclose(in);
	if(out!=sfstdout)
		sfclose(out);
	return(0);
}
コード例 #15
0
ファイル: history.c プロジェクト: att/ast
static int hist_write(Sfio_t *iop, const void *buff, int insize, Sfdisc_t *handle)
#endif
{
    History_t *hp = (History_t *)handle;
    char *bufptr = ((char *)buff) + insize;
    int c, size = insize;
    off_t cur;
    Shell_t *shp = hp->histshell;
    int saved = 0;
    char saveptr[HIST_MARKSZ];

    if (!hp->histflush) return write(sffileno(iop), (char *)buff, size);
    if ((cur = lseek(sffileno(iop), (off_t)0, SEEK_END)) < 0) {
        errormsg(SH_DICT, 2, "hist_flush: EOF seek failed errno=%d", errno);
        return -1;
    }
    hp->histcnt = cur;
    // Remove whitespace from end of commands.
    while (--bufptr >= (char *)buff) {
        c = *bufptr;
        if (!isspace(c)) {
            if (c == '\\' && *(bufptr + 1) != '\n') bufptr++;
            break;
        }
    }
    // Don't count empty lines.
    if (++bufptr <= (char *)buff) return insize;
    *bufptr++ = '\n';
    *bufptr++ = 0;
    size = bufptr - (char *)buff;
    if (hp->auditfp) {
        time_t t = time(NULL);
        sfprintf(hp->auditfp, "%u;%u;%s;%*s%c",
                 sh_isoption(shp, SH_PRIVILEGED) ? shgd->euserid : shgd->userid, t, hp->tty, size,
                 buff, 0);
        sfsync(hp->auditfp);
    }
    if (size & 01) {
        size++;
        *bufptr++ = 0;
    }
    hp->histcnt += size;
    c = hist_ind(hp, ++hp->histind);
    hp->histcmds[c] = hp->histcnt;
    if (hp->histflush > HIST_MARKSZ && hp->histcnt > hp->histmarker + HIST_BSIZE / 2) {
        memcpy(saveptr, bufptr, HIST_MARKSZ);
        saved = 1;
        hp->histcnt += HIST_MARKSZ;
        hist_marker(bufptr, hp->histind);
        hp->histmarker = hp->histcmds[hist_ind(hp, c)] = hp->histcnt;
        size += HIST_MARKSZ;
    }
    errno = 0;
    size = write(sffileno(iop), (char *)buff, size);
    if (saved) memcpy(bufptr, saveptr, HIST_MARKSZ);
    if (size >= 0) {
        hp->histwfail = 0;
        return insize;
    }
    return -1;
}
コード例 #16
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);
}
コード例 #17
0
ファイル: dssfile.c プロジェクト: nathanmkaya/ksh-arch
Dssfile_t*
dssfopen(Dss_t* dss, const char* path, Sfio_t* io, Dssflags_t flags, Dssformat_t* format)
{
	Dssfile_t*	file;
	Vmalloc_t*	vm;
	char*		s;
	size_t		n;
	int		i;
	struct stat	st;
	Sfdisc_t	top;
	char		buf[PATH_MAX];

	if (flags & DSS_FILE_WRITE)
	{
		if (io)
		{
			memset(&top, 0, sizeof(top));
			if (sfdisc(io, &top))
			{
				n = top.disc == &dss->state->compress_preferred;
				sfdisc(io, SF_POPDISC);
				if (n)
				{
					sfdisc(io, SF_POPDISC);
					sfdczip(io, path, dss->meth->compress ? dss->meth->compress : "gzip", dss->disc->errorf);
				}
			}
		}
		if (dss->flags & DSS_APPEND)
			flags |= DSS_FILE_APPEND;
	}
	if (!path || !*path || streq(path, "-"))
	{
		if (flags & DSS_FILE_WRITE)
		{
			if (io)
				path = "output-stream";
			else
			{
				path = "/dev/stdout";
				io = sfstdout;
			}
		}
		else if (io)
			path = "input-stream";
		else
		{
			path = "/dev/stdin";
			io = sfstdin;
		}
		flags |= DSS_FILE_KEEP;
	}
	else if (io)
		flags |= DSS_FILE_KEEP;
	else if (flags & DSS_FILE_WRITE)
	{
		if (!(io = sfopen(NiL, path, (flags & DSS_FILE_APPEND) ? "a" : "w")))
		{
			if (dss->disc->errorf)
				(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: cannot open", path);
			return 0;
		}
	}
	else if (!(io = dssfind(path, "", DSS_VERBOSE, buf, sizeof(buf), dss->disc)))
		return 0;
	else
		path = (const char*)buf;
	if (!(vm = vmopen(Vmdcheap, Vmbest, 0)))
	{
		if (dss->disc->errorf)
			(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space");
		return 0;
	}
	if (!(file = vmnewof(vm, 0, Dssfile_t, 1, strlen(path) + 1)))
	{
		if (dss->disc->errorf)
			(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space");
		if (!(flags & DSS_FILE_KEEP))
			sfclose(io);
		vmclose(vm);
		return 0;
	}
	strcpy(file->path = (char*)(file + 1), path);
	file->dss = dss;
	file->vm = vm;
	file->io = io;
	file->flags = flags;
	if (flags & DSS_FILE_WRITE)
	{
		if (!(file->format = format) && !(file->format = dss->format))
		{
			if (dss->disc->errorf)
				(*dss->disc->errorf)(NiL, dss->disc, 2, "output method format must be specified");
			if (!(flags & DSS_FILE_KEEP))
				sfclose(io);
			return 0;
		}
		file->readf = noreadf;
		file->writef = file->format->writef;
	}
	else
	{
		if (sfsize(file->io) || !fstat(sffileno(file->io), &st) && (S_ISFIFO(st.st_mode)
#ifdef S_ISSOCK
			|| S_ISSOCK(st.st_mode)
#endif
			))
		{
			if (sfdczip(file->io, file->path, NiL, dss->disc->errorf) < 0)
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: inflate error", file->path);
				dssfclose(file);
				return 0;
			}
			s = sfreserve(file->io, SF_UNBOUND, SF_LOCKR);
			n = sfvalue(file->io);
			if (!s)
			{
				if (n && dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: cannot peek", file->path);
				dssfclose(file);
				return 0;
			}
			for (file->format = (Dssformat_t*)dtfirst(dss->meth->formats); file->format && !(i = (*file->format->identf)(file, s, n, dss->disc)); file->format = (Dssformat_t*)dtnext(dss->meth->formats, file->format));
			sfread(file->io, s, 0);
			if (!file->format)
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: unknown %s format", file->path, dss->meth->name);
				dssfclose(file);
				return 0;
			}
			if (i < 0)
				return 0;
			if (format && format != file->format)
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %s file format %s incompatible with %s", file->path, dss->meth->name, file->format->name, format->name);
				dssfclose(file);
				return 0;
			}
			if ((dss->flags & DSS_VERBOSE) && dss->disc->errorf)
				(*dss->disc->errorf)(dss, dss->disc, 1, "%s: %s method %s format", file->path, dss->meth->name, file->format->name);
			file->readf = file->format->readf;
		}
		else
		{
			file->format = format ? format : dss->format ? dss->format : (Dssformat_t*)dtfirst(dss->meth->formats);
			file->readf = nullreadf;
		}
		file->writef = nowritef;
		if (!dss->format)
			dss->format = file->format;
	}
	if (!file->format)
	{
		if (dss->disc->errorf)
			(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %s method did not set file format", file->path, dss->meth->name);
		dssfclose(file);
		return 0;
	}
	file->record.file = file;
	if ((*file->format->openf)(file, dss->disc))
	{
		dssfclose(file);
		return 0;
	}
	return file;
}
コード例 #18
0
ファイル: pack.c プロジェクト: DataIX/ast
int
main(int argc, register char *argv[])
{
	static char command[] = "pack";
	register Huff_t	*hp;
	register char	*infile,*outfile;
	Sfio_t		*fpin,*fpout;
	int		nfile=0, npack=0, force=0, verbose=0;
	int		out, deleted, dsize, n;
	struct stat	statb;

	NOT_USED(argc);
	error_info.id = command;
	while(n = optget(argv,usage)) switch(n)
	{
	case 'f':
		force++;
		break;
	case 'v':
		verbose = !verbose;
		break;
	case ':':
		error(2, opt_info.arg);
		break;
	case '?':
		error(ERROR_usage(2), "%s", opt_info.arg);
		break;
	}
	argv += opt_info.index;
	if(error_info.errors || !*argv)
		error(ERROR_usage(2), "%s", optusage((char*)0));

	while (infile = *argv++)
	{
		if(*infile == '-')
		{
			/* awful way to handle options, but preserves SVID */
			switch(infile[1])
			{
				case 'f':
					force++;
					continue;
				case 0:
					verbose = !verbose;
					continue;
			}
		}
		nfile++;
		fpin = fpout = (Sfio_t*)0;
		hp = (Huff_t*)0;
		deleted = 0;
		if(!(outfile = outname(infile)))
			continue;
		if (!(fpin=sfopen((Sfio_t*)0,infile,"r")))
			error(ERROR_system(0), "%s: cannot open", infile);
		else if(fstat(sffileno(fpin),&statb) < 0)
			error(ERROR_system(0), "%s: cannot stat", infile);
		else if(S_ISDIR(statb.st_mode))
			error(2, "%s: cannot pack a directory", infile);
		else if(statb.st_nlink > 1)
			error(2, "%s: has links", infile);
		else if(statb.st_size ==0)
			error(2, "%s: cannot pack a zero length file", infile);
		else if(access(outfile,F_OK) ==0)
			error(ERROR_system(0), "%s: already exists", outfile);
		else if(((out=open(outfile,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,PERM(statb.st_mode))) < 0) ||
			!(fpout = sfnew((Sfio_t*)0,(char*)0,SF_UNBOUND,out,SF_WRITE)))
			error(ERROR_system(0), "%s: cannot create", outfile);
		else if((deleted++,chmod(outfile,statb.st_mode)) < 0)
			error(ERROR_system(0), "%s: cannot change mode to %o",outfile,statb.st_mode);
		else
		{
			chown(outfile,statb.st_uid,statb.st_gid);
			if(!(hp = huffinit(fpin,(Sfoff_t)-1)))
				error(2, "%s: read error", infile);
			else if(sfseek(fpin,(Sfoff_t)0,0) < 0)
				error(ERROR_system(0),"%s: seek error", infile);
			else if((dsize = huffputhdr(hp,fpout)) < 0)
				error(2, "%s: write error", infile);
			else if(!force && block(huffisize(hp)) <= block(huffosize(hp)+dsize))
				error(2, "%s:no savings - file unchanged", infile);
			else if(huffencode(hp,fpin,fpout,SF_UNBOUND)<0)
				error(2, "%s: read error", infile);
			else
			{
				double diff;
				if(remove(infile) < 0)
					error(ERROR_system(0), "%s: cannot remove", infile);
				diff = huffisize(hp) - (dsize+huffosize(hp));
				sfprintf(sfstdout,"%s: %s : %.1f%% Compression\n",command,
					infile,(100*diff)/((double)huffisize(hp)));
				if(verbose)
					vprint(hp,dsize);
				npack++;
				deleted = 0;
			}
		}
		if(hp)
			huffend(hp);
		if(fpin)
			sfclose(fpin);
		if(fpout)
			sfclose(fpout);
		if(deleted)
			remove(outfile);
		if(outfile)
			free(outfile);
	}
	nfile -= npack;
	if(nfile > 125)
		nfile = 125;
	exit(nfile);
}
コード例 #19
0
ファイル: print.c プロジェクト: nathanmkaya/ksh-arch
int    b_print(int argc, char *argv[], Shbltin_t *context)
{
	register Sfio_t *outfile;
	register int exitval=0,n, fd = 1;
	register Shell_t *shp = context->shp;
	const char *options, *msg = e_file+4;
	char *format = 0, *fmttype=0;
	int sflag = 0, nflag=0, rflag=0, vflag=0;
	Namval_t *vname=0;
	Optdisc_t disc;
	disc.version = OPT_VERSION;
	disc.infof = infof;
	opt_info.disc = &disc;
	if(argc>0)
	{
		options = sh_optprint;
		nflag = rflag = 0;
		format = 0;
	}
	else
	{
		struct print *pp = (struct print*)context;
		shp = pp->sh;
		options = pp->options;
		if(argc==0)
		{
			nflag = pp->echon;
			rflag = pp->raw;
			argv++;
			goto skip;
		}
	}
	while((n = optget(argv,options))) switch(n)
	{
		case 'n':
			nflag++;
			break;
		case 'p':
			fd = shp->coutpipe;
			msg = e_query;
			break;
		case 'f':
			format = opt_info.arg;
			break;
		case 's':
			/* print to history file */
			if(!sh_histinit((void*)shp))
				errormsg(SH_DICT,ERROR_system(1),e_history);
			fd = sffileno(shp->gd->hist_ptr->histfp);
			sh_onstate(shp,SH_HISTORY);
			sflag++;
			break;
		case 'e':
			rflag = 0;
			break;
		case 'r':
			rflag = 1;
			break;
		case 'u':
			if(opt_info.arg[0]=='p' && opt_info.arg[1]==0)
			{
				fd = shp->coutpipe;
				msg = e_query;
				break;
			}
			fd = (int)strtol(opt_info.arg,&opt_info.arg,10);
			if(*opt_info.arg)
				fd = -1;
			else if(!sh_iovalidfd(shp,fd))
				fd = -1;
			else if(!(shp->inuse_bits&(1<<fd)) && (sh_inuse(shp,fd) || (shp->gd->hist_ptr && fd==sffileno(shp->gd->hist_ptr->histfp))))

				fd = -1;
			break;
		case 'j':
			fmttype = "json";
		case 'v':
			if(argc < 0)
			{
				if(!(vname = nv_open(opt_info.arg, shp->var_tree,NV_VARNAME|NV_NOARRAY)))
					errormsg(SH_DICT,2, "Cannot create variable %s", opt_info.arg);
			}
			else
				vflag='v';
			break;
		case 'C':
			vflag='C';
			break;
		case ':':
			/* The following is for backward compatibility */
#if OPT_VERSION >= 19990123
			if(strcmp(opt_info.name,"-R")==0)
#else
			if(strcmp(opt_info.option,"-R")==0)
#endif
			{
				rflag = 1;
				if(error_info.errors==0)
				{
					argv += opt_info.index+1;
					/* special case test for -Rn */
					if(strchr(argv[-1],'n'))
						nflag++;
					if(*argv && strcmp(*argv,"-n")==0)
					{

						nflag++;
						argv++;
					}
					goto skip2;
				}
			}
			else
				errormsg(SH_DICT,2, "%s", opt_info.arg);
			break;
		case '?':
			errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
			break;
	}
	argv += opt_info.index;
	if(error_info.errors || (argc<0 && !(format = *argv++)))
		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
	if(vflag && format)
		errormsg(SH_DICT,ERROR_usage(2),"-%c and -f are mutually exclusive",vflag);
skip:
	if(format)
		format = genformat(shp,format);
	/* handle special case of '-' operand for print */
	if(argc>0 && *argv && strcmp(*argv,"-")==0 && strcmp(argv[-1],"--"))
		argv++;
	if(vname)
	{
		if(!shp->strbuf2)
			shp->strbuf2 = sfstropen();
		outfile = shp->strbuf2;
		goto printv;
	}
skip2:
	if(fd < 0)
	{
		errno = EBADF;
		n = 0;
	}
	else if(!(n=shp->fdstatus[fd]))
		n = sh_iocheckfd(shp,fd,fd);
	if(!(n&IOWRITE))
	{
		/* don't print error message for stdout for compatibility */
		if(fd==1)
			return(1);
		errormsg(SH_DICT,ERROR_system(1),msg);
	}
	if(!(outfile=shp->sftable[fd]))
	{
		sh_onstate(shp,SH_NOTRACK);
		n = SF_WRITE|((n&IOREAD)?SF_READ:0);
		shp->sftable[fd] = outfile = sfnew(NIL(Sfio_t*),shp->outbuff,IOBSIZE,fd,n);
		sh_offstate(shp,SH_NOTRACK);
		sfpool(outfile,shp->outpool,SF_WRITE);
	}
コード例 #20
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);
}
コード例 #21
0
ファイル: sfdcpzip.c プロジェクト: nathanmkaya/ksh-arch
int
sfdcpzip(Sfio_t* sp, const char* path, unsigned long flags, Pzdisc_t* disc)
{
	Sfio_t*		io;
	Sfpzip_t*	pz;
	Pz_t*		oz;

	if (flags & PZ_HANDLE)
	{
		oz = (Pz_t*)sp;
		sp = oz->io;
	}
	else
		oz = 0;
	if (sfset(sp, 0, 0) & SF_WRITE)
	{
		if (flags & PZ_STAT)
			return -1;
	}
	else if (!(flags & PZ_FORCE))
	{
		unsigned char*	s;
		int		r;
		int		m1;
		int		m2;

		if (!(r = sfset(sp, 0, 0) & SF_SHARE))
			sfset(sp, SF_SHARE, 1);
		s = (unsigned char*)sfreserve(sp, PZ_GZ_MAGOFF + 2, 1);
		if (!r)
			sfset(sp, SF_SHARE, 0);
		if (!s)
			return -1;
		m1 = s[0];
		m2 = s[1];
		r = m1 == PZ_MAGIC_1 && m2 == PZ_MAGIC_2 && s[2] > 0 && s[3] < 10 ||
		    m1 == GZ_MAGIC_1 && m2 == GZ_MAGIC_2 &&
		    s[PZ_GZ_MAGOFF] == PZ_GZ_MAGIC_1 && s[PZ_GZ_MAGOFF+1] == PZ_GZ_MAGIC_2;
		sfread(sp, s, 0);
		if (flags & PZ_STAT)
			return r;
		if (!r)
		{
			if (!(flags & PZ_NOGZIP))
			{
				if (m1 == GZ_MAGIC_1)
				{
					if (m2 == GZ_MAGIC_2)
						r = sfdcgzip(sp, (flags & PZ_CRC) ? 0 : SFGZ_NOCRC);
					else if (m2 == LZ_MAGIC_2)
						r = sfdclzw(sp, 0);
				}
				else if (m1 == 'B' && m2 == 'Z' && s[2] == 'h' && s[3] >= '1' && s[3] <= '9')
					r = sfdcbzip(sp, 0);
			}
			return r;
		}
		sfsync(sp);
	}
	if (!(io = sfnew(NiL, NiL, SF_UNBOUND, sffileno(sp), (sfset(sp, 0, 0) & (SF_READ|SF_WRITE)))))
		return -1;
	if (!(pz = newof(0, Sfpzip_t, 1, 0)))
	{
		io->_file = -1;
		sfclose(io);
		return -1;
	}
	pz->disc.version = PZ_VERSION;
	flags &= ~(PZ_READ|PZ_WRITE|PZ_STAT|PZ_STREAM|PZ_INTERNAL);
	flags |= PZ_PUSHED|PZ_STREAM|((sfset(sp, 0, 0) & SF_READ) ? PZ_READ : PZ_WRITE);
	if (oz && (oz->flags & PZ_WRITE))
		flags |= PZ_DELAY;
	if (disc)
	{
		pz->disc.errorf = disc->errorf;
		pz->disc.window = disc->window;
		pz->disc.options = disc->options;
		pz->disc.partition = disc->partition;
		if (disc->splitf)
			flags |= PZ_ACCEPT;
	}
	if (!(pz->pz = pzopen(&pz->disc, (char*)io, flags)) || (sp->_file = open("/dev/null", 0)) < 0)
	{
		io->_file = -1;
		sfclose(io);
		free(pz);
		return -1;
	}
	if (path)
		pz->pz->path = path;
	pz->sfdisc.exceptf = sfpzexcept;
	if (flags & PZ_WRITE)
	{
		pz->sfdisc.writef = sfpzwrite;
		pz->io = io;
	}
	else
		pz->sfdisc.readf = sfpzread;
	sfset(sp, SF_SHARE|SF_PUBLIC, 0);
	if (sfdisc(sp, &pz->sfdisc) != &pz->sfdisc)
	{
		close(sp->_file);
		sp->_file = io->_file;
		sfseek(sp, sftell(io), SEEK_SET);
		io->_file = -1;
		pzclose(pz->pz);
		free(pz);
		return -1;
	}
	if (oz)
		oz->flags |= pz->pz->flags & PZ_INTERNAL;
	return 1;
}
コード例 #22
0
ファイル: tsize.c プロジェクト: att/ast
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    Sfio_t *f, *f2;
    char *s;
    int i, n;
    char buf[16 * 1024];

    if (!(f = sfopen(NULL, tstfile("sf", 0), "w+"))) terror("Can't open file");

    if (sfnputc(f, 'a', 1000) != 1000) terror("Writing");

    if (sfseek(f, (Sfoff_t)0, 0) != 0) terror("Seeking");

    if ((n = (int)sfsize(f)) != 1000) terror("Wrong size %d", n);

    if (!(f2 = sfnew(NULL, NULL, (size_t)SF_UNBOUND, sffileno(f), SF_WRITE))) {
        terror("Can't open stream");
    }

    if (sfseek(f2, (Sfoff_t)1999, 0) != (Sfoff_t)1999) terror("Seeking2");
    sfputc(f2, 'b');
    sfsync(f2);
    if ((n = (int)sfsize(f2)) != 2000) terror("Wrong size2 %d", n);

    if ((n = (int)sfsize(f)) != 1000) terror("Wrong size3 %d", n);

    sfputc(f, 'a');
    sfset(f, SF_SHARE, 1);
    if ((n = (int)sfsize(f)) != 2000) terror("Wrong size4 %d", n);

    if (!(f = sfopen(f, NULL, "srw"))) terror("Can't open string stream");

    sfwrite(f, "0123456789", 10);
    if (sfsize(f) != 10) terror("String size is wrong1");
    sfseek(f, (Sfoff_t)19, 0);
    if (sfsize(f) != 10) terror("String size is wrong2");
    sfputc(f, 'a');
    if (sfsize(f) != 20) terror("String size is wrong3");
    sfseek(f, (Sfoff_t)0, 0);
    if (sfsize(f) != 20) terror("String size is wrong4");
    sfseek(f, (Sfoff_t)0, 0);
    if (!(s = sfreserve(f, SF_UNBOUND, SF_LOCKR)) && sfvalue(f) != 20) {
        terror("String size is wrong5");
    }
    sfread(f, s, 5);
    if (sfsize(f) != 20) terror("String size is wrong6");
    sfwrite(f, "01234567890123456789", 20);
    if (sfsize(f) != 25) terror("String size is wrong7");

    strcpy(buf, "0123456789");
    if (!(f = sfopen(f, buf, "s+"))) terror("Can't open string stream2");
    if (sfset(f, 0, 0) & SF_MALLOC) terror("SF_MALLOC should not have been set");
    if (sfsize(f) != 10) terror("String size is wrong8");
    sfread(f, buf, 5);
    if ((n = (int)sfwrite(f, "0123456789", 10)) != 5) terror("Write wrong amount %d", n);
    if (sfsize(f) != 10) terror("String size is wrong9");

    if (!(f = sfopen(f, tstfile("sf", 0), "w"))) terror("Reopening file1");
    for (i = 0; i < 10000; ++i) {
        if (sfputc(f, '0' + (i % 10)) != '0' + (i % 10)) terror("sfputc failed");
    }

    if (!(f = sfopen(f, tstfile("sf", 0), "r+"))) terror("Reopening file2");
    if (sfsize(f) != 10000) terror("Bad size of file1");

    sfsetbuf(f, buf, 1024);
    for (i = 0; i < 20; ++i) {
        if (!sfreserve(f, 100, 0)) terror("Reserve failed");
    }

    s = buf + 1024;
    for (i = 0; i < 20; ++i) s[i] = '0' + i % 10;
    sfseek(f, (Sfoff_t)(10000 - 10), 0);
    if (sfwrite(f, s, 20) != 20) terror("Write failed");
    if (sfsize(f) != 10010) terror("Bad size of file2");
    sfseek(f, (Sfoff_t)0, 0);
    for (i = 0; i < 10; ++i) {
        if (!(s = sfreserve(f, 1001, 0))) terror("Reserve failed2");
        if (s[0] != '0' + i) terror("Bad data1");
    }
    for (n = 0; n < 1001; ++n) {
        if (s[n] != ((n + i - 1) % 10 + '0')) terror("Bad data");
    }

    /* test to see if a string stream extends ok during writes */
    s = malloc(5);
    f = sfnew(NULL, (void *)s, 5, -1, SF_STRING | SF_READ | SF_WRITE | SF_MALLOC);
    if (!f) terror("Can't create string stream");
    if (sfwrite(f, "01", 2) != 2) terror("Bad write to string stream");
    if (sfwrite(f, "2345678", 7) != 7) terror("Bad write to string stream2");
    if (sfputc(f, 0) != 0) terror("sfputc failed");
    if (sfseek(f, (Sfoff_t)0, 0) != 0) terror("sfseek failed");
    if ((n = (int)sfread(f, buf, 100)) != 10) terror("sfread gets wrong amount of data %d", n);
    if (strcmp(buf, "012345678") != 0) terror("Get wrong data");

    texit(0);
}
コード例 #23
0
ファイル: tmultiple.c プロジェクト: gwowen/seismicunix
/*	Test multiple processes reading/writing from same file
**	descriptor.
*/
MAIN()
{
	char*	s;

	if(argc > 1)
	{	if(strcmp(argv[1],"-r") == 0)	/* doing sfgetr */
		{	if(!(s = sfgetr(sfstdin,'\n',1)) || strcmp(s,"Line2") != 0)
				terror("Coprocess getr did not get Line2\n");
			if(!(s = sfgetr(sfstdin,'\n',1)) || strcmp(s,"Line3") != 0)
				terror("Coprocess getr did not get Line3\n");
		}
		else	/* doing sfmove */
		{	Sfio_t*	f = sfopen(NIL(Sfio_t*),NIL(char*),"swr");
			if(!f)
				terror("Can't open string stream\n");
			if(sfmove(sfstdin,f,(Sfoff_t)2,'\n') != 2)
				terror("Coprocess sfmove failed\n");
			sfseek(f,(Sfoff_t)0,0);
			if(!(s = sfgetr(f,'\n',1)) || strcmp(s,"Line2") != 0)
				terror("Coprocess move did not get Line2\n");
			if(!(s = sfgetr(f,'\n',1)) || strcmp(s,"Line3") != 0)
				terror("Coprocess move did not get Line3\n");
		}
		TSTEXIT(0);
	}

	if(sfopen(sfstdout, tstfile(0), "w") != sfstdout )
		terror("Opening file\n");
	if(sfputr(sfstdout,"Line1",'\n') < 0 ||
	   sfputr(sfstdout,"Line2",'\n') < 0 ||
	   sfputr(sfstdout,"Line3",'\n') < 0 ||
	   sfputr(sfstdout,"Line4",'\n') < 0)
		terror("Writing data\n");
	sfopen(sfstdout,"/dev/null","w");

	/* testing coprocess calling sfgetr */
	if(sfopen(sfstdin, tstfile(0),"r") != sfstdin)
		terror("Opening to read\n");
	if(!(s = sfgetr(sfstdin,'\n',1)) || strcmp(s,"Line1") != 0)
		terror("Did not get Line1 for sfgetr\n");
	sfsync(sfstdin);
	system(sfprints("%s -r",argv[0]));
	sfseek(sfstdin, (Sfoff_t)lseek(sffileno(sfstdin), (off_t)0, 1), 0);
	if(!(s = sfgetr(sfstdin,'\n',1)) || strcmp(s,"Line4") != 0)
		terror("Did not get Line4 for sfgetr\n");

	/* testing coprocess calling sfmove */
	if(sfopen(sfstdin, tstfile(0), "r") != sfstdin)
		terror("Opening to read\n");
	if(!(s = sfgetr(sfstdin,'\n',1)) || strcmp(s,"Line1") != 0)
		terror("Did not get Line1 for sfmove\n");
	sfsync(sfstdin);
	system(sfprints("%s -m",argv[0]));
	sfseek(sfstdin, (Sfoff_t)lseek(sffileno(sfstdin), (off_t)0, 1), 0);
	if(!(s = sfgetr(sfstdin,'\n',1)) || strcmp(s,"Line4") != 0)
		terror("Did not get Line4 for sfmove\n");

	/* testing the head program */
#ifdef HEAD
	if(sfopen(sfstdin, tstfile(0), "r") != sfstdin)
		terror("Opening to read\n");
	if(!(s = sfgetr(sfstdin,'\n',1)) || strcmp(s,"Line1") != 0)
		terror("Did not get Line1 for head\n");
	sfsync(sfstdin);
	system("head -2 > /dev/null"); /* for testing the head program */
	sfseek(sfstdin, (Sfoff_t)lseek(sffileno(sfstdin), (off_t)0, 1), 0);
	if(!(s = sfgetr(sfstdin,'\n',1)) || strcmp(s,"Line4") != 0)
		terror("Did not get Line4 for head\n");
#endif

	TSTEXIT(0);
}
コード例 #24
0
ファイル: history.c プロジェクト: att/ast
//
// 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;
}
コード例 #25
0
ファイル: pty.c プロジェクト: nathanmkaya/ksh-arch
static int
mkpty(int* master, int* slave)
{
	struct termios	tty;
	struct termios	tst;
	struct termios*	ttyp;
#ifdef TIOCGWINSZ
	struct winsize	win;
	struct winsize*	winp;
#endif
#if !_lib_openpty
	char*		sname;
#endif
	/*
	 * some systems hang hard during the handshake
	 * if you know why then please let us know
	 */

	alarm(4);
	if (tcgetattr(sffileno(sfstderr), &tty) >= 0)
		ttyp = &tty;
	else
	{
		ttyp = 0;
		error(-1, "unable to get standard error terminal attributes");
	}
#ifdef TIOCGWINSZ
	if (ioctl(sffileno(sfstderr), TIOCGWINSZ, &win) >= 0)
		winp = &win;
	else
	{
		winp = 0;
		error(-1, "unable to get standard error window size");
	}
#endif
#if _lib_openpty
	if (openpty(master, slave, NULL, ttyp, winp) < 0)
		return -1;
#else
#if _lib_grantpt && _lib_unlockpt
#if !_lib_posix_openpt
#ifndef _pty_clone
#define _pty_clone	"/dev/ptmx"
#endif
#define posix_openpt(m)	open(_pty_clone,m)
#endif
	if ((*master = posix_openpt(O_RDWR)) < 0)
		return -1;
	if (grantpt(*master) || unlockpt(*master) || !(sname = ptsname(*master)) || (*slave = open(sname, O_RDWR|O_cloexec)) < 0)
	{
		close(*master);
		return -1;
	}
#else
	if (!(sname = ptymopen(master)) || (*slave = open(sname, O_RDWR|O_cloexec)) < 0)
		return -1;
#endif
#ifdef I_PUSH
	if (tcgetattr(*slave, &tst) < 0 && (ioctl(*slave, I_PUSH, "ptem") < 0 || ioctl(*slave, I_PUSH, "ldterm") < 0))
	{
		close(*slave);
		close(*master);
		return -1;
	}
#endif
#endif
	if (ttyp && tcsetattr(*slave, TCSANOW, ttyp) < 0)
		error(ERROR_warn(0), "unable to set pty terminal attributes");
#ifdef TIOCSWINSZ
	if (winp && ioctl(*slave, TIOCSWINSZ, winp) < 0)
		error(ERROR_warn(0), "unable to set pty window size");
#endif
	fcntl(*master, F_SETFD, FD_CLOEXEC);
#if !O_cloexec
	fcntl(*slave, F_SETFD, FD_CLOEXEC);
#endif
	alarm(0);
	return 0;
}
コード例 #26
0
ファイル: pty.c プロジェクト: nathanmkaya/ksh-arch
static int
process(Sfio_t* mp, Sfio_t* lp, int delay, int timeout)
{
	int		i;
	int		n;
	int		t;
	ssize_t		r;
	char*		s;
	Sfio_t*		ip;
	Sfio_t*		sps[2];
	struct stat	dst;
	struct stat	fst;

	ip = sfstdin;
	if (!fstat(sffileno(ip), &dst) && !stat("/dev/null", &fst) && dst.st_dev == fst.st_dev && dst.st_ino == fst.st_ino)
		ip = 0;
	do
	{
		i = 0;
		t = timeout;
		if (mp)
			sps[i++] = mp;
		if (ip)
		{
			sps[i++] = ip;
			t = -1;
		}
		if (!i)
			break;
		if ((n = sfpoll(sps, i, t)) <= 0)
		{
			if (n < 0)
				error(ERROR_SYSTEM|2, "poll failed");
			break;
		}
		for (i = t = 0; i < n; i++)
		{
			if (!(sfvalue(sps[i]) & SF_READ))
				/*skip*/;
			else if (sps[i] == mp)
			{
				t++;
				if (!(s = (char*)sfreserve(mp, SF_UNBOUND, -1)))
				{
					sfclose(mp);
					mp = 0;
				}
				else if ((r = sfvalue(mp)) > 0 && (sfwrite(sfstdout, s, r) != r || sfsync(sfstdout)))
				{
					error(ERROR_SYSTEM|2, "output write failed");
					goto done;
				}
			}
			else
			{
				t++;
				if (!(s = sfgetr(ip, '\n', 1)))
					ip = 0;
				else if (sfputr(mp, s, '\r') < 0 || sfsync(mp))
				{
					error(ERROR_SYSTEM|2, "write failed");
					goto done;
				}
			}
		}
	} while (t);
 done:
	if (mp)
		sfclose(mp);
	return error_info.errors != 0;
}
コード例 #27
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);
}