Example #1
0
static int create_text(int fd, unsigned char **text)
{
    size_t len = 0, buf_size = 16, rx;
    unsigned char *pend_seq = TEXT_END_SEQ;
    unsigned char *buf;

    buf_size = resize_buf(text, buf_size);
    while(buf_size) {
        buf = *text;
        if (receive(fd, &buf[len], 1, &rx) != 0 || rx == 0)
            goto bad_text;
        if (buf[len] == *pend_seq) {
            if (*++pend_seq == '\0')
                break;
        } else {
            pend_seq = TEXT_END_SEQ;
        }
        if (++len == buf_size)
            buf_size = resize_buf(text, buf_size);
    }
    if(len < 3 || !buf_size)
        goto bad_text;

    (*text)[len - 2] = '\0';
    return len - 2;
bad_text:
    if (buf_size)
        free(*text);
    *text = NULL;
    return 0;
}
Example #2
0
TwsXml::TwsXml() :
	file(NULL),
	buf_size(0),
	buf_len(0),
	buf(NULL),
	curDoc(NULL),
	curNode(NULL)
{
	resize_buf();
}
Example #3
0
/*
 * alloc_node()
 *	Allocate a new node
 *
 * Somewhat complicated because the file's storage structure is stored
 * at the front of the file.  We read in the first sector, then extend
 * the buffered block out to the indicated size.
 */
static struct openfile *
alloc_node(daddr_t d)
{
	struct buf *b;
	struct fs_file *fs;
	ulong len, fslen;
	struct openfile *o;

	/*
	 * Get buf, address first sector as an fs_file
	 */
	b = find_buf(d, 1, ABC_FILL);
	fs = index_buf(b, 0, 1);
	ASSERT(fs->fs_nblk > 0, "alloc_node: zero");
	ASSERT(fs->fs_blks[0].a_start == d, "alloc_node: mismatch");

	/*
	 * Extend the buf if necessary
	 */
	len = fs->fs_blks[0].a_len;
	fslen = fs->fs_len;
	if (len > 1) {
		if (len > EXTSIZ) {
			len = EXTSIZ;
		}
		if (resize_buf(d, (uint)len, 1)) {
			return(0);
		}
	}

	/*
	 * Create a new openfile and return it
	 */
	o = malloc(sizeof(struct openfile));
	if (o == 0) {
		return(0);
	}
	o->o_file = d;
	o->o_len = len;
	o->o_hiwrite = fslen;
	o->o_refs = 1;
	o->o_flags = 0;
	return(o);
}
Example #4
0
xmlDocPtr TwsXml::nextXmlDoc()
{
	xmlDocPtr doc = NULL;
	if( file == NULL ) {
		return doc;
	}

	/* This is ugly code. If we will rewrite it to use xml push parser then we
	   could avoid resize_buf(), memmove() and even find_form_feed(). */
	int jump_ff = 0;
	char *cp = buf;
	int tmp_len = buf_len;
	while( true ) {
		int ff = find_form_feed(cp, tmp_len);
		if( ff < tmp_len ) {
			cp += ff;
			jump_ff = 1;
			break;
		}
		cp += tmp_len;

		if( (buf_len + CHUNK_SIZE) >= buf_size ) {
			resize_buf();
			cp = buf + buf_len;
		}
		tmp_len = fread(cp, 1, CHUNK_SIZE, (FILE*)file);
		if( tmp_len <=0 ) {
			jump_ff = 0;
			break;
		}
		buf_len += tmp_len;
	}

	doc = xmlReadMemory( buf, cp-buf, "URL", NULL, 0 );

	buf_len -= cp - buf + jump_ff;
	memmove( buf, cp + jump_ff, buf_len );

	return doc;
}
Example #5
0
static int
read_whole_file(struct mparse *curp, const char *file, int fd,
		struct buf *fb, int *with_mmap)
{
	gzFile		 gz;
	size_t		 off;
	ssize_t		 ssz;

#if HAVE_MMAP
	struct stat	 st;

	if (fstat(fd, &st) == -1)
		err((int)MANDOCLEVEL_SYSERR, "%s", file);

	/*
	 * If we're a regular file, try just reading in the whole entry
	 * via mmap().  This is faster than reading it into blocks, and
	 * since each file is only a few bytes to begin with, I'm not
	 * concerned that this is going to tank any machines.
	 */

	if (curp->gzip == 0 && S_ISREG(st.st_mode)) {
		if (st.st_size > 0x7fffffff) {
			mandoc_msg(MANDOCERR_TOOLARGE, curp, 0, 0, NULL);
			return 0;
		}
		*with_mmap = 1;
		fb->sz = (size_t)st.st_size;
		fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0);
		if (fb->buf != MAP_FAILED)
			return 1;
	}
#endif

	if (curp->gzip) {
		if ((gz = gzdopen(fd, "rb")) == NULL)
			err((int)MANDOCLEVEL_SYSERR, "%s", file);
	} else
		gz = NULL;

	/*
	 * If this isn't a regular file (like, say, stdin), then we must
	 * go the old way and just read things in bit by bit.
	 */

	*with_mmap = 0;
	off = 0;
	fb->sz = 0;
	fb->buf = NULL;
	for (;;) {
		if (off == fb->sz) {
			if (fb->sz == (1U << 31)) {
				mandoc_msg(MANDOCERR_TOOLARGE, curp,
				    0, 0, NULL);
				break;
			}
			resize_buf(fb, 65536);
		}
		ssz = curp->gzip ?
		    gzread(gz, fb->buf + (int)off, fb->sz - off) :
		    read(fd, fb->buf + (int)off, fb->sz - off);
		if (ssz == 0) {
			fb->sz = off;
			return 1;
		}
		if (ssz == -1)
			err((int)MANDOCLEVEL_SYSERR, "%s", file);
		off += (size_t)ssz;
	}

	free(fb->buf);
	fb->buf = NULL;
	return 0;
}
Example #6
0
/*
 * Main parse routine for a buffer.
 * It assumes encoding and line numbering are already set up.
 * It can recurse directly (for invocations of user-defined
 * macros, inline equations, and input line traps)
 * and indirectly (for .so file inclusion).
 */
static void
mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
{
	const struct tbl_span	*span;
	struct buf	 ln;
	const char	*save_file;
	char		*cp;
	size_t		 pos; /* byte number in the ln buffer */
	enum rofferr	 rr;
	int		 of;
	int		 lnn; /* line number in the real file */
	int		 fd;
	unsigned char	 c;

	memset(&ln, 0, sizeof(ln));

	lnn = curp->line;
	pos = 0;

	while (i < blk.sz) {
		if (0 == pos && '\0' == blk.buf[i])
			break;

		if (start) {
			curp->line = lnn;
			curp->reparse_count = 0;

			if (lnn < 3 &&
			    curp->filenc & MPARSE_UTF8 &&
			    curp->filenc & MPARSE_LATIN1)
				curp->filenc = preconv_cue(&blk, i);
		}

		while (i < blk.sz && (start || blk.buf[i] != '\0')) {

			/*
			 * When finding an unescaped newline character,
			 * leave the character loop to process the line.
			 * Skip a preceding carriage return, if any.
			 */

			if ('\r' == blk.buf[i] && i + 1 < blk.sz &&
			    '\n' == blk.buf[i + 1])
				++i;
			if ('\n' == blk.buf[i]) {
				++i;
				++lnn;
				break;
			}

			/*
			 * Make sure we have space for the worst
			 * case of 11 bytes: "\\[u10ffff]\0"
			 */

			if (pos + 11 > ln.sz)
				resize_buf(&ln, 256);

			/*
			 * Encode 8-bit input.
			 */

			c = blk.buf[i];
			if (c & 0x80) {
				if ( ! (curp->filenc && preconv_encode(
				    &blk, &i, &ln, &pos, &curp->filenc))) {
					mandoc_vmsg(MANDOCERR_CHAR_BAD, curp,
					    curp->line, pos, "0x%x", c);
					ln.buf[pos++] = '?';
					i++;
				}
				continue;
			}

			/*
			 * Exclude control characters.
			 */

			if (c == 0x7f || (c < 0x20 && c != 0x09)) {
				mandoc_vmsg(c == 0x00 || c == 0x04 ||
				    c > 0x0a ? MANDOCERR_CHAR_BAD :
				    MANDOCERR_CHAR_UNSUPP,
				    curp, curp->line, pos, "0x%x", c);
				i++;
				if (c != '\r')
					ln.buf[pos++] = '?';
				continue;
			}

			/* Trailing backslash = a plain char. */

			if (blk.buf[i] != '\\' || i + 1 == blk.sz) {
				ln.buf[pos++] = blk.buf[i++];
				continue;
			}

			/*
			 * Found escape and at least one other character.
			 * When it's a newline character, skip it.
			 * When there is a carriage return in between,
			 * skip that one as well.
			 */

			if ('\r' == blk.buf[i + 1] && i + 2 < blk.sz &&
			    '\n' == blk.buf[i + 2])
				++i;
			if ('\n' == blk.buf[i + 1]) {
				i += 2;
				++lnn;
				continue;
			}

			if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) {
				i += 2;
				/* Comment, skip to end of line */
				for (; i < blk.sz; ++i) {
					if ('\n' == blk.buf[i]) {
						++i;
						++lnn;
						break;
					}
				}

				/* Backout trailing whitespaces */
				for (; pos > 0; --pos) {
					if (ln.buf[pos - 1] != ' ')
						break;
					if (pos > 2 && ln.buf[pos - 2] == '\\')
						break;
				}
				break;
			}

			/* Catch escaped bogus characters. */

			c = (unsigned char) blk.buf[i+1];

			if ( ! (isascii(c) &&
			    (isgraph(c) || isblank(c)))) {
				mandoc_vmsg(MANDOCERR_CHAR_BAD, curp,
				    curp->line, pos, "0x%x", c);
				i += 2;
				ln.buf[pos++] = '?';
				continue;
			}

			/* Some other escape sequence, copy & cont. */

			ln.buf[pos++] = blk.buf[i++];
			ln.buf[pos++] = blk.buf[i++];
		}

		if (pos >= ln.sz)
			resize_buf(&ln, 256);

		ln.buf[pos] = '\0';

		/*
		 * A significant amount of complexity is contained by
		 * the roff preprocessor.  It's line-oriented but can be
		 * expressed on one line, so we need at times to
		 * readjust our starting point and re-run it.  The roff
		 * preprocessor can also readjust the buffers with new
		 * data, so we pass them in wholesale.
		 */

		of = 0;

		/*
		 * Maintain a lookaside buffer of all parsed lines.  We
		 * only do this if mparse_keep() has been invoked (the
		 * buffer may be accessed with mparse_getkeep()).
		 */

		if (curp->secondary) {
			curp->secondary->buf = mandoc_realloc(
			    curp->secondary->buf,
			    curp->secondary->sz + pos + 2);
			memcpy(curp->secondary->buf +
			    curp->secondary->sz,
			    ln.buf, pos);
			curp->secondary->sz += pos;
			curp->secondary->buf
				[curp->secondary->sz] = '\n';
			curp->secondary->sz++;
			curp->secondary->buf
				[curp->secondary->sz] = '\0';
		}
rerun:
		rr = roff_parseln(curp->roff, curp->line, &ln, &of);

		switch (rr) {
		case ROFF_REPARSE:
			if (REPARSE_LIMIT >= ++curp->reparse_count)
				mparse_buf_r(curp, ln, of, 0);
			else
				mandoc_msg(MANDOCERR_ROFFLOOP, curp,
				    curp->line, pos, NULL);
			pos = 0;
			continue;
		case ROFF_APPEND:
			pos = strlen(ln.buf);
			continue;
		case ROFF_RERUN:
			goto rerun;
		case ROFF_IGN:
			pos = 0;
			continue;
		case ROFF_SO:
			if ( ! (curp->options & MPARSE_SO) &&
			    (i >= blk.sz || blk.buf[i] == '\0')) {
				curp->sodest = mandoc_strdup(ln.buf + of);
				free(ln.buf);
				return;
			}
			/*
			 * We remove `so' clauses from our lookaside
			 * buffer because we're going to descend into
			 * the file recursively.
			 */
			if (curp->secondary)
				curp->secondary->sz -= pos + 1;
			save_file = curp->file;
			if ((fd = mparse_open(curp, ln.buf + of)) != -1) {
				mparse_readfd(curp, fd, ln.buf + of);
				close(fd);
				curp->file = save_file;
			} else {
				curp->file = save_file;
				mandoc_vmsg(MANDOCERR_SO_FAIL,
				    curp, curp->line, pos,
				    ".so %s", ln.buf + of);
				ln.sz = mandoc_asprintf(&cp,
				    ".sp\nSee the file %s.\n.sp",
				    ln.buf + of);
				free(ln.buf);
				ln.buf = cp;
				of = 0;
				mparse_buf_r(curp, ln, of, 0);
			}
			pos = 0;
			continue;
		default:
			break;
		}

		/*
		 * If input parsers have not been allocated, do so now.
		 * We keep these instanced between parsers, but set them
		 * locally per parse routine since we can use different
		 * parsers with each one.
		 */

		if (curp->man == NULL ||
		    curp->man->macroset == MACROSET_NONE)
			choose_parser(curp);

		/*
		 * Lastly, push down into the parsers themselves.
		 * If libroff returns ROFF_TBL, then add it to the
		 * currently open parse.  Since we only get here if
		 * there does exist data (see tbl_data.c), we're
		 * guaranteed that something's been allocated.
		 * Do the same for ROFF_EQN.
		 */

		if (rr == ROFF_TBL)
			while ((span = roff_span(curp->roff)) != NULL)
				roff_addtbl(curp->man, span);
		else if (rr == ROFF_EQN)
			roff_addeqn(curp->man, roff_eqn(curp->roff));
		else if ((curp->man->macroset == MACROSET_MDOC ?
		    mdoc_parseln(curp->man, curp->line, ln.buf, of) :
		    man_parseln(curp->man, curp->line, ln.buf, of)) == 2)
				break;

		/* Temporary buffers typically are not full. */

		if (0 == start && '\0' == blk.buf[i])
			break;

		/* Start the next input line. */

		pos = 0;
	}

	free(ln.buf);
}
Example #7
0
static int
read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
{
	struct stat	 st;
	size_t		 off;
	ssize_t		 ssz;

	if (-1 == fstat(fd, &st)) {
		perror(file);
		return(0);
	}

	/*
	 * If we're a regular file, try just reading in the whole entry
	 * via mmap().  This is faster than reading it into blocks, and
	 * since each file is only a few bytes to begin with, I'm not
	 * concerned that this is going to tank any machines.
	 */

	if (S_ISREG(st.st_mode)) {
		if (st.st_size >= (1U << 31)) {
			fprintf(stderr, "%s: input too large\n", file);
			return(0);
		}
		*with_mmap = 1;
		fb->sz = (size_t)st.st_size;
		fb->buf = mmap(NULL, fb->sz, PROT_READ, 
				MAP_FILE|MAP_SHARED, fd, 0);
		if (fb->buf != MAP_FAILED)
			return(1);
	}

	/*
	 * If this isn't a regular file (like, say, stdin), then we must
	 * go the old way and just read things in bit by bit.
	 */

	*with_mmap = 0;
	off = 0;
	fb->sz = 0;
	fb->buf = NULL;
	for (;;) {
		if (off == fb->sz) {
			if (fb->sz == (1U << 31)) {
				fprintf(stderr, "%s: input too large\n", file);
				break;
			}
			resize_buf(fb, 65536);
		}
		ssz = read(fd, fb->buf + (int)off, fb->sz - off);
		if (ssz == 0) {
			fb->sz = off;
			return(1);
		}
		if (ssz == -1) {
			perror(file);
			break;
		}
		off += (size_t)ssz;
	}

	free(fb->buf);
	fb->buf = NULL;
	return(0);
}
Example #8
0
/*
 * Main parse routine for an opened file.  This is called for each
 * opened file and simply loops around the full input file, possibly
 * nesting (i.e., with `so').
 */
static void
mparse_buf_r(struct mparse *curp, struct buf blk, int start)
{
	const struct tbl_span	*span;
	struct buf	 ln;
	enum rofferr	 rr;
	int		 i, of, rc;
	int		 pos; /* byte number in the ln buffer */
	int		 lnn; /* line number in the real file */
	unsigned char	 c;

	memset(&ln, 0, sizeof(struct buf));

	lnn = curp->line; 
	pos = 0; 

	for (i = 0; i < (int)blk.sz; ) {
		if (0 == pos && '\0' == blk.buf[i])
			break;

		if (start) {
			curp->line = lnn;
			curp->reparse_count = 0;
		}

		while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) {

			/*
			 * When finding an unescaped newline character,
			 * leave the character loop to process the line.
			 * Skip a preceding carriage return, if any.
			 */

			if ('\r' == blk.buf[i] && i + 1 < (int)blk.sz &&
			    '\n' == blk.buf[i + 1])
				++i;
			if ('\n' == blk.buf[i]) {
				++i;
				++lnn;
				break;
			}

			/* 
			 * Warn about bogus characters.  If you're using
			 * non-ASCII encoding, you're screwing your
			 * readers.  Since I'd rather this not happen,
			 * I'll be helpful and drop these characters so
			 * we don't display gibberish.  Note to manual
			 * writers: use special characters.
			 */

			c = (unsigned char) blk.buf[i];

			if ( ! (isascii(c) && 
					(isgraph(c) || isblank(c)))) {
				mandoc_msg(MANDOCERR_BADCHAR, curp,
						curp->line, pos, "ignoring byte");
				i++;
				continue;
			}

			/* Trailing backslash = a plain char. */

			if ('\\' != blk.buf[i] || i + 1 == (int)blk.sz) {
				if (pos >= (int)ln.sz)
					resize_buf(&ln, 256);
				ln.buf[pos++] = blk.buf[i++];
				continue;
			}

			/*
			 * Found escape and at least one other character.
			 * When it's a newline character, skip it.
			 * When there is a carriage return in between,
			 * skip that one as well.
			 */

			if ('\r' == blk.buf[i + 1] && i + 2 < (int)blk.sz &&
			    '\n' == blk.buf[i + 2])
				++i;
			if ('\n' == blk.buf[i + 1]) {
				i += 2;
				++lnn;
				continue;
			}

			if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) {
				i += 2;
				/* Comment, skip to end of line */
				for (; i < (int)blk.sz; ++i) {
					if ('\n' == blk.buf[i]) {
						++i;
						++lnn;
						break;
					}
				}

				/* Backout trailing whitespaces */
				for (; pos > 0; --pos) {
					if (ln.buf[pos - 1] != ' ')
						break;
					if (pos > 2 && ln.buf[pos - 2] == '\\')
						break;
				}
				break;
			}

			/* Some other escape sequence, copy & cont. */

			if (pos + 1 >= (int)ln.sz)
				resize_buf(&ln, 256);

			ln.buf[pos++] = blk.buf[i++];
			ln.buf[pos++] = blk.buf[i++];
		}

 		if (pos >= (int)ln.sz)
			resize_buf(&ln, 256);

		ln.buf[pos] = '\0';

		/*
		 * A significant amount of complexity is contained by
		 * the roff preprocessor.  It's line-oriented but can be
		 * expressed on one line, so we need at times to
		 * readjust our starting point and re-run it.  The roff
		 * preprocessor can also readjust the buffers with new
		 * data, so we pass them in wholesale.
		 */

		of = 0;

		/*
		 * Maintain a lookaside buffer of all parsed lines.  We
		 * only do this if mparse_keep() has been invoked (the
		 * buffer may be accessed with mparse_getkeep()).
		 */

		if (curp->secondary) {
			curp->secondary->buf = 
				mandoc_realloc
				(curp->secondary->buf, 
				 curp->secondary->sz + pos + 2);
			memcpy(curp->secondary->buf + 
					curp->secondary->sz, 
					ln.buf, pos);
			curp->secondary->sz += pos;
			curp->secondary->buf
				[curp->secondary->sz] = '\n';
			curp->secondary->sz++;
			curp->secondary->buf
				[curp->secondary->sz] = '\0';
		}
rerun:
		rr = roff_parseln
			(curp->roff, curp->line, 
			 &ln.buf, &ln.sz, of, &of);

		switch (rr) {
		case (ROFF_REPARSE):
			if (REPARSE_LIMIT >= ++curp->reparse_count)
				mparse_buf_r(curp, ln, 0);
			else
				mandoc_msg(MANDOCERR_ROFFLOOP, curp,
					curp->line, pos, NULL);
			pos = 0;
			continue;
		case (ROFF_APPEND):
			pos = (int)strlen(ln.buf);
			continue;
		case (ROFF_RERUN):
			goto rerun;
		case (ROFF_IGN):
			pos = 0;
			continue;
		case (ROFF_ERR):
			assert(MANDOCLEVEL_FATAL <= curp->file_status);
			break;
		case (ROFF_SO):
			/*
			 * We remove `so' clauses from our lookaside
			 * buffer because we're going to descend into
			 * the file recursively.
			 */
			if (curp->secondary) 
				curp->secondary->sz -= pos + 1;
			mparse_readfd_r(curp, -1, ln.buf + of, 1);
			if (MANDOCLEVEL_FATAL <= curp->file_status)
				break;
			pos = 0;
			continue;
		default:
			break;
		}

		/*
		 * If we encounter errors in the recursive parse, make
		 * sure we don't continue parsing.
		 */

		if (MANDOCLEVEL_FATAL <= curp->file_status)
			break;

		/*
		 * If input parsers have not been allocated, do so now.
		 * We keep these instanced between parsers, but set them
		 * locally per parse routine since we can use different
		 * parsers with each one.
		 */

		if ( ! (curp->man || curp->mdoc))
			pset(ln.buf + of, pos - of, curp);

		/* 
		 * Lastly, push down into the parsers themselves.  One
		 * of these will have already been set in the pset()
		 * routine.
		 * If libroff returns ROFF_TBL, then add it to the
		 * currently open parse.  Since we only get here if
		 * there does exist data (see tbl_data.c), we're
		 * guaranteed that something's been allocated.
		 * Do the same for ROFF_EQN.
		 */

		rc = -1;

		if (ROFF_TBL == rr)
			while (NULL != (span = roff_span(curp->roff))) {
				rc = curp->man ?
					man_addspan(curp->man, span) :
					mdoc_addspan(curp->mdoc, span);
				if (0 == rc)
					break;
			}
		else if (ROFF_EQN == rr)
			rc = curp->mdoc ? 
				mdoc_addeqn(curp->mdoc, 
					roff_eqn(curp->roff)) :
				man_addeqn(curp->man,
					roff_eqn(curp->roff));
		else if (curp->man || curp->mdoc)
			rc = curp->man ?
				man_parseln(curp->man, 
					curp->line, ln.buf, of) :
				mdoc_parseln(curp->mdoc, 
					curp->line, ln.buf, of);

		if (0 == rc) {
			assert(MANDOCLEVEL_FATAL <= curp->file_status);
			break;
		}

		/* Temporary buffers typically are not full. */

		if (0 == start && '\0' == blk.buf[i])
			break;

		/* Start the next input line. */

		pos = 0;
	}

	free(ln.buf);
}
Example #9
0
static void buf_add_str(ErlNifEnv* env, int buf_len, struct buf *rbuf, char *data, int len)
{
    resize_buf(env, buf_len, rbuf, len);
    memcpy(rbuf->b + rbuf->len, data, len);
    rbuf->len += len;
}
Example #10
0
static void buf_add_char(ErlNifEnv* env, int buf_len, struct buf *rbuf, unsigned char c)
{
    resize_buf(env, buf_len, rbuf, 1);
    (rbuf->b)[rbuf->len] = c;
    rbuf->len += 1;
}
Example #11
0
void speed()
{
        int keyboard = _open("/dev/keyboard", 0, 0);
        int stdin = _open("/dev/stdin", 0, 0);
        char ch;
        int fd = _open(active_proc->name, 0, 0);
        int size = _seek(fd, 0, SEEK_END);
        size++; //terminating '\0'
        _seek(fd, 0, SEEK_SET);
        char* str = _malloc(size);
        bzero(str, size);
        _read(fd, str, size);
        line *startline = _malloc(sizeof(line));
        startline->num_chars=0;
        startline->offset=0;
        startline->next = NULL;
        startline->prev = NULL;
        line * actualline = startline;

        int pos = 0;
        while (str[pos]!='\0') {
                _printf("%c", str[pos]);
                if(str[pos] == '\n' || str[pos] == '\t') {
                        NEXT_LINE
                } else {
                        actualline->num_chars++;
                }
                pos++;
                if(pos == size - 1) { //terminating \0
                        size*=2;
                        str = resize_buf(size, str);
                }
        }
        _close(fd);

        //flush stdin
        while (_read(stdin, &ch, sizeof(ch)) != 0) ;

        while (!keydown(ESCAPE, keyboard)) {
                if(pos == size - 1) { //terminating \0
                        size *= 2;
                        str = resize_buf(size, str);
                }
                ch = _fgetch(stdin);
                switch(ch){
                case '\a':
                        break;
                case '\b':
                        if(actualline == startline && startline->num_chars == 0) { //nothing to erase
                                break;
                        }
                        if(str[pos - 1]=='\n' || str[pos - 1]=='\t') { //erase '\n' or '\t'
                                PREV_LINE
                        } else { //erase 1 character
                                actualline->num_chars--;
                                _printf("%c", ch);
                        }
                        str[--pos] = '\0';
                        if (pos == size / 4 - 1) {
                                size /= 2;
                                str = resize_buf(size, str);
                        }
                        break;
                default:
                        _printf("%c", ch);
                        str[pos] = ch;
                        if(ch == '\n' || ch == '\t') {
                                NEXT_LINE
                        } else {
                                actualline->num_chars++;
                        }
                        pos++;
                }
        }

        //flush stdin
        while (_read(stdin, &ch, sizeof(ch)) != 0) ;
        //DUMP_LINES
        _unlink(active_proc->name);
        //        fd = _open(active_proc->name, 0, 0);
        //        int fsize = _seek(fd, 0, SEEK_END);
        //        _close(fd);
        //        fd = _open(active_proc->name, 0, 0);
        //        char* nullstring = _malloc(fsize);
        //        bzero(nullstring, fsize);
        //        _free(nullstring);
        //        _write(fd, nullstring, fsize);
        //        _close(fd);

        fd = _open(active_proc->name, O_CREAT, 0);
        _write(fd, str, strlen(str));
        for(line *temp = startline; temp != NULL; temp = temp->next) {
                _free(temp);
        }
        _free(str);
        _close(keyboard);
        _close(stdin);
        _close(fd);
        _exit(0);
}
Example #12
0
static int
read_whole_file(struct mparse *curp, const char *file, int fd,
		struct buf *fb, int *with_mmap)
{
	size_t		 off;
	ssize_t		 ssz;

#ifdef	HAVE_MMAP
	struct stat	 st;
	if (-1 == fstat(fd, &st)) {
		curp->file_status = MANDOCLEVEL_SYSERR;
		if (curp->mmsg)
			(*curp->mmsg)(MANDOCERR_SYSSTAT, curp->file_status,
			    file, 0, 0, strerror(errno));
		return(0);
	}

	/*
	 * If we're a regular file, try just reading in the whole entry
	 * via mmap().  This is faster than reading it into blocks, and
	 * since each file is only a few bytes to begin with, I'm not
	 * concerned that this is going to tank any machines.
	 */

	if (S_ISREG(st.st_mode)) {
		if (st.st_size >= (1U << 31)) {
			curp->file_status = MANDOCLEVEL_FATAL;
			if (curp->mmsg)
				(*curp->mmsg)(MANDOCERR_TOOLARGE,
				    curp->file_status, file, 0, 0, NULL);
			return(0);
		}
		*with_mmap = 1;
		fb->sz = (size_t)st.st_size;
		fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0);
		if (fb->buf != MAP_FAILED)
			return(1);
	}
#endif

	/*
	 * If this isn't a regular file (like, say, stdin), then we must
	 * go the old way and just read things in bit by bit.
	 */

	*with_mmap = 0;
	off = 0;
	fb->sz = 0;
	fb->buf = NULL;
	for (;;) {
		if (off == fb->sz) {
			if (fb->sz == (1U << 31)) {
				curp->file_status = MANDOCLEVEL_FATAL;
				if (curp->mmsg)
					(*curp->mmsg)(MANDOCERR_TOOLARGE,
					    curp->file_status,
					    file, 0, 0, NULL);
				break;
			}
			resize_buf(fb, 65536);
		}
		ssz = read(fd, fb->buf + (int)off, fb->sz - off);
		if (ssz == 0) {
			fb->sz = off;
			return(1);
		}
		if (ssz == -1) {
			curp->file_status = MANDOCLEVEL_SYSERR;
			if (curp->mmsg)
				(*curp->mmsg)(MANDOCERR_SYSREAD,
				    curp->file_status, file, 0, 0,
				    strerror(errno));
			break;
		}
		off += (size_t)ssz;
	}

	free(fb->buf);
	fb->buf = NULL;
	return(0);
}