Exemple #1
0
/*
 * _prop_object_externalize_write_file --
 *	Write an externalized dictionary to the specified file.
 *	The file is written atomically from the caller's perspective,
 *	and the mode set to 0666 modified by the caller's umask.
 */
bool
_prop_object_externalize_write_file(const char *fname, const char *xml,
    size_t len)
{
	char tname[PATH_MAX];
	int fd;
	int save_errno;
	mode_t myumask;

	if (len > SSIZE_MAX) {
		errno = EFBIG;
		return (false);
	}

	/*
	 * Get the directory name where the file is to be written
	 * and create the temporary file.
	 */
	_prop_object_externalize_file_dirname(fname, tname);
#define PLISTTMP "/.plistXXXXXX"
	if (strlen(tname) + strlen(PLISTTMP) >= sizeof(tname)) {
		errno = ENAMETOOLONG;
		return (false);
	}
	strcat(tname, PLISTTMP);
#undef PLISTTMP

	if ((fd = mkstemp(tname)) == -1)
		return (false);

	if (write(fd, xml, len) != (ssize_t)len)
		goto bad;

	if (fsync(fd) == -1)
		goto bad;

	myumask = umask(0);
	(void)umask(myumask);
	if (fchmod(fd, 0666 & ~myumask) == -1)
		goto bad;

	(void) close(fd);
	fd = -1;

	if (rename(tname, fname) == -1)
		goto bad;

	return (true);

 bad:
	save_errno = errno;
	if (fd != -1)
		(void) close(fd);
	(void) unlink(tname);
	errno = save_errno;
	return (false);
}
Exemple #2
0
/*
 * _prop_object_externalize_write_file --
 *	Write an externalized dictionary to the specified file.
 *	The file is written atomically from the caller's perspective,
 *	and the mode set to 0666 modified by the caller's umask.
 *
 *	The 'compress' argument enables gzip (via zlib) compression
 *	for the file to be written.
 */
bool
_prop_object_externalize_write_file(const char *fname, const char *xml,
    size_t len, bool do_compress)
{
	gzFile gzf = NULL;
	char tname[PATH_MAX];
	int fd;
	int save_errno;
	mode_t myumask;

	if (len > SSIZE_MAX) {
		errno = EFBIG;
		return (false);
	}

	/*
	 * Get the directory name where the file is to be written
	 * and create the temporary file.
	 */
	_prop_object_externalize_file_dirname(fname, tname);
#define PLISTTMP "/.plistXXXXXX"
	if (strlen(tname) + strlen(PLISTTMP) >= sizeof(tname)) {
		errno = ENAMETOOLONG;
		return (false);
	}
	strcat(tname, PLISTTMP);
#undef PLISTTMP

	if ((fd = mkstemp(tname)) == -1)
		return (false);

	if (do_compress) {
		if ((gzf = gzdopen(fd, "a")) == NULL)
			goto bad;

		if (gzsetparams(gzf, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY))
			goto bad;

		if (gzwrite(gzf, xml, len) != (ssize_t)len)
			goto bad;
	} else {
		if (write(fd, xml, len) != (ssize_t)len)
			goto bad;
	}

#ifdef HAVE_FDATASYNC
	if (fdatasync(fd) == -1)
#else
	if (fsync(fd) == -1)
#endif
		goto bad;

	myumask = umask(0);
	(void)umask(myumask);
	if (fchmod(fd, 0666 & ~myumask) == -1)
		goto bad;

	if (do_compress)
		(void)gzclose(gzf);
	else
		(void)close(fd);

	fd = -1;

	if (rename(tname, fname) == -1)
		goto bad;

	return (true);

 bad:
	save_errno = errno;
	if (do_compress && gzf != NULL)
		(void)gzclose(gzf);
	else if (fd != -1)
		(void)close(fd);
	(void) unlink(tname);
	errno = save_errno;
	return (false);
}