Example #1
0
File: shf.c Project: Open343/bitrig
/* Read a buffer from shf.  Returns the number of bytes read into buf,
 * if no bytes were read, returns 0 if end of file was seen, EOF if
 * a read error occurred.
 */
int
shf_read(char *buf, int bsize, struct shf *shf)
{
	int orig_bsize = bsize;
	int ncopy;

	if (!(shf->flags & SHF_RD))
		internal_errorf(1, "shf_read: flags %x", shf->flags);

	if (bsize <= 0)
		internal_errorf(1, "shf_read: bsize %d", bsize);

	while (bsize > 0) {
		if (shf->rnleft == 0 &&
		    (shf_fillbuf(shf) == EOF || shf->rnleft == 0))
			break;
		ncopy = shf->rnleft;
		if (ncopy > bsize)
			ncopy = bsize;
		memcpy(buf, shf->rp, ncopy);
		buf += ncopy;
		bsize -= ncopy;
		shf->rp += ncopy;
		shf->rnleft -= ncopy;
	}
	/* Note: fread(3S) returns 0 for errors - this doesn't */
	return orig_bsize == bsize ? (shf_error(shf) ? EOF : 0) :
	    orig_bsize - bsize;
}
Example #2
0
/* Make j the last async process
 *
 * If jobs are compiled in then this routine expects sigchld to be blocked.
 */
static void
j_set_async(Job *j)
{
	Job	*jl, *oldest;

	if (async_job && (async_job->flags & (JF_KNOWN|JF_ZOMBIE)) == JF_ZOMBIE)
		remove_job(async_job, "async");
	if (!(j->flags & JF_STARTED)) {
		internal_errorf(0, "j_async: job not started");
		return;
	}
	async_job = j;
	async_pid = j->last_proc->pid;
	while (nzombie > child_max) {
		oldest = (Job *) 0;
		for (jl = job_list; jl; jl = jl->next)
			if (jl != async_job && (jl->flags & JF_ZOMBIE) &&
			    (!oldest || jl->age < oldest->age))
				oldest = jl;
		if (!oldest) {
			/* XXX debugging */
			if (!(async_job->flags & JF_ZOMBIE) || nzombie != 1) {
				internal_errorf(0,
				    "j_async: bad nzombie (%d)", nzombie);
				nzombie = 0;
			}
			break;
		}
		remove_job(oldest, "zombie");
	}
}
Example #3
0
File: shf.c Project: Open343/bitrig
/* Write a buffer.  Returns nbytes if successful, EOF if there is an error. */
int
shf_write(const char *buf, int nbytes, struct shf *shf)
{
	int orig_nbytes = nbytes;
	int n;
	int ncopy;

	if (!(shf->flags & SHF_WR))
		internal_errorf(1, "shf_write: flags %x", shf->flags);

	if (nbytes < 0)
		internal_errorf(1, "shf_write: nbytes %d", nbytes);

	/* Don't buffer if buffer is empty and we're writting a large amount. */
	if ((ncopy = shf->wnleft) &&
	    (shf->wp != shf->buf || nbytes < shf->wnleft)) {
		if (ncopy > nbytes)
			ncopy = nbytes;
		memcpy(shf->wp, buf, ncopy);
		nbytes -= ncopy;
		buf += ncopy;
		shf->wp += ncopy;
		shf->wnleft -= ncopy;
	}
	if (nbytes > 0) {
		/* Flush deals with strings and sticky errors */
		if (shf_emptybuf(shf, EB_GROW) == EOF)
			return EOF;
		if (nbytes > shf->wbsize) {
			ncopy = nbytes;
			if (shf->wbsize)
				ncopy -= nbytes % shf->wbsize;
			nbytes -= ncopy;
			while (ncopy > 0) {
				n = write(shf->fd, buf, ncopy);
				if (n < 0) {
					if (errno == EINTR &&
					    !(shf->flags & SHF_INTERRUPT))
						continue;
					shf->flags |= SHF_ERROR;
					shf->errno_ = errno;
					shf->wnleft = 0;
					/* Note: fwrite(3S) returns 0 for
					 * errors - this doesn't */
					return EOF;
				}
				buf += n;
				ncopy -= n;
			}
		}
		if (nbytes > 0) {
			memcpy(shf->wp, buf, nbytes);
			shf->wp += nbytes;
			shf->wnleft -= nbytes;
		}
	}

	return orig_nbytes;
}
Example #4
0
File: shf.c Project: Open343/bitrig
/* Put a character back in the input stream.  Returns the character if
 * successful, EOF if there is no room.
 */
int
shf_ungetc(int c, struct shf *shf)
{
	if (!(shf->flags & SHF_RD))
		internal_errorf(1, "shf_ungetc: flags %x", shf->flags);

	if ((shf->flags & SHF_ERROR) || c == EOF ||
	    (shf->rp == shf->buf && shf->rnleft))
		return EOF;

	if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == EOF)
		return EOF;

	if (shf->rp == shf->buf)
		shf->rp = shf->buf + shf->rbsize;
	if (shf->flags & SHF_STRING) {
		/* Can unget what was read, but not something different - we
		 * don't want to modify a string.
		 */
		if (shf->rp[-1] != c)
			return EOF;
		shf->flags &= ~SHF_EOF;
		shf->rp--;
		shf->rnleft++;
		return c;
	}
	shf->flags &= ~SHF_EOF;
	*--(shf->rp) = c;
	shf->rnleft++;
	return c;
}
/*
 * Process here documents by providing the content, either as
 * result (globally allocated) string or in a temp file; if
 * unquoted, the string is expanded first.
 */
static int
hereinval(const char *content, int sub, char **resbuf, struct shf *shf)
{
	const char * volatile ccp = content;
	struct source *s, *osource;

	osource = source;
	newenv(E_ERRH);
	if (kshsetjmp(e->jbuf)) {
		source = osource;
		quitenv(shf);
		/* special to iosetup(): don't print error */
		return (-2);
	}
	if (sub) {
		/* do substitutions on the content of heredoc */
		s = pushs(SSTRING, ATEMP);
		s->start = s->str = ccp;
		source = s;
		if (yylex(sub) != LWORD)
			internal_errorf("%s: %s", "herein", "yylex");
		source = osource;
		ccp = evalstr(yylval.cp, 0);
	}

	if (resbuf == NULL)
		shf_puts(ccp, shf);
	else
		strdupx(*resbuf, ccp, APERM);

	quitenv(NULL);
	return (0);
}
Example #6
0
File: shf.c Project: Open343/bitrig
/* Un-read what has been read but not examined, or write what has been
 * buffered.  Returns 0 for success, EOF for (write) error.
 */
int
shf_flush(struct shf *shf)
{
	if (shf->flags & SHF_STRING)
		return (shf->flags & SHF_WR) ? EOF : 0;

	if (shf->fd < 0)
		internal_errorf(1, "shf_flush: no fd");

	if (shf->flags & SHF_ERROR) {
		errno = shf->errno_;
		return EOF;
	}

	if (shf->flags & SHF_READING) {
		shf->flags &= ~(SHF_EOF | SHF_READING);
		if (shf->rnleft > 0) {
			lseek(shf->fd, (off_t) -shf->rnleft, SEEK_CUR);
			shf->rnleft = 0;
			shf->rp = shf->buf;
		}
		return 0;
	} else if (shf->flags & SHF_WRITING)
		return shf_emptybuf(shf, 0);

	return 0;
}
Example #7
0
File: shf.c Project: Open343/bitrig
/* Open a string for reading or writing.  If reading, bsize is the number
 * of bytes that can be read.  If writing, bsize is the maximum number of
 * bytes that can be written.  If shf is not null, it is filled in and
 * returned, if it is null, shf is allocated.  If writing and buf is null
 * and SHF_DYNAMIC is set, the buffer is allocated (if bsize > 0, it is
 * used for the initial size).  Doesn't fail.
 * When writing, a byte is reserved for a trailing null - see shf_sclose().
 */
struct shf *
shf_sopen(char *buf, int bsize, int sflags, struct shf *shf)
{
	/* can't have a read+write string */
	if (!(sflags & (SHF_RD | SHF_WR)) ||
	    (sflags & (SHF_RD | SHF_WR)) == (SHF_RD | SHF_WR))
		internal_errorf(1, "shf_sopen: flags 0x%x", sflags);

	if (!shf) {
		shf = alloc(sizeof(struct shf), ATEMP);
		sflags |= SHF_ALLOCS;
	}
	shf->areap = ATEMP;
	if (!buf && (sflags & SHF_WR) && (sflags & SHF_DYNAMIC)) {
		if (bsize <= 0)
			bsize = 64;
		sflags |= SHF_ALLOCB;
		buf = alloc(bsize, shf->areap);
	}
	shf->fd = -1;
	shf->buf = shf->rp = shf->wp = (unsigned char *) buf;
	shf->rnleft = bsize;
	shf->rbsize = bsize;
	shf->wnleft = bsize - 1;	/* space for a '\0' */
	shf->wbsize = bsize;
	shf->flags = sflags | SHF_STRING;
	shf->errno_ = 0;
	shf->bsize = bsize;

	return shf;
}
Example #8
0
File: jobs.c Project: adtools/abcsh
int
waitlast(void)
{
        int     rv;
        Job     *j;
        sigset_t omask;

        sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);

        j = last_job;
        if (!j || !(j->flags & JF_STARTED)) {
                if (!j)
                {
                      //   warningf(true, "waitlast: no last job");
                }
                else
                        internal_errorf(0, "waitlast: not started");
                sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);

                // work arround for no job control
                // place the result of the last command
                // subshell or whatever in lastresult
                // and return it here.
                return lastresult;
                //return 125; /* not so arbitrary, non-zero value */
        }

        rv = j_waitj(j, JW_NONE, "jw:waitlast");

        sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);

        return rv;
}
Example #9
0
/* wait for last job: only used for `command` jobs */
int
waitlast(void)
{
	int	rv;
	Job	*j;
	sigset_t omask;

	sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);

	j = last_job;
	if (!j || !(j->flags & JF_STARTED)) {
		if (!j)
			warningf(true, "waitlast: no last job");
		else
			internal_errorf(0, "waitlast: not started");
		sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
		return 125; /* not so arbitrary, non-zero value */
	}

	rv = j_waitj(j, JW_NONE, "jw:waitlast");

	sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);

	return rv;
}
Example #10
0
File: alloc.c Project: 0xMF/oksh
void
afree(void *ptr, Area *ap)
{
	struct link *l, *l2;

	if (!ptr)
		return;

	l = P2L(ptr);

	for (l2 = ap->freelist; l2 != NULL; l2 = l2->next) {
		if (l == l2)
			break;
	}
	if (l2 == NULL)
		internal_errorf(1, "afree: %p not present in area %p", ptr, ap);

	if (l->prev)
		l->prev->next = l->next;
	else
		ap->freelist = l->next;
	if (l->next)
		l->next->prev = l->prev;

	free(l);
}
Example #11
0
/*
 *  Do file globbing:
 *	- appends * to (copy of) str if no globbing chars found
 *	- does expansion, checks for no match, etc.
 *	- sets *wordsp to array of matching strings
 *	- returns number of matching strings
 */
static int
x_file_glob(int flags, const char *str, int slen, char ***wordsp)
{
	char *toglob;
	char **words;
	int nwords;
	XPtrV w;
	struct source *s, *sold;

	if (slen < 0)
		return 0;

	toglob = add_glob(str, slen);

	/*
	 * Convert "foo*" (toglob) to an array of strings (words)
	 */
	sold = source;
	s = pushs(SWSTR, ATEMP);
	s->start = s->str = toglob;
	source = s;
	if (yylex(ONEWORD|UNESCAPE) != LWORD) {
		source = sold;
		internal_errorf(0, "fileglob: substitute error");
		return 0;
	}
	source = sold;
	XPinit(w, 32);
	expand(yylval.cp, &w, DOGLOB|DOTILDE|DOMARKDIRS);
	XPput(w, NULL);
	words = (char **) XPclose(w);

	for (nwords = 0; words[nwords]; nwords++)
		;
	if (nwords == 1) {
		struct stat statb;

		/* Check if file exists, also, check for empty
		 * result - happens if we tried to glob something
		 * which evaluated to an empty string (e.g.,
		 * "$FOO" when there is no FOO, etc).
		 */
		 if ((lstat(words[0], &statb) < 0) ||
		    words[0][0] == '\0') {
			x_free_words(nwords, words);
			words = NULL;
			nwords = 0;
		}
	}
	afree(toglob, ATEMP);

	if (nwords) {
		*wordsp = words;
	} else if (words) {
		x_free_words(nwords, words);
		*wordsp = NULL;
	}

	return nwords;
}
Example #12
0
void *
aresize(void *ptr, size_t numb, Area *ap)
{
	ALLOC_ITEM *lp = NULL;

	/* resizing (true) or newly allocating? */
	if (ptr != NULL) {
		ALLOC_ITEM *pp;

		pp = findptr(&lp, ptr, ap);
		pp->next = lp->next;
	}

	if ((numb >= SIZE_MAX - ALLOC_SIZE) ||
	    (lp = remalloc(lp, numb + ALLOC_SIZE)) == NULL
#ifndef MKSH_SMALL
	    || ALLOC_ISUNALIGNED(lp)
#endif
	    )
		internal_errorf("cannot allocate %lu data bytes",
		    (unsigned long)numb);
	/* this only works because Area is an ALLOC_ITEM */
	lp->next = ap->next;
	ap->next = lp;
	/* return user item address */
	return ((char *)lp + ALLOC_SIZE);
}
Example #13
0
/* set variable to string value */
int
setstr(struct tbl *vq, const char *s, int error_ok)
{
	const char *fs = NULL;
	int no_ro_check = error_ok & 0x4;
	error_ok &= ~0x4;
	if ((vq->flag & RDONLY) && !no_ro_check) {
		warningf(true, "%s: is read only", vq->name);
		if (!error_ok)
			errorf(null);
		return 0;
	}
	if (!(vq->flag&INTEGER)) { /* string dest */
		if ((vq->flag&ALLOC)) {
			/* debugging */
			if (s >= vq->val.s &&
			    s <= vq->val.s + strlen(vq->val.s))
				internal_errorf(true,
				    "setstr: %s=%s: assigning to self",
				    vq->name, s);
			afree((void*)vq->val.s, vq->areap);
		}
		vq->flag &= ~(ISSET|ALLOC);
		vq->type = 0;
		if (s && (vq->flag & (UCASEV_AL|LCASEV|LJUST|RJUST)))
			fs = s = formatstr(vq, s);
		if ((vq->flag&EXPORT))
			export(vq, s);
		else {
			vq->val.s = str_save(s, vq->areap);
			vq->flag |= ALLOC;
		}
	} else {		/* integer dest */
Example #14
0
static ALLOC_ITEM *
findptr(ALLOC_ITEM **lpp, char *ptr, Area *ap)
{
	void *lp;

#ifndef MKSH_SMALL
	if (ALLOC_ISUNALIGNED(ptr))
		goto fail;
#endif
	/* get address of ALLOC_ITEM from user item */
	/*
	 * note: the alignment of "ptr" to ALLOC_SIZE is checked
	 * above; the "void *" gets us rid of a gcc 2.95 warning
	 */
	*lpp = (lp = ptr - ALLOC_SIZE);
	/* search for allocation item in group list */
	while (ap->next != lp)
		if ((ap = ap->next) == NULL) {
#ifndef MKSH_SMALL
 fail:
#endif
			internal_errorf("rogue pointer %p", ptr);
		}
	return (ap);
}
Example #15
0
/* Take job out of job_list and put old structures into free list.
 * Keeps nzombies, last_job and async_job up to date.
 *
 * If jobs are compiled in then this routine expects sigchld to be blocked.
 */
static void
remove_job(Job *j, const char *where)
{
	Proc	*p, *tmp;
	Job	**prev, *curr;

	prev = &job_list;
	curr = *prev;
	for (; curr != (Job *) 0 && curr != j; prev = &curr->next, curr = *prev)
		;
	if (curr != j) {
		internal_errorf(0, "remove_job: job not found (%s)", where);
		return;
	}
	*prev = curr->next;

	/* free up proc structures */
	for (p = j->proc_list; p != (Proc *) 0; ) {
		tmp = p;
		p = p->next;
		tmp->next = free_procs;
		free_procs = tmp;
	}

	if ((j->flags & JF_ZOMBIE) && j->ppid == procpid)
		--nzombie;
	j->next = free_jobs;
	free_jobs = j;

	if (j == last_job)
		last_job = (Job *) 0;
	if (j == async_job)
		async_job = (Job *) 0;
}
Example #16
0
File: shf.c Project: Open343/bitrig
/* Set up an existing shf (and buffer) to use the given fd */
struct shf *
shf_reopen(int fd, int sflags, struct shf *shf)
{
	int bsize = sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE;

	/* use fcntl() to figure out correct read/write flags */
	if (sflags & SHF_GETFL) {
		int flags = fcntl(fd, F_GETFL, 0);

		if (flags < 0)
			/* will get an error on first read/write */
			sflags |= SHF_RDWR;
		else {
			switch (flags & O_ACCMODE) {
			case O_RDONLY:
				sflags |= SHF_RD;
				break;
			case O_WRONLY:
				sflags |= SHF_WR;
				break;
			case O_RDWR:
				sflags |= SHF_RDWR;
				break;
			}
		}
	}

	if (!(sflags & (SHF_RD | SHF_WR)))
		internal_errorf(1, "shf_reopen: missing read/write");
	if (!shf || !shf->buf || shf->bsize < bsize)
		internal_errorf(1, "shf_reopen: bad shf/buf/bsize");

	/* assumes shf->buf and shf->bsize already set up */
	shf->fd = fd;
	shf->rp = shf->wp = shf->buf;
	shf->rnleft = 0;
	shf->rbsize = bsize;
	shf->wnleft = 0; /* force call to shf_emptybuf() */
	shf->wbsize = sflags & SHF_UNBUF ? 0 : bsize;
	shf->flags = (shf->flags & (SHF_ALLOCS | SHF_ALLOCB)) | sflags;
	shf->errno_ = 0;
	if (sflags & SHF_CLEXEC)
		fcntl(fd, F_SETFD, FD_CLOEXEC);
	return shf;
}
Example #17
0
File: shf.c Project: Open343/bitrig
/* Set up the shf structure for a file descriptor.  Doesn't fail. */
struct shf *
shf_fdopen(int fd, int sflags, struct shf *shf)
{
	int bsize = sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE;

	/* use fcntl() to figure out correct read/write flags */
	if (sflags & SHF_GETFL) {
		int flags = fcntl(fd, F_GETFL, 0);

		if (flags < 0)
			/* will get an error on first read/write */
			sflags |= SHF_RDWR;
		else {
			switch (flags & O_ACCMODE) {
			case O_RDONLY:
				sflags |= SHF_RD;
				break;
			case O_WRONLY:
				sflags |= SHF_WR;
				break;
			case O_RDWR:
				sflags |= SHF_RDWR;
				break;
			}
		}
	}

	if (!(sflags & (SHF_RD | SHF_WR)))
		internal_errorf(1, "shf_fdopen: missing read/write");

	if (shf) {
		if (bsize) {
			shf->buf = alloc(bsize, ATEMP);
			sflags |= SHF_ALLOCB;
		} else
			shf->buf = NULL;
	} else {
		shf = alloc(sizeof(struct shf) + bsize, ATEMP);
		shf->buf = (unsigned char *) &shf[1];
		sflags |= SHF_ALLOCS;
	}
	shf->areap = ATEMP;
	shf->fd = fd;
	shf->rp = shf->wp = shf->buf;
	shf->rnleft = 0;
	shf->rbsize = bsize;
	shf->wnleft = 0; /* force call to shf_emptybuf() */
	shf->wbsize = sflags & SHF_UNBUF ? 0 : bsize;
	shf->flags = sflags;
	shf->errno_ = 0;
	shf->bsize = bsize;
	if (sflags & SHF_CLEXEC)
		fcntl(fd, F_SETFD, FD_CLOEXEC);
	return shf;
}
Example #18
0
File: shf.c Project: Open343/bitrig
/* Returns the char read.  Returns EOF for error and end of file. */
int
shf_getchar(struct shf *shf)
{
	if (!(shf->flags & SHF_RD))
		internal_errorf(1, "shf_getchar: flags %x", shf->flags);

	if (shf->rnleft == 0 && (shf_fillbuf(shf) == EOF || shf->rnleft == 0))
		return EOF;
	--shf->rnleft;
	return *shf->rp++;
}
Example #19
0
/* printf to shl_stdout (stdout) */
void
shprintf(const char *fmt, ...)
{
	va_list va;

	if (!shl_stdout_ok)
		internal_errorf(1, "shl_stdout not valid");
	va_start(va, fmt);
	shf_vfprintf(shl_stdout, fmt, va);
	va_end(va);
}
Example #20
0
File: shf.c Project: Open343/bitrig
/* Write a character.  Returns the character if successful, EOF if
 * the char could not be written.
 */
int
shf_putchar(int c, struct shf *shf)
{
	if (!(shf->flags & SHF_WR))
		internal_errorf(1, "shf_putchar: flags %x", shf->flags);

	if (c == EOF)
		return EOF;

	if (shf->flags & SHF_UNBUF) {
		char cc = c;
		int n;

		if (shf->fd < 0)
			internal_errorf(1, "shf_putchar: no fd");
		if (shf->flags & SHF_ERROR) {
			errno = shf->errno_;
			return EOF;
		}
		while ((n = write(shf->fd, &cc, 1)) != 1)
			if (n < 0) {
				if (errno == EINTR &&
				    !(shf->flags & SHF_INTERRUPT))
					continue;
				shf->flags |= SHF_ERROR;
				shf->errno_ = errno;
				return EOF;
			}
	} else {
		/* Flush deals with strings and sticky errors */
		if (shf->wnleft == 0 && shf_emptybuf(shf, EB_GROW) == EOF)
			return EOF;
		shf->wnleft--;
		*shf->wp++ = c;
	}

	return c;
}
Example #21
0
/* set variable to string value */
int
setstr(struct tbl *vq, const char *s, int error_ok)
{
	char *salloc = NULL;
	bool no_ro_check = tobool(error_ok & 0x4);

	error_ok &= ~0x4;
	if ((vq->flag & RDONLY) && !no_ro_check) {
		warningf(true, "read-only: %s", vq->name);
		if (!error_ok)
			errorfxz(2);
		return (0);
	}
	if (!(vq->flag&INTEGER)) {
		/* string dest */
		if ((vq->flag&ALLOC)) {
#ifndef MKSH_SMALL
			/* debugging */
			if (s >= vq->val.s &&
			    s <= vq->val.s + strlen(vq->val.s)) {
				internal_errorf(
				    "setstr: %s=%s: assigning to self",
				    vq->name, s);
			}
#endif
			afree(vq->val.s, vq->areap);
		}
		vq->flag &= ~(ISSET|ALLOC);
		vq->type = 0;
		if (s && (vq->flag & (UCASEV_AL|LCASEV|LJUST|RJUST)))
			s = salloc = formatstr(vq, s);
		if ((vq->flag&EXPORT))
			exportprep(vq, s);
		else {
			strdupx(vq->val.s, s, vq->areap);
			vq->flag |= ALLOC;
		}
	} else {
		/* integer dest */
		if (!v_evaluate(vq, s, error_ok, true))
			return (0);
	}
	vq->flag |= ISSET;
	if ((vq->flag&SPECIAL))
		setspec(vq);
	afree(salloc, ATEMP);
	return (1);
}
Example #22
0
File: alloc.c Project: 0xMF/oksh
void *
alloc(size_t size, Area *ap)
{
	struct link *l;

	l = malloc(sizeof(struct link) + size);
	if (l == NULL)
		internal_errorf(1, "unable to allocate memory");
	l->next = ap->freelist;
	l->prev = NULL;
	if (ap->freelist)
		ap->freelist->prev = l;
	ap->freelist = l;

	return L2P(l);
}
Example #23
0
File: shf.c Project: Open343/bitrig
int
shf_snprintf(char *buf, int bsize, const char *fmt, ...)
{
	struct shf shf;
	va_list args;
	int n;

	if (!buf || bsize <= 0)
		internal_errorf(1, "shf_snprintf: buf %lx, bsize %d",
			(long) buf, bsize);

	shf_sopen(buf, bsize, SHF_WR, &shf);
	va_start(args, fmt);
	n = shf_vfprintf(&shf, fmt, args);
	va_end(args);
	shf_sclose(&shf); /* null terminates */
	return n;
}
Example #24
0
static void
tgrow(struct table *tp)
{
	size_t i, j, osize, mask, perturb;
	struct tbl *tblp, **pp;
	struct tbl **ntblp, **otblp = tp->tbls;

	if (tp->tshift > 29)
		internal_errorf("hash table size limit reached");

	/* calculate old size, new shift and new size */
	osize = (size_t)1 << (tp->tshift++);
	i = osize << 1;

	ntblp = alloc2(i, sizeof(struct tbl *), tp->areap);
	/* multiplication cannot overflow: alloc2 checked that */
	memset(ntblp, 0, i * sizeof(struct tbl *));

	/* table can get very full when reaching its size limit */
	tp->nfree = (tp->tshift == 30) ? 0x3FFF0000UL :
	    /* but otherwise, only 75% */
	    ((i * 3) / 4);
	tp->tbls = ntblp;
	if (otblp == NULL)
		return;

	mask = i - 1;
	for (i = 0; i < osize; i++)
		if ((tblp = otblp[i]) != NULL) {
			if ((tblp->flag & DEFINED)) {
				/* search for free hash table slot */
				j = perturb = tblp->ua.hval;
				goto find_first_empty_slot;
 find_next_empty_slot:
				j = (j << 2) + j + perturb + 1;
				perturb >>= PERTURB_SHIFT;
 find_first_empty_slot:
				pp = &ntblp[j & mask];
				if (*pp != NULL)
					goto find_next_empty_slot;
				/* found an empty hash table slot */
				*pp = tblp;
				tp->nfree--;
			} else if (!(tblp->flag & FINUSE)) {
static int
call_builtin(struct tbl *tp, const char **wp, const char *where)
{
	int rv;

	if (!tp)
		internal_errorf("%s: %s", where, wp[0]);
	builtin_argv0 = wp[0];
	builtin_flag = tp->flag;
	shf_reopen(1, SHF_WR, shl_stdout);
	shl_stdout_ok = true;
	ksh_getopt_reset(&builtin_opt, GF_ERROR);
	rv = (*tp->val.f)(wp);
	shf_flush(shl_stdout);
	shl_stdout_ok = false;
	builtin_flag = 0;
	builtin_argv0 = NULL;
	return (rv);
}
Example #26
0
File: shf.c Project: Open343/bitrig
/* Fill up a read buffer.  Returns EOF for a read error, 0 otherwise. */
static int
shf_fillbuf(struct shf *shf)
{
	if (shf->flags & SHF_STRING)
		return 0;

	if (shf->fd < 0)
		internal_errorf(1, "shf_fillbuf: no fd");

	if (shf->flags & (SHF_EOF | SHF_ERROR)) {
		if (shf->flags & SHF_ERROR)
			errno = shf->errno_;
		return EOF;
	}

	if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == EOF)
		return EOF;

	shf->flags |= SHF_READING;

	shf->rp = shf->buf;
	while (1) {
		shf->rnleft = blocking_read(shf->fd, (char *) shf->buf,
		    shf->rbsize);
		if (shf->rnleft < 0 && errno == EINTR &&
		    !(shf->flags & SHF_INTERRUPT))
			continue;
		break;
	}
	if (shf->rnleft <= 0) {
		if (shf->rnleft < 0) {
			shf->flags |= SHF_ERROR;
			shf->errno_ = errno;
			shf->rnleft = 0;
			shf->rp = shf->buf;
			return EOF;
		}
		shf->flags |= SHF_EOF;
	}
	return 0;
}
Example #27
0
/* hash(n) */
struct tbl *
ktenter(struct table *tp, const char *n, unsigned int h)
{
    struct tbl **pp, *p;
    int len;

    if (tp->size == 0)
        texpand(tp, INIT_TBLS);
Search:
    /* search for name in hashed table */
    for (pp = &tp->tbls[h & (tp->size-1)]; (p = *pp) != NULL; pp--) {
        if (*p->name == *n && strcmp(p->name, n) == 0)
            return p;	/* found */
        if (pp == tp->tbls) /* wrap */
            pp += tp->size;
    }

    if (tp->nfree <= 0) {	/* too full */
        if (tp->size <= INT_MAX/2)
            texpand(tp, 2*tp->size);
        else
            internal_errorf(1, "too many vars");
        goto Search;
    }

    /* create new tbl entry */
    len = strlen(n) + 1;
    p = alloc(offsetof(struct tbl, name[0]) + len,
              tp->areap);
    p->flag = 0;
    p->type = 0;
    p->areap = tp->areap;
    p->u2.field = 0;
    p->u.array = NULL;
    memcpy(p->name, n, len);

    /* enter in tp->tbls */
    tp->nfree--;
    *pp = p;
    return p;
}
Example #28
0
static int
call_builtin(struct tbl *tp, const char **wp, const char *where, bool resetspec)
{
	int rv;

	if (!tp)
		internal_errorf("%s: %s", where, wp[0]);
	builtin_argv0 = wp[0];
	builtin_spec = tobool(!resetspec &&
	    /*XXX odd use of KEEPASN */
	    ((tp->flag & SPEC_BI) || (Flag(FPOSIX) && (tp->flag & KEEPASN))));
	shf_reopen(1, SHF_WR, shl_stdout);
	shl_stdout_ok = true;
	ksh_getopt_reset(&builtin_opt, GF_ERROR);
	rv = (*tp->val.f)(wp);
	shf_flush(shl_stdout);
	shl_stdout_ok = false;
	builtin_argv0 = NULL;
	builtin_spec = false;
	return (rv);
}
Example #29
0
File: shf.c Project: Open343/bitrig
/* Read up to a newline or EOF.  The newline is put in buf; buf is always
 * null terminated.  Returns NULL on read error or if nothing was read before
 * end of file, returns a pointer to the null byte in buf otherwise.
 */
char *
shf_getse(char *buf, int bsize, struct shf *shf)
{
	unsigned char *end;
	int ncopy;
	char *orig_buf = buf;

	if (!(shf->flags & SHF_RD))
		internal_errorf(1, "shf_getse: flags %x", shf->flags);

	if (bsize <= 0)
		return NULL;

	--bsize;	/* save room for null */
	do {
		if (shf->rnleft == 0) {
			if (shf_fillbuf(shf) == EOF)
				return NULL;
			if (shf->rnleft == 0) {
				*buf = '\0';
				return buf == orig_buf ? NULL : buf;
			}
		}
		end = (unsigned char *) memchr((char *) shf->rp, '\n',
		    shf->rnleft);
		ncopy = end ? end - shf->rp + 1 : shf->rnleft;
		if (ncopy > bsize)
			ncopy = bsize;
		memcpy(buf, (char *) shf->rp, ncopy);
		shf->rp += ncopy;
		shf->rnleft -= ncopy;
		buf += ncopy;
		bsize -= ncopy;
	} while (!end && bsize);
	*buf = '\0';
	return buf;
}
Example #30
0
/* control what signal is set to before an exec() */
void
setexecsig(Trap *p, int restore)
{
	/* XXX debugging */
	if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL)))
		internal_errorf(1, "setexecsig: unset signal %d(%s)",
		    p->signal, p->name);

	/* restore original value for exec'd kids */
	p->flags &= ~(TF_EXEC_IGN|TF_EXEC_DFL);
	switch (restore & SS_RESTORE_MASK) {
	case SS_RESTORE_CURR: /* leave things as they currently are */
		break;
	case SS_RESTORE_ORIG:
		p->flags |= p->flags & TF_ORIG_IGN ? TF_EXEC_IGN : TF_EXEC_DFL;
		break;
	case SS_RESTORE_DFL:
		p->flags |= TF_EXEC_DFL;
		break;
	case SS_RESTORE_IGN:
		p->flags |= TF_EXEC_IGN;
		break;
	}
}