示例#1
0
/*
 * _prop_object_internalize_context_alloc --
 *	Allocate an internalize context.
 */
struct _prop_object_internalize_context *
_prop_object_internalize_context_alloc(const char *xml)
{
	struct _prop_object_internalize_context *ctx;

	ctx = _PROP_MALLOC(sizeof(struct _prop_object_internalize_context),
			   M_TEMP);
	if (ctx == NULL)
		return (NULL);
	
	ctx->poic_xml = ctx->poic_cp = xml;

	/*
	 * Skip any whitespace and XML preamble stuff that we don't
	 * know about / care about.
	 */
	for (;;) {
		while (_PROP_ISSPACE(*xml))
			xml++;
		if (_PROP_EOF(*xml) || *xml != '<')
			goto bad;

#define	MATCH(str)	(memcmp(&xml[1], str, sizeof(str) - 1) == 0)

		/*
		 * Skip over the XML preamble that Apple XML property
		 * lists usually include at the top of the file.
		 */
		if (MATCH("?xml ") ||
		    MATCH("!DOCTYPE plist")) {
			while (*xml != '>' && !_PROP_EOF(*xml))
				xml++;
			if (_PROP_EOF(*xml))
				goto bad;
			xml++;	/* advance past the '>' */
			continue;
		}

		if (MATCH("<!--")) {
			ctx->poic_cp = xml + 4;
			if (_prop_object_internalize_skip_comment(ctx) == false)
				goto bad;
			xml = ctx->poic_cp;
			continue;
		}

#undef MATCH

		/*
		 * We don't think we should skip it, so let's hope we can
		 * parse it.
		 */
		break;
	}

	ctx->poic_cp = xml;
	return (ctx);
 bad:
	_PROP_FREE(ctx, M_TEMP);
	return (NULL);
}
示例#2
0
/*
 * _prop_object_internalize_map_file --
 *	Map a file for the purpose of internalizing it.
 */
struct _prop_object_internalize_mapped_file *
_prop_object_internalize_map_file(const char *fname)
{
	struct stat sb;
	struct _prop_object_internalize_mapped_file *mf;
	size_t pgsize = (size_t)sysconf(_SC_PAGESIZE);
	size_t pgmask = pgsize - 1;
	bool need_guard = false;
	int fd;

	mf = _PROP_MALLOC(sizeof(*mf), M_TEMP);
	if (mf == NULL)
		return (NULL);
	
	fd = open(fname, O_RDONLY, 0400);
	if (fd == -1) {
		_PROP_FREE(mf, M_TEMP);
		return (NULL);
	}

	if (fstat(fd, &sb) == -1) {
		(void) close(fd);
		_PROP_FREE(mf, M_TEMP);
		return (NULL);
	}
	mf->poimf_mapsize = ((size_t)sb.st_size + pgmask) & ~pgmask;
	if (mf->poimf_mapsize < (size_t)sb.st_size) {
		(void) close(fd);
		_PROP_FREE(mf, M_TEMP);
		return (NULL);
	}

	/*
	 * If the file length is an integral number of pages, then we
	 * need to map a guard page at the end in order to provide the
	 * necessary NUL-termination of the buffer.
	 */
	if ((sb.st_size & pgmask) == 0)
		need_guard = true;

	mf->poimf_xml = mmap(NULL, need_guard ? mf->poimf_mapsize + pgsize
			    		      : mf->poimf_mapsize,
			    PROT_READ, MAP_FILE|MAP_SHARED, fd, (off_t)0);
	(void) close(fd);
	if (mf->poimf_xml == MAP_FAILED) {
		_PROP_FREE(mf, M_TEMP);
		return (NULL);
	}

#ifndef __minix
	(void) madvise(mf->poimf_xml, mf->poimf_mapsize, MADV_SEQUENTIAL);

	if (need_guard) {
		if (mmap(mf->poimf_xml + mf->poimf_mapsize,
			 pgsize, PROT_READ,
			 MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1,
			 (off_t)0) == MAP_FAILED) {
			(void) munmap(mf->poimf_xml, mf->poimf_mapsize);
			_PROP_FREE(mf, M_TEMP);
			return (NULL);
		}
		mf->poimf_mapsize += pgsize;
	}
#endif

	return (mf);
}