Blame src/fccompat.c

Packit 352660
/*
Packit 352660
 * fontconfig/src/fccompat.c
Packit 352660
 *
Packit 352660
 * Copyright © 2012 Red Hat, Inc.
Packit 352660
 *
Packit 352660
 * Author(s):
Packit 352660
 *  Akira TAGOH
Packit 352660
 *
Packit 352660
 * Permission to use, copy, modify, distribute, and sell this software and its
Packit 352660
 * documentation for any purpose is hereby granted without fee, provided that
Packit 352660
 * the above copyright notice appear in all copies and that both that
Packit 352660
 * copyright notice and this permission notice appear in supporting
Packit 352660
 * documentation, and that the name of the author(s) not be used in
Packit 352660
 * advertising or publicity pertaining to distribution of the software without
Packit 352660
 * specific, written prior permission.  The authors make no
Packit 352660
 * representations about the suitability of this software for any purpose.  It
Packit 352660
 * is provided "as is" without express or implied warranty.
Packit 352660
 *
Packit 352660
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
Packit 352660
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
Packit 352660
 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
Packit 352660
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
Packit 352660
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
Packit 352660
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
Packit 352660
 * PERFORMANCE OF THIS SOFTWARE.
Packit 352660
 */
Packit 352660
Packit 352660
#include "fcint.h"
Packit 352660
Packit 352660
#include <errno.h>
Packit 352660
#if HAVE_SYS_TYPES_H
Packit 352660
#include <sys/types.h>
Packit 352660
#endif
Packit 352660
#if HAVE_SYS_STAT_H
Packit 352660
#include <sys/stat.h>
Packit 352660
#endif
Packit 352660
#if HAVE_FCNTL_H
Packit 352660
#include <fcntl.h>
Packit 352660
#endif
Packit 352660
#if HAVE_UNISTD_H
Packit 352660
#include <unistd.h>
Packit 352660
#endif
Packit 352660
#include <stdarg.h>
Packit 352660
#include <stdlib.h>
Packit 352660
#include <string.h>
Packit 352660
#include <time.h>
Packit 352660
Packit 352660
#ifdef O_CLOEXEC
Packit 352660
#define FC_O_CLOEXEC O_CLOEXEC
Packit 352660
#else
Packit 352660
#define FC_O_CLOEXEC 0
Packit 352660
#endif
Packit 352660
#ifdef O_LARGEFILE
Packit 352660
#define FC_O_LARGEFILE O_LARGEFILE
Packit 352660
#else
Packit 352660
#define FC_O_LARGEFILE 0
Packit 352660
#endif
Packit 352660
#ifdef O_BINARY
Packit 352660
#define FC_O_BINARY O_BINARY
Packit 352660
#else
Packit 352660
#define FC_O_BINARY 0
Packit 352660
#endif
Packit 352660
#ifdef O_TEMPORARY
Packit 352660
#define FC_O_TEMPORARY O_TEMPORARY
Packit 352660
#else
Packit 352660
#define FC_O_TEMPORARY 0
Packit 352660
#endif
Packit 352660
#ifdef O_NOINHERIT
Packit 352660
#define FC_O_NOINHERIT O_NOINHERIT
Packit 352660
#else
Packit 352660
#define FC_O_NOINHERIT 0
Packit 352660
#endif
Packit 352660
Packit 352660
#if !defined (HAVE_MKOSTEMP) && !defined(HAVE_MKSTEMP) && !defined(HAVE__MKTEMP_S)
Packit 352660
static int
Packit 352660
mkstemp (char *template)
Packit 352660
{
Packit 352660
    static const char s[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
Packit 352660
    int fd, i;
Packit 352660
    size_t l;
Packit 352660
Packit 352660
    if (template == NULL)
Packit 352660
    {
Packit 352660
	errno = EINVAL;
Packit 352660
	return -1;
Packit 352660
    }
Packit 352660
    l = strlen (template);
Packit 352660
    if (l < 6 || strcmp (&template[l - 6], "XXXXXX") != 0)
Packit 352660
    {
Packit 352660
	errno = EINVAL;
Packit 352660
	return -1;
Packit 352660
    }
Packit 352660
    do
Packit 352660
    {
Packit 352660
	errno = 0;
Packit 352660
	for (i = l - 6; i < l; i++)
Packit 352660
	{
Packit 352660
	    int r = FcRandom ();
Packit 352660
	    template[i] = s[r % 62];
Packit 352660
	}
Packit 352660
	fd = FcOpen (template, FC_O_BINARY | O_CREAT | O_EXCL | FC_O_TEMPORARY | FC_O_NOINHERIT | O_RDWR, 0600);
Packit 352660
    } while (fd < 0 && errno == EEXIST);
Packit 352660
    if (fd >= 0)
Packit 352660
	errno = 0;
Packit 352660
Packit 352660
    return fd;
Packit 352660
}
Packit 352660
#define HAVE_MKSTEMP 1
Packit 352660
#endif
Packit 352660
Packit 352660
int
Packit 352660
FcOpen(const char *pathname, int flags, ...)
Packit 352660
{
Packit 352660
    int fd = -1;
Packit 352660
Packit 352660
    if (flags & O_CREAT)
Packit 352660
    {
Packit 352660
	va_list ap;
Packit 352660
	mode_t mode;
Packit 352660
Packit 352660
	va_start(ap, flags);
Packit 352660
	mode = (mode_t) va_arg(ap, int);
Packit 352660
	va_end(ap);
Packit 352660
Packit 352660
	fd = open(pathname, flags | FC_O_CLOEXEC | FC_O_LARGEFILE, mode);
Packit 352660
    }
Packit 352660
    else
Packit 352660
    {
Packit 352660
	fd = open(pathname, flags | FC_O_CLOEXEC | FC_O_LARGEFILE);
Packit 352660
    }
Packit 352660
Packit 352660
    return fd;
Packit 352660
}
Packit 352660
Packit 352660
int
Packit 352660
FcMakeTempfile (char *template)
Packit 352660
{
Packit 352660
    int fd = -1;
Packit 352660
Packit 352660
#if HAVE_MKOSTEMP
Packit 352660
    fd = mkostemp (template, FC_O_CLOEXEC);
Packit 352660
#elif HAVE_MKSTEMP
Packit 352660
    fd = mkstemp (template);
Packit 352660
#  ifdef F_DUPFD_CLOEXEC
Packit 352660
    if (fd != -1)
Packit 352660
    {
Packit 352660
	int newfd = fcntl(fd, F_DUPFD_CLOEXEC, STDIN_FILENO);
Packit 352660
Packit 352660
	close(fd);
Packit 352660
	fd = newfd;
Packit 352660
    }
Packit 352660
#  elif defined(FD_CLOEXEC)
Packit 352660
    if (fd != -1)
Packit 352660
    {
Packit 352660
	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
Packit 352660
    }
Packit 352660
#  endif
Packit 352660
#elif HAVE__MKTEMP_S
Packit 352660
   if (_mktemp_s(template, strlen(template) + 1) != 0)
Packit 352660
       return -1;
Packit 352660
   fd = FcOpen(template, O_RDWR | O_EXCL | O_CREAT, 0600);
Packit 352660
#endif
Packit 352660
Packit 352660
    return fd;
Packit 352660
}
Packit 352660
Packit 352660
int32_t
Packit 352660
FcRandom(void)
Packit 352660
{
Packit 352660
    int32_t result;
Packit 352660
Packit 352660
#if HAVE_RANDOM_R
Packit 352660
    static struct random_data fcrandbuf;
Packit 352660
    static char statebuf[256];
Packit 352660
    static FcBool initialized = FcFalse;
Packit 352660
#ifdef _AIX
Packit 352660
    static char *retval;
Packit 352660
    long res;
Packit 352660
#endif
Packit 352660
Packit 352660
    if (initialized != FcTrue)
Packit 352660
    {
Packit 352660
#ifdef _AIX
Packit 352660
	initstate_r (time (NULL), statebuf, 256, &retval, &fcrandbuf);
Packit 352660
#else
Packit 352660
	initstate_r (time (NULL), statebuf, 256, &fcrandbuf);
Packit 352660
#endif
Packit 352660
	initialized = FcTrue;
Packit 352660
    }
Packit 352660
Packit 352660
#ifdef _AIX
Packit 352660
    random_r (&res, &fcrandbuf);
Packit 352660
    result = (int32_t)res;
Packit 352660
#else
Packit 352660
    random_r (&fcrandbuf, &result);
Packit 352660
#endif
Packit 352660
#elif HAVE_RANDOM
Packit 352660
    static char statebuf[256];
Packit 352660
    char *state;
Packit 352660
    static FcBool initialized = FcFalse;
Packit 352660
Packit 352660
    if (initialized != FcTrue)
Packit 352660
    {
Packit 352660
	state = initstate (time (NULL), statebuf, 256);
Packit 352660
	initialized = FcTrue;
Packit 352660
    }
Packit 352660
    else
Packit 352660
	state = setstate (statebuf);
Packit 352660
Packit 352660
    result = random ();
Packit 352660
Packit 352660
    setstate (state);
Packit 352660
#elif HAVE_LRAND48
Packit 352660
    result = lrand48 ();
Packit 352660
#elif HAVE_RAND_R
Packit 352660
    static unsigned int seed = time (NULL);
Packit 352660
Packit 352660
    result = rand_r (&seed);
Packit 352660
#elif HAVE_RAND
Packit 352660
    static FcBool initialized = FcFalse;
Packit 352660
Packit 352660
    if (initialized != FcTrue)
Packit 352660
    {
Packit 352660
	srand (time (NULL));
Packit 352660
	initialized = FcTrue;
Packit 352660
    }
Packit 352660
    result = rand ();
Packit 352660
#else
Packit 352660
# error no random number generator function available.
Packit 352660
#endif
Packit 352660
Packit 352660
    return result;
Packit 352660
}
Packit 352660
Packit 352660
#ifdef _WIN32
Packit 352660
#include <direct.h>
Packit 352660
#define mkdir(path,mode) _mkdir(path)
Packit 352660
#endif
Packit 352660
Packit 352660
FcBool
Packit 352660
FcMakeDirectory (const FcChar8 *dir)
Packit 352660
{
Packit 352660
    FcChar8 *parent;
Packit 352660
    FcBool  ret;
Packit 352660
Packit 352660
    if (strlen ((char *) dir) == 0)
Packit 352660
	return FcFalse;
Packit 352660
Packit 352660
    parent = FcStrDirname (dir);
Packit 352660
    if (!parent)
Packit 352660
	return FcFalse;
Packit 352660
    if (access ((char *) parent, F_OK) == 0)
Packit 352660
	ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0;
Packit 352660
    else if (access ((char *) parent, F_OK) == -1)
Packit 352660
	ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0;
Packit 352660
    else
Packit 352660
	ret = FcFalse;
Packit 352660
    FcStrFree (parent);
Packit 352660
    return ret;
Packit 352660
}
Packit 352660
Packit 352660
ssize_t
Packit 352660
FcReadLink (const FcChar8 *pathname,
Packit 352660
	    FcChar8       *buf,
Packit 352660
	    size_t         bufsiz)
Packit 352660
{
Packit 352660
#ifdef HAVE_READLINK
Packit 352660
    return readlink ((const char *) pathname, (char *)buf, bufsiz);
Packit 352660
#else
Packit 352660
    /* XXX: this function is only used for FcConfigRealFilename() so far
Packit 352660
     * and returning -1 as an error still just works.
Packit 352660
     */
Packit 352660
    errno = ENOSYS;
Packit 352660
    return -1;
Packit 352660
#endif
Packit 352660
}
Packit 352660
Packit 352660
#define __fccompat__
Packit 352660
#include "fcaliastail.h"
Packit 352660
#undef __fccompat__