fccompat.c revision 953daeba
1c9710b42Smrg/* 2c9710b42Smrg * fontconfig/src/fccompat.c 3c9710b42Smrg * 4c9710b42Smrg * Copyright © 2012 Red Hat, Inc. 5c9710b42Smrg * 6c9710b42Smrg * Author(s): 7c9710b42Smrg * Akira TAGOH 8c9710b42Smrg * 9c9710b42Smrg * Permission to use, copy, modify, distribute, and sell this software and its 10c9710b42Smrg * documentation for any purpose is hereby granted without fee, provided that 11c9710b42Smrg * the above copyright notice appear in all copies and that both that 12c9710b42Smrg * copyright notice and this permission notice appear in supporting 13c9710b42Smrg * documentation, and that the name of the author(s) not be used in 14c9710b42Smrg * advertising or publicity pertaining to distribution of the software without 15c9710b42Smrg * specific, written prior permission. The authors make no 16c9710b42Smrg * representations about the suitability of this software for any purpose. It 17c9710b42Smrg * is provided "as is" without express or implied warranty. 18c9710b42Smrg * 19c9710b42Smrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 20c9710b42Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 21c9710b42Smrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR 22c9710b42Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 23c9710b42Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 24c9710b42Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 25c9710b42Smrg * PERFORMANCE OF THIS SOFTWARE. 26c9710b42Smrg */ 27c9710b42Smrg 28c9710b42Smrg#include "fcint.h" 29c9710b42Smrg 30c9710b42Smrg#include <errno.h> 31c9710b42Smrg#if HAVE_SYS_TYPES_H 32c9710b42Smrg#include <sys/types.h> 33c9710b42Smrg#endif 34c9710b42Smrg#if HAVE_SYS_STAT_H 35c9710b42Smrg#include <sys/stat.h> 36c9710b42Smrg#endif 37c9710b42Smrg#if HAVE_FCNTL_H 38c9710b42Smrg#include <fcntl.h> 39c9710b42Smrg#endif 40c9710b42Smrg#include <stdarg.h> 41c9710b42Smrg#include <stdlib.h> 42c9710b42Smrg#include <string.h> 43c9710b42Smrg#include <time.h> 44c9710b42Smrg 45c9710b42Smrg#ifdef O_CLOEXEC 46c9710b42Smrg#define FC_O_CLOEXEC O_CLOEXEC 47c9710b42Smrg#else 48c9710b42Smrg#define FC_O_CLOEXEC 0 49c9710b42Smrg#endif 50c9710b42Smrg#ifdef O_LARGEFILE 51c9710b42Smrg#define FC_O_LARGEFILE O_LARGEFILE 52c9710b42Smrg#else 53c9710b42Smrg#define FC_O_LARGEFILE 0 54c9710b42Smrg#endif 55c9710b42Smrg#ifdef O_BINARY 56c9710b42Smrg#define FC_O_BINARY O_BINARY 57c9710b42Smrg#else 58c9710b42Smrg#define FC_O_BINARY 0 59c9710b42Smrg#endif 60c9710b42Smrg#ifdef O_TEMPORARY 61c9710b42Smrg#define FC_O_TEMPORARY O_TEMPORARY 62c9710b42Smrg#else 63c9710b42Smrg#define FC_O_TEMPORARY 0 64c9710b42Smrg#endif 65c9710b42Smrg#ifdef O_NOINHERIT 66c9710b42Smrg#define FC_O_NOINHERIT O_NOINHERIT 67c9710b42Smrg#else 68c9710b42Smrg#define FC_O_NOINHERIT 0 69c9710b42Smrg#endif 70c9710b42Smrg 71c9710b42Smrg#if !defined (HAVE_MKOSTEMP) && !defined(HAVE_MKSTEMP) && !defined(HAVE__MKTEMP_S) 72c9710b42Smrgstatic int 73c9710b42Smrgmkstemp (char *template) 74c9710b42Smrg{ 75c9710b42Smrg static const char s[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 76c9710b42Smrg int fd, i; 77c9710b42Smrg size_t l; 78c9710b42Smrg 79c9710b42Smrg if (template == NULL) 80c9710b42Smrg { 81c9710b42Smrg errno = EINVAL; 82c9710b42Smrg return -1; 83c9710b42Smrg } 84c9710b42Smrg l = strlen (template); 85c9710b42Smrg if (l < 6 || strcmp (&template[l - 6], "XXXXXX") != 0) 86c9710b42Smrg { 87c9710b42Smrg errno = EINVAL; 88c9710b42Smrg return -1; 89c9710b42Smrg } 90c9710b42Smrg do 91c9710b42Smrg { 92c9710b42Smrg errno = 0; 93c9710b42Smrg for (i = l - 6; i < l; i++) 94c9710b42Smrg { 95c9710b42Smrg int r = FcRandom (); 96c9710b42Smrg template[i] = s[r % 62]; 97c9710b42Smrg } 98c9710b42Smrg fd = FcOpen (template, FC_O_BINARY | O_CREAT | O_EXCL | FC_O_TEMPORARY | FC_O_NOINHERIT | O_RDWR, 0600); 99c9710b42Smrg } while (fd < 0 && errno == EEXIST); 100c9710b42Smrg if (fd >= 0) 101c9710b42Smrg errno = 0; 102c9710b42Smrg 103c9710b42Smrg return fd; 104c9710b42Smrg} 105c9710b42Smrg#define HAVE_MKSTEMP 1 106c9710b42Smrg#endif 107c9710b42Smrg 108c9710b42Smrgint 109c9710b42SmrgFcOpen(const char *pathname, int flags, ...) 110c9710b42Smrg{ 111c9710b42Smrg int fd = -1; 112c9710b42Smrg 113c9710b42Smrg if (flags & O_CREAT) 114c9710b42Smrg { 115c9710b42Smrg va_list ap; 116c9710b42Smrg mode_t mode; 117c9710b42Smrg 118c9710b42Smrg va_start(ap, flags); 119c9710b42Smrg mode = (mode_t) va_arg(ap, int); 120c9710b42Smrg va_end(ap); 121c9710b42Smrg 122c9710b42Smrg fd = open(pathname, flags | FC_O_CLOEXEC | FC_O_LARGEFILE, mode); 123c9710b42Smrg } 124c9710b42Smrg else 125c9710b42Smrg { 126c9710b42Smrg fd = open(pathname, flags | FC_O_CLOEXEC | FC_O_LARGEFILE); 127c9710b42Smrg } 128c9710b42Smrg 129c9710b42Smrg return fd; 130c9710b42Smrg} 131c9710b42Smrg 132c9710b42Smrgint 133c9710b42SmrgFcMakeTempfile (char *template) 134c9710b42Smrg{ 135c9710b42Smrg int fd = -1; 136c9710b42Smrg 137c9710b42Smrg#if HAVE_MKOSTEMP 138c9710b42Smrg fd = mkostemp (template, FC_O_CLOEXEC); 139c9710b42Smrg#elif HAVE_MKSTEMP 140c9710b42Smrg fd = mkstemp (template); 141c9710b42Smrg# ifdef F_DUPFD_CLOEXEC 142c9710b42Smrg if (fd != -1) 143c9710b42Smrg { 144c9710b42Smrg int newfd = fcntl(fd, F_DUPFD_CLOEXEC, STDIN_FILENO); 145c9710b42Smrg 146c9710b42Smrg close(fd); 147c9710b42Smrg fd = newfd; 148c9710b42Smrg } 149c9710b42Smrg# elif defined(FD_CLOEXEC) 150c9710b42Smrg if (fd != -1) 151c9710b42Smrg { 152c9710b42Smrg fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); 153c9710b42Smrg } 154c9710b42Smrg# endif 155c9710b42Smrg#elif HAVE__MKTEMP_S 156c9710b42Smrg if (_mktemp_s(template, strlen(template) + 1) != 0) 157c9710b42Smrg return -1; 158c9710b42Smrg fd = FcOpen(template, O_RDWR | O_EXCL | O_CREAT, 0600); 159c9710b42Smrg#endif 160c9710b42Smrg 161c9710b42Smrg return fd; 162c9710b42Smrg} 163c9710b42Smrg 164c9710b42Smrgint32_t 165c9710b42SmrgFcRandom(void) 166c9710b42Smrg{ 167c9710b42Smrg int32_t result; 168c9710b42Smrg 169c9710b42Smrg#if HAVE_RANDOM_R 170c9710b42Smrg static struct random_data fcrandbuf; 171c9710b42Smrg static char statebuf[256]; 172c9710b42Smrg static FcBool initialized = FcFalse; 173b09479dcSmrg#ifdef _AIX 174b09479dcSmrg static char *retval; 175b09479dcSmrg long res; 176b09479dcSmrg#endif 177c9710b42Smrg 178c9710b42Smrg if (initialized != FcTrue) 179c9710b42Smrg { 180b09479dcSmrg#ifdef _AIX 181b09479dcSmrg initstate_r (time (NULL), statebuf, 256, &retval, &fcrandbuf); 182b09479dcSmrg#else 183b09479dcSmrg initstate_r (time (NULL), statebuf, 256, &fcrandbuf); 184b09479dcSmrg#endif 185c9710b42Smrg initialized = FcTrue; 186c9710b42Smrg } 187c9710b42Smrg 188b09479dcSmrg#ifdef _AIX 189b09479dcSmrg random_r (&res, &fcrandbuf); 190b09479dcSmrg result = (int32_t)res; 191b09479dcSmrg#else 192b09479dcSmrg random_r (&fcrandbuf, &result); 193b09479dcSmrg#endif 194c9710b42Smrg#elif HAVE_RANDOM 195c9710b42Smrg static char statebuf[256]; 196c9710b42Smrg char *state; 197c9710b42Smrg static FcBool initialized = FcFalse; 198c9710b42Smrg 199c9710b42Smrg if (initialized != FcTrue) 200c9710b42Smrg { 201b09479dcSmrg state = initstate (time (NULL), statebuf, 256); 202c9710b42Smrg initialized = FcTrue; 203c9710b42Smrg } 204c9710b42Smrg else 205b09479dcSmrg state = setstate (statebuf); 206c9710b42Smrg 207b09479dcSmrg result = random (); 208c9710b42Smrg 209b09479dcSmrg setstate (state); 210c9710b42Smrg#elif HAVE_LRAND48 211b09479dcSmrg result = lrand48 (); 212c9710b42Smrg#elif HAVE_RAND_R 213b09479dcSmrg static unsigned int seed = time (NULL); 214c9710b42Smrg 215b09479dcSmrg result = rand_r (&seed); 216c9710b42Smrg#elif HAVE_RAND 217c9710b42Smrg static FcBool initialized = FcFalse; 218c9710b42Smrg 219c9710b42Smrg if (initialized != FcTrue) 220c9710b42Smrg { 221b09479dcSmrg srand (time (NULL)); 222c9710b42Smrg initialized = FcTrue; 223c9710b42Smrg } 224b09479dcSmrg result = rand (); 225c9710b42Smrg#else 226c9710b42Smrg# error no random number generator function available. 227c9710b42Smrg#endif 228c9710b42Smrg 229c9710b42Smrg return result; 230c9710b42Smrg} 2316fc018e4Smrg 2326fc018e4Smrg#ifdef _WIN32 2336fc018e4Smrg#include <direct.h> 2346fc018e4Smrg#define mkdir(path,mode) _mkdir(path) 2356fc018e4Smrg#endif 2366fc018e4Smrg 2376fc018e4SmrgFcBool 2386fc018e4SmrgFcMakeDirectory (const FcChar8 *dir) 2396fc018e4Smrg{ 2406fc018e4Smrg FcChar8 *parent; 2416fc018e4Smrg FcBool ret; 2426fc018e4Smrg 2436fc018e4Smrg if (strlen ((char *) dir) == 0) 2446fc018e4Smrg return FcFalse; 2456fc018e4Smrg 2466fc018e4Smrg parent = FcStrDirname (dir); 2476fc018e4Smrg if (!parent) 2486fc018e4Smrg return FcFalse; 2496fc018e4Smrg if (access ((char *) parent, F_OK) == 0) 2506fc018e4Smrg ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0; 2516fc018e4Smrg else if (access ((char *) parent, F_OK) == -1) 2526fc018e4Smrg ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0; 2536fc018e4Smrg else 2546fc018e4Smrg ret = FcFalse; 2556fc018e4Smrg FcStrFree (parent); 2566fc018e4Smrg return ret; 2576fc018e4Smrg} 258953daebaSmrg 259953daebaSmrg#define __fccompat__ 260953daebaSmrg#include "fcaliastail.h" 261953daebaSmrg#undef __fccompat__ 262