Example #1
0
File: sh.sem.c Project: lukem/tcsh
/*
 * Perform io redirection.
 * We may or maynot be forked here.
 */
static void
doio(struct command *t, int *pipein, int *pipeout)
{
    int fd;
    Char *cp;
    unsigned long flags = t->t_dflg;

    if (didfds || (flags & F_REPEAT))
	return;
    if ((flags & F_READ) == 0) {/* F_READ already done */
	if (t->t_dlef) {
	    char *tmp;

	    /*
	     * so < /dev/std{in,out,err} work
	     */
	    (void) dcopy(SHIN, 0);
	    (void) dcopy(SHOUT, 1);
	    (void) dcopy(SHDIAG, 2);
	    cp = splicepipe(t, t->t_dlef);
	    tmp = strsave(short2str(cp));
	    xfree(cp);
	    cleanup_push(tmp, xfree);
	    if ((fd = xopen(tmp, O_RDONLY|O_LARGEFILE)) < 0)
		stderror(ERR_SYSTEM, tmp, strerror(errno));
	    cleanup_until(tmp);
	    /* allow input files larger than 2Gb  */
#ifndef WINNT_NATIVE
	    (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_LARGEFILE);
#endif /*!WINNT_NATIVE*/
	    (void) dmove(fd, 0);
	}
	else if (flags & F_PIPEIN) {
	    xclose(0);
	    TCSH_IGNORE(dup(pipein[0]));
	    xclose(pipein[0]);
	    xclose(pipein[1]);
	}
	else if ((flags & F_NOINTERRUPT) && tpgrp == -1) {
	    xclose(0);
	    (void) xopen(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE);
	}
	else {
	    xclose(0);
	    TCSH_IGNORE(dup(OLDSTD));
#if defined(CLOSE_ON_EXEC) && defined(CLEX_DUPS)
	    /*
	     * PWP: Unlike Bezerkeley 4.3, FIONCLEX for Pyramid is preserved
	     * across dup()s, so we have to UNSET it here or else we get a
	     * command with NO stdin, stdout, or stderr at all (a bad thing
	     * indeed)
	     */
	    (void) close_on_exec(0, 0);
#endif /* CLOSE_ON_EXEC && CLEX_DUPS */
	}
    }
    if (t->t_drit) {
	char *tmp;

	cp = splicepipe(t, t->t_drit);
	tmp = strsave(short2str(cp));
	xfree(cp);
	cleanup_push(tmp, xfree);
	/*
	 * so > /dev/std{out,err} work
	 */
	(void) dcopy(SHOUT, 1);
	(void) dcopy(SHDIAG, 2);
	if ((flags & F_APPEND) != 0) {
#ifdef O_APPEND
	    fd = xopen(tmp, O_WRONLY|O_APPEND|O_LARGEFILE);
#else /* !O_APPEND */
	    fd = xopen(tmp, O_WRONLY|O_LARGEFILE);
	    (void) lseek(fd, (off_t) 0, L_XTND);
#endif /* O_APPEND */
	}
	else
	    fd = 0;
	if ((flags & F_APPEND) == 0 || fd == -1) {
	    if (!(flags & F_OVERWRITE) && adrof(STRnoclobber)) {
		if (flags & F_APPEND)
		    stderror(ERR_SYSTEM, tmp, strerror(errno));
		chkclob(tmp);
	    }
	    if ((fd = xcreat(tmp, 0666)) < 0)
		stderror(ERR_SYSTEM, tmp, strerror(errno));
	    /* allow input files larger than 2Gb  */
#ifndef WINNT_NATIVE
	    (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_LARGEFILE);
#endif /*!WINNT_NATIVE*/
	}
	cleanup_until(tmp);
	(void) dmove(fd, 1);
	is1atty = isatty(1);
    }
    else if (flags & F_PIPEOUT) {
	xclose(1);
	TCSH_IGNORE(dup(pipeout[1]));
	is1atty = 0;
    }
    else {
	xclose(1);
	TCSH_IGNORE(dup(SHOUT));
	is1atty = isoutatty;
# if defined(CLOSE_ON_EXEC) && defined(CLEX_DUPS)
	(void) close_on_exec(1, 0);
# endif /* CLOSE_ON_EXEC && CLEX_DUPS */
    }

    xclose(2);
    if (flags & F_STDERR) {
	TCSH_IGNORE(dup(1));
	is2atty = is1atty;
    }
    else {
	TCSH_IGNORE(dup(SHDIAG));
	is2atty = isdiagatty;
# if defined(CLOSE_ON_EXEC) && defined(CLEX_DUPS)
	(void) close_on_exec(2, 0);
# endif /* CLOSE_ON_EXEC && CLEX_DUPS */
    }
    didfds = 1;
}
Example #2
0
File: sh.dir.c Project: lukem/tcsh
/*
 * create a file called ~/.cshdirs which has a sequence
 * of pushd commands which will restore the dir stack to
 * its state before exit/logout. remember that the order
 * is reversed in the file because we are pushing.
 * -strike
 */
void
recdirs(Char *fname, int def)
{
    int     fp, ftmp, oldidfds;
    int     cdflag = 0;
    struct directory *dp;
    unsigned int    num;
    Char   *snum;
    struct Strbuf qname = Strbuf_INIT;

    if (fname == NULL && !def) 
	return;

    if (fname == NULL) {
	if ((fname = varval(STRdirsfile)) == STRNULL)
	    fname = Strspl(varval(STRhome), &STRtildotdirs[1]);
	else
	    fname = Strsave(fname);
    }
    else 
	fname = globone(fname, G_ERROR);
    cleanup_push(fname, xfree);

    if ((fp = xcreat(short2str(fname), 0600)) == -1) {
	cleanup_until(fname);
	return;
    }

    if ((snum = varval(STRsavedirs)) == STRNULL || snum[0] == '\0') 
	num = (unsigned int) ~0;
    else
	num = (unsigned int) atoi(short2str(snum));

    oldidfds = didfds;
    didfds = 0;
    ftmp = SHOUT;
    SHOUT = fp;

    cleanup_push(&qname, Strbuf_cleanup);
    dp = dcwd->di_next;
    do {
	if (dp == &dhead)
	    continue;

	if (cdflag == 0) {
	    cdflag = 1;
	    xprintf("cd %S\n", quote_meta(&qname, dp->di_name));
	}
	else
	    xprintf("pushd %S\n", quote_meta(&qname, dp->di_name));

	if (num-- == 0)
	    break;

    } while ((dp = dp->di_next) != dcwd->di_next);

    xclose(fp);
    SHOUT = ftmp;
    didfds = oldidfds;
    cleanup_until(fname);
}
Example #3
0
/*
 * Form a shell temporary file (in unit 0) from the words
 * of the shell input up to EOF or a line the same as "term".
 * Unit 0 should have been closed before this call.
 */
void
heredoc(Char *term)
{
    eChar  c;
    Char   *Dv[2];
    struct Strbuf lbuf = Strbuf_INIT, mbuf = Strbuf_INIT;
    Char    obuf[BUFSIZE + 1];
#define OBUF_END (obuf + sizeof(obuf) / sizeof (*obuf) - 1)
    Char *lbp, *obp, *mbp;
    Char  **vp;
    int    quoted;
#ifdef HAVE_MKSTEMP
    char   *tmp = short2str(shtemp);
    char   *dot = strrchr(tmp, '.');

    if (!dot)
	stderror(ERR_NAME | ERR_NOMATCH);
    strcpy(dot, TMP_TEMPLATE);

    xclose(0);
    if (mkstemp(tmp) == -1)
	stderror(ERR_SYSTEM, tmp, strerror(errno));
#else /* !HAVE_MKSTEMP */
    char   *tmp;
# ifndef WINNT_NATIVE

again:
# endif /* WINNT_NATIVE */
    tmp = short2str(shtemp);
# if O_CREAT == 0
    if (xcreat(tmp, 0600) < 0)
	stderror(ERR_SYSTEM, tmp, strerror(errno));
# endif
    xclose(0);
    if (xopen(tmp, O_RDWR|O_CREAT|O_EXCL|O_TEMPORARY|O_LARGEFILE, 0600) ==
	-1) {
	int oerrno = errno;
# ifndef WINNT_NATIVE
	if (errno == EEXIST) {
	    if (unlink(tmp) == -1) {
		xfree(shtemp);
		mbp = randsuf();
		shtemp = Strspl(STRtmpsh, mbp);
		xfree(mbp);
	    }
	    goto again;
	}
# endif /* WINNT_NATIVE */
	(void) unlink(tmp);
	errno = oerrno;
 	stderror(ERR_SYSTEM, tmp, strerror(errno));
    }
#endif /* HAVE_MKSTEMP */
    (void) unlink(tmp);		/* 0 0 inode! */
    Dv[0] = term;
    Dv[1] = NULL;
    gflag = 0;
    trim(Dv);
    rscan(Dv, Dtestq);
    quoted = gflag;
    obp = obuf;
    obuf[BUFSIZE] = 0;
    inheredoc = 1;
    cleanup_push(&inheredoc, inheredoc_cleanup);
#ifdef WINNT_NATIVE
    __dup_stdin = 1;
#endif /* WINNT_NATIVE */
    cleanup_push(&lbuf, Strbuf_cleanup);
    cleanup_push(&mbuf, Strbuf_cleanup);
    for (;;) {
	Char **words;

	/*
	 * Read up a line
	 */
	lbuf.len = 0;
	for (;;) {
	    c = readc(1);	/* 1 -> Want EOF returns */
	    if (c == CHAR_ERR || c == '\n')
		break;
	    if ((c &= TRIM) != 0)
		Strbuf_append1(&lbuf, (Char) c);
	}
	Strbuf_terminate(&lbuf);

	/* Catch EOF in the middle of a line. */
	if (c == CHAR_ERR && lbuf.len != 0)
	    c = '\n';

	/*
	 * Check for EOF or compare to terminator -- before expansion
	 */
	if (c == CHAR_ERR || eq(lbuf.s, term))
	    break;

	/*
	 * If term was quoted or -n just pass it on
	 */
	if (quoted || noexec) {
	    Strbuf_append1(&lbuf, '\n');
	    Strbuf_terminate(&lbuf);
	    for (lbp = lbuf.s; (c = *lbp++) != 0;) {
		*obp++ = (Char) c;
		if (obp == OBUF_END) {
		    tmp = short2str(obuf);
		    (void) xwrite(0, tmp, strlen (tmp));
		    obp = obuf;
		}
	    }
	    continue;
	}

	/*
	 * Term wasn't quoted so variable and then command expand the input
	 * line
	 */
	Dcp = lbuf.s;
	Dvp = Dv + 1;
	mbuf.len = 0;
	for (;;) {
	    c = DgetC(DODOL);
	    if (c == DEOF)
		break;
	    if ((c &= TRIM) == 0)
		continue;
	    /* \ quotes \ $ ` here */
	    if (c == '\\') {
		c = DgetC(0);
		if (!any("$\\`", c))
		    unDgetC(c | QUOTE), c = '\\';
		else
		    c |= QUOTE;
	    }
	    Strbuf_append1(&mbuf, (Char) c);
	}
	Strbuf_terminate(&mbuf);

	/*
	 * If any ` in line do command substitution
	 */
	mbp = mbuf.s;
	if (Strchr(mbp, '`') != NULL) {
	    /*
	     * 1 arg to dobackp causes substitution to be literal. Words are
	     * broken only at newlines so that all blanks and tabs are
	     * preserved.  Blank lines (null words) are not discarded.
	     */
	    words = dobackp(mbp, 1);
	}
	else
	    /* Setup trivial vector similar to return of dobackp */
	    Dv[0] = mbp, Dv[1] = NULL, words = Dv;

	/*
	 * Resurrect the words from the command substitution each separated by
	 * a newline.  Note that the last newline of a command substitution
	 * will have been discarded, but we put a newline after the last word
	 * because this represents the newline after the last input line!
	 */
	for (vp= words; *vp; vp++) {
	    for (mbp = *vp; *mbp; mbp++) {
		*obp++ = *mbp & TRIM;
		if (obp == OBUF_END) {
		    tmp = short2str(obuf);
		    (void) xwrite(0, tmp, strlen (tmp));
		    obp = obuf;
		}
	    }
	    *obp++ = '\n';
	    if (obp == OBUF_END) {
	        tmp = short2str(obuf);
		(void) xwrite(0, tmp, strlen (tmp));
		obp = obuf;
	    }
	}
	if (words != Dv)
	    blkfree(words);
    }
    *obp = 0;
    tmp = short2str(obuf);
    (void) xwrite(0, tmp, strlen (tmp));
    (void) lseek(0, (off_t) 0, L_SET);
    cleanup_until(&inheredoc);
}
Example #4
0
/*ARGSUSED*/
long xrename(int n, char *p1, char *p2)
{
        register OFD *fd2;
        OFD     *f1,*fd;
        FCB     *f;
        DND     *dn1,*dn2;
        const char *s1,*s2;
        char    buf[11];
        int     hnew,att;
        long    rc, h1;

        if (!ixsfirst(p2,0,(DTAINFO *)0L))
                return(EACCDN);

        if ((long)(dn1 = findit(p1,&s1,0)) < 0)          /* M01.01.1212.01 */
                return( (long)dn1 );
        if (!dn1)                                        /* M01.01.1214.01 */
                return( EPTHNF );

        if ((long)(dn2 = findit(p2,&s2,0)) < 0)          /* M01.01.1212.01 */
                return( (long)dn2 );
        if (!dn2)                                        /* M01.01.1214.01 */
                return( EPTHNF );

        if (contains_illegal_characters(s2))
                return( EACCDN ) ;

        if ((h1 = xopen(p1, 2)) < 0L)
                return (h1);

        f1 = getofd ((int)h1);

        fd = f1->o_dirfil;
        buf[0] = 0xe5;
        ixlseek(fd,f1->o_dirbyt);

        if (dn1 != dn2)
        {
                /* get old attribute */
                f = (FCB *) ixread(fd,32L,NULLPTR);
                att = f->f_attrib;
                /* erase (0xe5) old file */
                ixlseek(fd,f1->o_dirbyt);
                ixwrite(fd,1L,buf);

                /* copy time/date/clust, etc. */

                ixlseek(fd,f1->o_dirbyt + 22);
                ixread(fd,10L,buf);
                hnew = xcreat(p2,att);
                fd2 = getofd(hnew);
                ixlseek(fd2->o_dirfil,fd2->o_dirbyt + 22);
                ixwrite(fd2->o_dirfil,10L,buf);
                fd2->o_flag &= ~O_DIRTY;
                xclose(hnew);
                ixclose(fd2->o_dirfil,CL_DIR);
        }
        else
        {
                builds(s2,buf);
                ixwrite(fd,11L,buf);
        }

        if ((rc = xclose((int)h1)) < 0L)
                return(rc);

        return(ixclose(fd,CL_DIR));
}