2124 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			2124 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Copyright 1997-2003 by The XFree86 Project, Inc.
 | |
|  *
 | |
|  * Permission to use, copy, modify, distribute, and sell this software and its
 | |
|  * documentation for any purpose is hereby granted without fee, provided that
 | |
|  * the above copyright notice appear in all copies and that both that
 | |
|  * copyright notice and this permission notice appear in supporting
 | |
|  * documentation, and that the names of Orest Zborowski and David Wexelblat 
 | |
|  * not be used in advertising or publicity pertaining to distribution of 
 | |
|  * the software without specific, written prior permission.  Orest Zborowski
 | |
|  * and David Wexelblat make no representations about the suitability of this 
 | |
|  * software for any purpose.  It is provided "as is" without express or 
 | |
|  * implied warranty.
 | |
|  *
 | |
|  * THE XFREE86 PROJECT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD 
 | |
|  * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 
 | |
|  * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT BE LIABLE 
 | |
|  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
 | |
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
 | |
|  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
 | |
|  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_XORG_CONFIG_H
 | |
| #include <xorg-config.h>
 | |
| #endif
 | |
| 
 | |
| #if defined(linux) && !defined(__GLIBC__)
 | |
| #undef __STRICT_ANSI__
 | |
| #endif
 | |
| #include <X11/X.h>
 | |
| #include <X11/Xmd.h>
 | |
| #include <X11/Xos.h>
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #if defined(__bsdi__)
 | |
| #undef _POSIX_SOURCE
 | |
| #undef _ANSI_SOURCE
 | |
| #endif
 | |
| #include <sys/time.h>
 | |
| #include <math.h>
 | |
| #ifdef sun
 | |
| #include <ieeefp.h>
 | |
| #endif
 | |
| #include <stdarg.h>
 | |
| #include <fcntl.h>
 | |
| #include <X11/Xfuncproto.h>
 | |
| #include "os.h"
 | |
| #include <ctype.h>
 | |
| #include <unistd.h>
 | |
| #include <string.h>
 | |
| #include <errno.h>
 | |
| #include <stdio.h>
 | |
| #include <sys/ioctl.h>
 | |
| #ifdef HAS_SVR3_MMAPDRV
 | |
| #define NO_MMAP
 | |
| #ifdef SELF_CONTAINED_WRAPPER
 | |
| #include <sys/at_ansi.h>
 | |
| #include <sys/kd.h>
 | |
| #include <sys/sysmacros.h>
 | |
| #if !defined(_NEED_SYSI86)
 | |
| # include <sys/immu.h>
 | |
| # include <sys/region.h>
 | |
| #endif
 | |
| #include <sys/mmap.h>
 | |
| struct kd_memloc MapDSC;
 | |
| int mmapFd = -2;
 | |
| #else
 | |
| extern struct kd_memloc MapDSC;
 | |
| extern int mmapFd;
 | |
| #endif
 | |
| #endif
 | |
| #ifndef NO_MMAP
 | |
| #include <sys/mman.h>
 | |
| #ifndef MAP_FAILED
 | |
| #define MAP_FAILED ((caddr_t)-1)
 | |
| #endif
 | |
| #endif
 | |
| #if !defined(ISC)
 | |
| #include <stdlib.h>
 | |
| #endif
 | |
| 
 | |
| #define NEED_XF86_TYPES 1
 | |
| #define NEED_XF86_PROTOTYPES 1
 | |
| #define DONT_DEFINE_WRAPPERS
 | |
| #include "xf86_ansic.h"
 | |
| 
 | |
| #ifndef SELF_CONTAINED_WRAPPER
 | |
| #include "xf86.h"
 | |
| #include "xf86Priv.h"
 | |
| #define NO_OSLIB_PROTOTYPES
 | |
| #define XF86_OS_PRIVS
 | |
| #define HAVE_WRAPPER_DECLS
 | |
| #include "xf86_OSlib.h"
 | |
| #else
 | |
| void xf86WrapperInit(void);
 | |
| #endif
 | |
| 
 | |
| 
 | |
| #ifndef X_NOT_POSIX
 | |
| #include <dirent.h>
 | |
| #else
 | |
| #ifdef SYSV
 | |
| #include <dirent.h>
 | |
| #else
 | |
| #ifdef USG
 | |
| #include <dirent.h>
 | |
| #else
 | |
| #include <sys/dir.h>
 | |
| #ifndef dirent
 | |
| #define dirent direct
 | |
| #endif
 | |
| #endif
 | |
| #endif
 | |
| #endif
 | |
| typedef struct dirent DIRENTRY;
 | |
| 
 | |
| #ifdef ISC202
 | |
| #include <sys/types.h>
 | |
| #define WIFEXITED(a)  ((a & 0x00ff) == 0)  /* LSB will be 0 */
 | |
| #define WEXITSTATUS(a) ((a & 0xff00) >> 8)
 | |
| #define WIFSIGNALED(a) ((a & 0xff00) == 0) /* MSB will be 0 */
 | |
| #define WTERMSIG(a) (a & 0x00ff)
 | |
| #else
 | |
| #if defined(ISC) && !defined(_POSIX_SOURCE)
 | |
| #define _POSIX_SOURCE
 | |
| #include <sys/types.h>
 | |
| #include <sys/wait.h>
 | |
| #undef _POSIX_SOURCE
 | |
| #else
 | |
| #if (defined(ISC) && defined(_POSIX_SOURCE)) || defined(Lynx) || (defined (__alpha__) && defined(linux))
 | |
| #include <sys/types.h>
 | |
| #endif
 | |
| #include <sys/wait.h>
 | |
| #endif
 | |
| #endif
 | |
| #ifdef Lynx
 | |
| #if !defined(S_IFIFO) && defined(S_IFFIFO)
 | |
| #define S_IFIFO S_IFFIFO
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| /* For xf86getpagesize() */
 | |
| #if defined(linux)
 | |
| #define HAS_SC_PAGESIZE
 | |
| #define HAS_GETPAGESIZE
 | |
| #elif defined(CSRG_BASED)
 | |
| #define HAS_GETPAGESIZE
 | |
| #elif defined(DGUX)
 | |
| #define HAS_GETPAGESIZE
 | |
| #elif defined(sun) && !defined(SVR4)
 | |
| #define HAS_GETPAGESIZE
 | |
| #endif
 | |
| #ifdef XNO_SYSCONF
 | |
| #undef _SC_PAGESIZE
 | |
| #endif
 | |
| #ifdef HAVE_SYSV_IPC
 | |
| #include <sys/ipc.h>
 | |
| #include <sys/shm.h>
 | |
| #endif
 | |
| #include <setjmp.h>
 | |
| 
 | |
| #if defined(setjmp) && defined(__GNU_LIBRARY__) && \
 | |
|     (!defined(__GLIBC__) || (__GLIBC__ < 2) || \
 | |
|      ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 3)))
 | |
| #define HAS_GLIBC_SIGSETJMP 1
 | |
| #endif
 | |
| 
 | |
| #if 0
 | |
| #define SETBUF_RETURNS_INT
 | |
| #endif
 | |
| 
 | |
| _X_EXPORT double xf86HUGE_VAL;
 | |
| 
 | |
| #ifndef SELF_CONTAINED_WRAPPERS
 | |
| extern void xf86DisableIO(void);
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  * This file contains the XFree86 wrappers for libc functions that can be
 | |
|  * called by loadable modules
 | |
|  */
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86hypot(double x, double y)
 | |
| {
 | |
| 	return(hypot(x,y));
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86qsort(void *base, xf86size_t nmemb, xf86size_t size,
 | |
| 	  int (*comp)(const void *, const void *))
 | |
| {
 | |
| 	qsort(base, nmemb, size, comp);
 | |
| }
 | |
| 
 | |
| /* string functions */
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strcat(char* dest, const char* src)
 | |
| {
 | |
| 	return(strcat(dest,src));
 | |
| }
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strchr(const char* s, int c)
 | |
| {
 | |
| 	return strchr(s,c);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86strcmp(const char* s1, const char* s2)
 | |
| {
 | |
| 	return strcmp(s1,s2);
 | |
| }
 | |
| 
 | |
| /* Just like the BSD version.  It assumes that tolower() is ANSI-compliant */
 | |
| _X_EXPORT int
 | |
| xf86strcasecmp(const char* s1, const char* s2)
 | |
| {
 | |
| 	const unsigned char *us1 = (const unsigned char *)s1;
 | |
| 	const unsigned char *us2 = (const unsigned char *)s2;
 | |
| 
 | |
| 	while (tolower(*us1) == tolower(*us2++))
 | |
| 		if (*us1++ == '\0')
 | |
| 			return 0;
 | |
| 
 | |
| 	return tolower(*us1) - tolower(*--us2);
 | |
| }
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strcpy(char* dest, const char* src)
 | |
| {
 | |
| 	return strcpy(dest,src);
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86size_t
 | |
| xf86strcspn(const char* s1, const char* s2)
 | |
| {
 | |
| 	return (xf86size_t)strcspn(s1,s2);
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86size_t
 | |
| xf86strlen(const char* s)
 | |
| {
 | |
| 	return (xf86size_t)strlen(s);
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86size_t
 | |
| xf86strlcat(char *dest, const char *src, xf86size_t size)
 | |
| {
 | |
| 	return(strlcat(dest, src, size));
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86size_t
 | |
| xf86strlcpy(char *dest, const char *src, xf86size_t size)
 | |
| {
 | |
| 	return strlcpy(dest, src, size);
 | |
| }
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strncat(char* dest, const char* src, xf86size_t n)
 | |
| {
 | |
| 	return strncat(dest,src,(size_t)n);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86strncmp(const char* s1, const char* s2, xf86size_t n)
 | |
| {
 | |
| 	return strncmp(s1,s2,(size_t)n);
 | |
| }
 | |
| 
 | |
| /* Just like the BSD version.  It assumes that tolower() is ANSI-compliant */
 | |
| _X_EXPORT int
 | |
| xf86strncasecmp(const char* s1, const char* s2, xf86size_t n)
 | |
| {
 | |
| 	if (n != 0) {
 | |
| 		const unsigned char *us1 = (const unsigned char *)s1;
 | |
| 		const unsigned char *us2 = (const unsigned char *)s2;
 | |
| 
 | |
| 		do {
 | |
| 			if (tolower(*us1) != tolower(*us2++))
 | |
| 				return tolower(*us1) - tolower(*--us2);
 | |
| 			if (*us1++ == '\0')
 | |
| 				break;
 | |
| 		} while (--n != 0);
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strncpy(char* dest, const char* src, xf86size_t n)
 | |
| {
 | |
| 	return strncpy(dest,src,(size_t)n);
 | |
| }
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strpbrk(const char* s1, const char* s2)
 | |
| {
 | |
| 	return strpbrk(s1,s2);
 | |
| }
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strrchr(const char* s, int c)
 | |
| {
 | |
| 	return strrchr(s,c);
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86size_t
 | |
| xf86strspn(const char* s1, const char* s2)
 | |
| {
 | |
| 	return strspn(s1,s2);
 | |
| }
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strstr(const char* s1, const char* s2)
 | |
| {
 | |
| 	return strstr(s1,s2);
 | |
| }
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strtok(char* s1, const char* s2)
 | |
| {
 | |
| 	return strtok(s1,s2);
 | |
| }
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strdup(const char* s)
 | |
| {
 | |
| 	return xstrdup(s);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86sprintf(char *s, const char *format, ...)
 | |
| {
 | |
|     int ret;
 | |
|     va_list args;
 | |
|     va_start(args, format);
 | |
|     ret = vsprintf(s, format, args);
 | |
|     va_end(args);
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86snprintf(char *s, xf86size_t len, const char *format, ...)
 | |
| {
 | |
|     int ret;
 | |
|     va_list args;
 | |
|     va_start(args, format);
 | |
|     ret = vsnprintf(s, (size_t)len, format, args);
 | |
|     va_end(args);
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86bzero(void* s, unsigned int n)
 | |
| {
 | |
|     memset(s, 0, n);
 | |
| }
 | |
|   
 | |
| #ifdef HAVE_VSSCANF
 | |
| _X_EXPORT int
 | |
| xf86sscanf(char *s, const char *format, ...)
 | |
| #else
 | |
| _X_EXPORT int
 | |
| xf86sscanf(char *s, const char *format, char *a0, char *a1, char *a2,
 | |
| 	   char *a3, char *a4, char *a5, char *a6, char *a7, char *a8,
 | |
| 	   char *a9) /* limit of ten args */
 | |
| #endif
 | |
| {
 | |
| #ifdef HAVE_VSSCANF
 | |
| 	int ret;
 | |
| 	va_list args;
 | |
| 	va_start(args, format);
 | |
| 
 | |
| 	ret = vsscanf(s,format,args);
 | |
| 	va_end(args);
 | |
| 	return ret;
 | |
| #else
 | |
| 	return sscanf(s, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 | |
| #endif
 | |
| }
 | |
|   
 | |
| /* Basic I/O */
 | |
| 
 | |
| _X_EXPORT int xf86errno;
 | |
| 
 | |
| /* XXX This is not complete */
 | |
| 
 | |
| static int
 | |
| xfToOsOpenFlags(int xfflags)
 | |
| {
 | |
|     int flags = 0;
 | |
| 
 | |
|     /* XXX This assumes O_RDONLY is 0 */
 | |
|     if (xfflags & XF86_O_WRONLY)
 | |
| 	flags |= O_WRONLY;
 | |
|     if (xfflags & XF86_O_RDWR)
 | |
| 	flags |= O_RDWR;
 | |
|     if (xfflags & XF86_O_CREAT)
 | |
| 	flags |= O_CREAT;
 | |
| 
 | |
|     return flags;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int 
 | |
| xf86open(const char *path, int flags, ...)
 | |
| {
 | |
|     int fd;
 | |
|     va_list ap;
 | |
| 
 | |
|     va_start(ap, flags);
 | |
|     flags = xfToOsOpenFlags(flags);
 | |
|     if (flags & O_CREAT) {
 | |
| 	/* can't request a mode_t directly on systems where mode_t 
 | |
| 	   is an unsigned short */
 | |
| 	mode_t mode = (mode_t)va_arg(ap, unsigned int);
 | |
| 	fd = open(path, flags, mode);
 | |
|     } else {
 | |
| 	fd = open(path, flags);
 | |
|     }
 | |
|     va_end(ap);
 | |
|     xf86errno = xf86GetErrno();
 | |
| 
 | |
|     return fd;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86close(int fd)
 | |
| {
 | |
|     int status = close(fd);
 | |
| 
 | |
|     xf86errno = xf86GetErrno();
 | |
|     return status;
 | |
| }
 | |
| 
 | |
| _X_EXPORT long
 | |
| xf86lseek(int fd, long offset, int whence)
 | |
| {
 | |
| 	switch (whence) {
 | |
| 	case XF86_SEEK_SET:
 | |
| 		whence = SEEK_SET;
 | |
| 		break;
 | |
| 	case XF86_SEEK_CUR:
 | |
| 		whence = SEEK_CUR;
 | |
| 		break;
 | |
| 	case XF86_SEEK_END:
 | |
| 		whence = SEEK_END;
 | |
| 		break;
 | |
| 	}
 | |
| 	return (long)lseek(fd, (off_t)offset, whence);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86ioctl(int fd, unsigned long request, pointer argp)
 | |
| {
 | |
|     int status = ioctl(fd, request, argp);
 | |
| 
 | |
|     xf86errno = xf86GetErrno();
 | |
|     return status;
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86ssize_t
 | |
| xf86read(int fd, void *buf, xf86size_t nbytes)
 | |
| {
 | |
|     xf86ssize_t n = read(fd, buf, (size_t)nbytes);
 | |
| 
 | |
|     xf86errno = xf86GetErrno();
 | |
|     return n;
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86ssize_t
 | |
| xf86write(int fd, const void *buf, xf86size_t nbytes)
 | |
| {
 | |
|     xf86ssize_t n = write(fd, buf, (size_t)nbytes);
 | |
| 
 | |
|     xf86errno = xf86GetErrno();
 | |
|     return n;
 | |
| }
 | |
| 
 | |
| _X_EXPORT void*
 | |
| xf86mmap(void *start, xf86size_t length, int prot,
 | |
| 	 int flags, int fd, xf86size_t /* off_t */ offset)
 | |
| {
 | |
| #ifndef NO_MMAP
 | |
|     int p=0, f=0;
 | |
|     void *rc;
 | |
| 
 | |
|     if (flags & XF86_MAP_FIXED)		f |= MAP_FIXED;
 | |
|     if (flags & XF86_MAP_SHARED)	f |= MAP_SHARED;
 | |
|     if (flags & XF86_MAP_PRIVATE)	f |= MAP_PRIVATE;
 | |
| #if defined(__amd64__) && defined(linux)
 | |
|     if (flags & XF86_MAP_32BIT)	        f |= MAP_32BIT;
 | |
| #endif
 | |
|     if (prot  & XF86_PROT_EXEC)		p |= PROT_EXEC;
 | |
|     if (prot  & XF86_PROT_READ)		p |= PROT_READ;
 | |
|     if (prot  & XF86_PROT_WRITE)	p |= PROT_WRITE;
 | |
|     if (prot  & XF86_PROT_NONE)		p |= PROT_NONE;
 | |
| 
 | |
|     rc = mmap(start,(size_t)length,p,f,fd,(off_t)offset);
 | |
| 
 | |
|     xf86errno = xf86GetErrno();
 | |
|     if (rc == MAP_FAILED)
 | |
| 	return XF86_MAP_FAILED;
 | |
|     else
 | |
| 	return rc;
 | |
| #else
 | |
| #ifdef HAS_SVR3_MMAPDRV
 | |
|     void *rc;
 | |
| #ifdef SELF_CONTAINED_WRAPPER
 | |
|     if(mmapFd < 0) {
 | |
|       if ((mmapFd = open("/dev/mmap", O_RDWR)) == -1) {
 | |
|           ErrorF("Warning: failed to open /dev/mmap \n");
 | |
|           xf86errno = xf86_ENOSYS;
 | |
|           return XF86_MAP_FAILED;
 | |
|       }
 | |
|     }
 | |
| #endif
 | |
|     MapDSC.vaddr    = (char *)start;
 | |
|     MapDSC.physaddr = (char *)offset;
 | |
|     MapDSC.length   = length;
 | |
|     MapDSC.ioflg    = 1;
 | |
| 
 | |
|     rc = (pointer)ioctl(mmapFd, MAP, &MapDSC);
 | |
|     xf86errno = xf86GetErrno();
 | |
|     if (rc == NULL)
 | |
| 	return XF86_MAP_FAILED;
 | |
|     else
 | |
| 	return rc;
 | |
| #else
 | |
|     ErrorF("Warning: mmap() is not supported on this platform\n");
 | |
|     xf86errno = xf86_ENOSYS;
 | |
|     return XF86_MAP_FAILED;
 | |
| #endif
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86munmap(void *start, xf86size_t length)
 | |
| {
 | |
| #ifndef NO_MMAP
 | |
|     int rc = munmap(start,(size_t)length);
 | |
| 
 | |
|     xf86errno = xf86GetErrno();
 | |
|     return rc;
 | |
| #else
 | |
| #ifdef HAS_SVR3_MMAPDRV
 | |
|     int rc = ioctl(mmapFd, UNMAPRM , start);
 | |
|  
 | |
|     xf86errno = xf86GetErrno();
 | |
|     return rc;
 | |
| #else
 | |
|     ErrorF("Warning: munmap() is not supported on this platform\n");
 | |
|     xf86errno = xf86_ENOSYS;
 | |
|     return -1;
 | |
| #endif
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86stat(const char *file_name, struct xf86stat *xfst)
 | |
| {
 | |
|     int         rc;
 | |
|     struct stat st;
 | |
| 
 | |
|     rc            = stat(file_name, &st);
 | |
|     xf86errno     = xf86GetErrno();
 | |
|     xfst->st_rdev = st.st_rdev;	/* Not much is currently supported */
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fstat(int fd, struct xf86stat *xfst)
 | |
| {
 | |
|     int         rc;
 | |
|     struct stat st;
 | |
| 
 | |
|     rc            = fstat(fd, &st);
 | |
|     xf86errno     = xf86GetErrno();
 | |
|     xfst->st_rdev = st.st_rdev;	/* Not much is currently supported */
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| static int
 | |
| xfToOsAccessMode(int xfmode)
 | |
| {
 | |
|     switch(xfmode) {
 | |
|     case XF86_R_OK: return R_OK;
 | |
|     case XF86_W_OK: return W_OK;
 | |
|     case XF86_X_OK: return X_OK;
 | |
|     case XF86_F_OK: return F_OK;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86access(const char *pathname, int mode)
 | |
| {
 | |
|     int rc;
 | |
|     
 | |
|     mode      = xfToOsAccessMode(mode);
 | |
|     rc        = access(pathname, mode);
 | |
|     xf86errno = xf86GetErrno();
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /* limited stdio support */
 | |
| 
 | |
| #define XF86FILE_magic	0x58464856	/* "XFHV" */
 | |
| 
 | |
| typedef struct _xf86_file_ {
 | |
| 	INT32	fileno;
 | |
| 	INT32	magic;
 | |
| 	FILE*	filehnd;
 | |
| 	char*	fname;
 | |
| } XF86FILE_priv;
 | |
| 
 | |
| static XF86FILE_priv stdhnd[3] = {
 | |
| 	{ 0, XF86FILE_magic, NULL, "$stdinp$" },
 | |
| 	{ 0, XF86FILE_magic, NULL, "$stdout$" },
 | |
| 	{ 0, XF86FILE_magic, NULL, "$stderr$" }
 | |
| };
 | |
| 
 | |
| _X_EXPORT XF86FILE* xf86stdin = (XF86FILE*)&stdhnd[0];
 | |
| _X_EXPORT XF86FILE* xf86stdout = (XF86FILE*)&stdhnd[1];
 | |
| _X_EXPORT XF86FILE* xf86stderr = (XF86FILE*)&stdhnd[2];
 | |
| 
 | |
| void
 | |
| xf86WrapperInit()
 | |
| {
 | |
|     if (stdhnd[0].filehnd == NULL)
 | |
| 	stdhnd[0].filehnd = stdin;
 | |
|     if (stdhnd[1].filehnd == NULL)
 | |
| 	stdhnd[1].filehnd = stdout;
 | |
|     if (stdhnd[2].filehnd == NULL)
 | |
| 	stdhnd[2].filehnd = stderr;
 | |
|     xf86HUGE_VAL = HUGE_VAL;
 | |
| }
 | |
| 
 | |
| _X_EXPORT XF86FILE*
 | |
| xf86fopen(const char* fn, const char* mode)
 | |
| {
 | |
| 	XF86FILE_priv* fp;
 | |
| 	FILE *f = fopen(fn,mode);
 | |
| 	xf86errno = xf86GetErrno();
 | |
| 	if (!f) return 0;
 | |
| 
 | |
| 	fp = xalloc(sizeof(XF86FILE_priv));
 | |
| 	fp->magic = XF86FILE_magic;
 | |
| 	fp->filehnd = f;
 | |
| 	fp->fileno = fileno(f);
 | |
| 	fp->fname = xf86strdup(fn);
 | |
| #ifdef DEBUG
 | |
| 	ErrorF("xf86fopen(%s,%s) yields FILE %p XF86FILE %p\n",
 | |
| 		fn,mode,f,fp);
 | |
| #endif
 | |
| 	return (XF86FILE*)fp;
 | |
| }
 | |
| 
 | |
| static void _xf86checkhndl(XF86FILE_priv* f,const char *func)
 | |
| {
 | |
| 	if (!f || f->magic != XF86FILE_magic ||
 | |
| 	    !f->filehnd || !f->fname) {
 | |
| 		FatalError("libc_wrapper error: passed invalid FILE handle to %s",
 | |
| 			func);
 | |
| 		exit(42);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fclose(XF86FILE* f) 
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 	int ret;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fclose");
 | |
| 
 | |
| 	/* somewhat bad check */
 | |
| 	if (fp->fileno < 3 && fp->fname[0]=='$') {
 | |
| 		/* assume this is stdin/out/err, don't dispose */
 | |
| 		ret = fclose(fp->filehnd);
 | |
| 	} else {
 | |
| 		ret = fclose(fp->filehnd);
 | |
| 		fp->magic = 0;	/* invalidate */
 | |
| 		xfree(fp->fname);
 | |
| 		xfree(fp);
 | |
| 	}
 | |
| 	return ret ? -1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86printf(const char *format, ...)
 | |
| {
 | |
| 	int ret;
 | |
| 	va_list args;
 | |
| 	va_start(args, format);
 | |
| 
 | |
| 	ret = printf(format,args);
 | |
| 	va_end(args);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fprintf(XF86FILE* f, const char *format, ...)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	int ret;
 | |
| 	va_list args;
 | |
| 	va_start(args, format);
 | |
| 
 | |
| #ifdef DEBUG
 | |
| 	ErrorF("xf86fprintf for XF86FILE %p\n", fp);
 | |
| #endif
 | |
| 	_xf86checkhndl(fp,"xf86fprintf");
 | |
| 
 | |
| 	ret = vfprintf(fp->filehnd,format,args);
 | |
| 	va_end(args);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86vfprintf(XF86FILE* f, const char *format, va_list ap)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| #ifdef DEBUG
 | |
| 	ErrorF("xf86vfprintf for XF86FILE %p\n", fp);
 | |
| #endif
 | |
| 	_xf86checkhndl(fp,"xf86vfprintf");
 | |
| 
 | |
| 	return vfprintf(fp->filehnd,format,ap);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86vsprintf(char *s, const char *format, va_list ap)
 | |
| {
 | |
| 	return vsprintf(s, format, ap);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86vsnprintf(char *s, xf86size_t len, const char *format, va_list ap)
 | |
| {
 | |
| 	return vsnprintf(s, (size_t)len, format, ap);
 | |
| }
 | |
| 
 | |
| #ifdef HAVE_VFSCANF
 | |
| _X_EXPORT int
 | |
| xf86fscanf(XF86FILE* f, const char *format, ...)
 | |
| #else
 | |
| _X_EXPORT int
 | |
| xf86fscanf(XF86FILE* f, const char *format, char *a0, char *a1, char *a2,
 | |
| 	   char *a3, char *a4, char *a5, char *a6, char *a7, char *a8,
 | |
| 	   char *a9) /* limit of ten args */
 | |
| #endif
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| #ifdef HAVE_VFSCANF
 | |
| 	int ret;
 | |
| 	va_list args;
 | |
| 	va_start(args, format);
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fscanf");
 | |
| 
 | |
| 	ret = vfscanf(fp->filehnd,format,args);
 | |
| 	va_end(args);
 | |
| 	return ret;
 | |
| #else
 | |
| 	_xf86checkhndl(fp,"xf86fscanf");
 | |
| 	return fscanf(fp->filehnd, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT char *
 | |
| xf86fgets(char *buf, INT32 n, XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fgets");
 | |
| 	return fgets(buf,(int)n,fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fputs(const char *buf, XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fputs");
 | |
| 	return fputs(buf,fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86getc(XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86getc");
 | |
| 	return getc(fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fgetc(XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fgetc");
 | |
| 	return fgetc(fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fputc(int c,XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fputc");
 | |
| 	return fputc(c,fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fflush(XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fflush");
 | |
| 	return fflush(fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86size_t
 | |
| xf86fread(void* buf, xf86size_t sz, xf86size_t cnt, XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| #ifdef DEBUG
 | |
| 	ErrorF("xf86fread for XF86FILE %p\n", fp);
 | |
| #endif
 | |
| 	_xf86checkhndl(fp,"xf86fread");
 | |
| 	return fread(buf,(size_t)sz,(size_t)cnt,fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86size_t
 | |
| xf86fwrite(const void* buf, xf86size_t sz, xf86size_t cnt, XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fwrite");
 | |
| 	return fwrite(buf,(size_t)sz,(size_t)cnt,fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fseek(XF86FILE* f, long offset, int whence)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fseek");
 | |
| 	switch (whence) {
 | |
| 	case XF86_SEEK_SET:
 | |
| 		whence = SEEK_SET;
 | |
| 		break;
 | |
| 	case XF86_SEEK_CUR:
 | |
| 		whence = SEEK_CUR;
 | |
| 		break;
 | |
| 	case XF86_SEEK_END:
 | |
| 		whence = SEEK_END;
 | |
| 		break;
 | |
| 	}
 | |
| 	return fseek(fp->filehnd,offset,whence);
 | |
| }
 | |
| 
 | |
| _X_EXPORT long
 | |
| xf86ftell(XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86ftell");
 | |
| 	return ftell(fp->filehnd);
 | |
| }
 | |
| 
 | |
| #define mapnum(e) case (xf86_##e): err = e; break;
 | |
| 
 | |
| _X_EXPORT char*
 | |
| xf86strerror(int n)
 | |
| {
 | |
| 	int err;
 | |
| 
 | |
| 	switch (n)
 | |
| 	{
 | |
| 		case 0: err = 0; break;
 | |
| 		mapnum (EACCES);
 | |
| 		mapnum (EAGAIN);
 | |
| 		mapnum (EBADF);
 | |
| 		mapnum (EEXIST);
 | |
| 		mapnum (EFAULT);
 | |
| 		mapnum (EINTR);
 | |
| 		mapnum (EINVAL);
 | |
| 		mapnum (EISDIR);
 | |
| 		mapnum (ELOOP);		/* not POSIX 1 */
 | |
| 		mapnum (EMFILE);
 | |
| 		mapnum (ENAMETOOLONG);
 | |
| 		mapnum (ENFILE);
 | |
| 		mapnum (ENOENT);
 | |
| 		mapnum (ENOMEM);
 | |
| 		mapnum (ENOSPC);
 | |
| 		mapnum (ENOTDIR);
 | |
| 		mapnum (EPIPE);
 | |
| 		mapnum (EROFS);
 | |
| 		mapnum (ETXTBSY);	/* not POSIX 1 */
 | |
| 		mapnum (ENOTTY);
 | |
| #ifdef ENOSYS
 | |
| 		mapnum (ENOSYS);
 | |
| #endif
 | |
| 		mapnum (EBUSY);
 | |
| 		mapnum (ENODEV);
 | |
| 		mapnum (EIO);
 | |
| #ifdef ESRCH
 | |
| 		mapnum (ESRCH);
 | |
| #endif
 | |
| #ifdef ENXIO
 | |
| 		mapnum (ENXIO);  
 | |
| #endif
 | |
| #ifdef E2BIG
 | |
| 		mapnum (E2BIG);    
 | |
| #endif
 | |
| #ifdef ENOEXEC
 | |
| 		mapnum (ENOEXEC);
 | |
| #endif
 | |
| #ifdef ECHILD
 | |
| 		mapnum (ECHILD);
 | |
| #endif
 | |
| #ifdef ENOTBLK
 | |
| 		mapnum (ENOTBLK);
 | |
| #endif
 | |
| #ifdef EXDEV
 | |
| 		mapnum (EXDEV); 
 | |
| #endif
 | |
| #ifdef EFBIG
 | |
| 		mapnum (EFBIG);
 | |
| #endif
 | |
| #ifdef ESPIPE
 | |
| 		mapnum (ESPIPE);
 | |
| #endif
 | |
| #ifdef EMLINK
 | |
| 		mapnum (EMLINK);
 | |
| #endif
 | |
| #ifdef EDOM
 | |
| 		mapnum (EDOM);
 | |
| #endif
 | |
| #ifdef ERANGE
 | |
| 		mapnum (ERANGE);
 | |
| #endif
 | |
| 
 | |
| 		default:
 | |
| 			err = 999;
 | |
| 	}
 | |
| 	return strerror(err);
 | |
| }
 | |
| 
 | |
| #undef mapnum
 | |
| 
 | |
| 
 | |
| /* required for portable fgetpos/fsetpos,
 | |
|  * use as
 | |
|  *	XF86fpos_t* pos = xalloc(xf86fpossize());
 | |
|  */
 | |
| _X_EXPORT long
 | |
| xf86fpossize()
 | |
| {
 | |
| 	return sizeof(fpos_t);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fgetpos(XF86FILE* f,XF86fpos_t* pos)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 	fpos_t *ppos = (fpos_t*)pos;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fgetpos");
 | |
| #ifndef ISC
 | |
| 	return fgetpos(fp->filehnd,ppos);
 | |
| #else
 | |
| 	*ppos = ftell(fp->filehnd);
 | |
| 	if (*ppos < 0L)
 | |
| 		return(-1);
 | |
| 	return(0);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86fsetpos(XF86FILE* f,const XF86fpos_t* pos)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 	fpos_t *ppos = (fpos_t*)pos;
 | |
| 
 | |
| 	/* XXX need to handle xf86errno here */
 | |
| 	_xf86checkhndl(fp,"xf86fsetpos");
 | |
| #ifndef ISC
 | |
| 	return fsetpos(fp->filehnd,ppos);
 | |
| #else
 | |
| 	if (ppos == NULL)
 | |
| 	{
 | |
| 		errno = EINVAL;
 | |
| 		return EOF;
 | |
| 	}
 | |
| 	return fseek(fp->filehnd, *ppos, SEEK_SET);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86perror(const char *s)
 | |
| {
 | |
| 	perror(s);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86remove(const char *s)
 | |
| {
 | |
| #ifdef _POSIX_SOURCE
 | |
| 	return remove(s);
 | |
| #else
 | |
| 	return unlink(s);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86rename(const char *old, const char *new)
 | |
| {
 | |
| #ifdef _POSIX_SOURCE
 | |
| 	return rename(old,new);
 | |
| #else
 | |
| 	int ret = link(old,new);
 | |
| 	if (!ret) {
 | |
| 		ret = unlink(old);
 | |
| 		if (ret) unlink(new);
 | |
| 	} else
 | |
| 		ret = unlink(new);
 | |
| 	return ret;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86rewind(XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fsetpos");
 | |
| 	rewind(fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86clearerr(XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86clearerr");
 | |
| 	clearerr(fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86feof(XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86feof");
 | |
| 	return feof(fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86ferror(XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86ferror");
 | |
| 	return ferror(fp->filehnd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT XF86FILE*
 | |
| xf86freopen(const char* fname,const char* mode,XF86FILE* fold)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)fold;
 | |
| 	FILE *fnew;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86freopen");
 | |
| 	fnew = freopen(fname,mode,fp->filehnd);
 | |
| 	xf86errno = xf86GetErrno();
 | |
| 	if (!fnew) {
 | |
| 		xf86fclose(fold);	/* discard old XF86FILE structure */
 | |
| 		return 0;
 | |
| 	}
 | |
| 	/* recycle the old XF86FILE structure */
 | |
| 	fp->magic = XF86FILE_magic;
 | |
| 	fp->filehnd = fnew;
 | |
| 	fp->fileno = fileno(fnew);
 | |
| 	fp->fname = xf86strdup(fname);
 | |
| #ifdef DEBUG
 | |
| 	ErrorF("xf86freopen(%s,%s,%p) yields FILE %p XF86FILE %p\n",
 | |
| 		fname,mode,fold,fnew,fp);
 | |
| #endif
 | |
| 	return (XF86FILE*)fp;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86setbuf(XF86FILE* f, char *buf)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fsetbuf");
 | |
| #ifdef SETBUF_RETURNS_INT
 | |
| 	return setbuf(fp->filehnd, buf);
 | |
| #else
 | |
| 	setbuf(fp->filehnd, buf);
 | |
| 	return 0;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86setvbuf(XF86FILE* f, char *buf, int mode, xf86size_t size)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 	int vbufmode;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86fsetvbuf");
 | |
| 
 | |
| 	switch (mode) {
 | |
| 	case XF86_IONBF:
 | |
| 		vbufmode = _IONBF;
 | |
| 		break;
 | |
| 	case XF86_IOLBF:
 | |
| 		vbufmode = _IOFBF;
 | |
| 		break;
 | |
| 	case XF86_IOFBF:
 | |
| 		vbufmode = _IOLBF;
 | |
| 		break;
 | |
| 	default:
 | |
| 		FatalError("libc_wrapper error: mode in setvbuf incorrect");
 | |
| 		exit(42);
 | |
| 	}
 | |
| 
 | |
| 	return setvbuf(fp->filehnd,buf,vbufmode,(size_t)size);
 | |
| }
 | |
| 
 | |
| _X_EXPORT XF86FILE*
 | |
| xf86tmpfile(void)
 | |
| {
 | |
| #ifdef NEED_TMPFILE
 | |
| 	return xf86fopen(tmpnam((char*)0),"w+");
 | |
| #else
 | |
| 	XF86FILE_priv* fp;
 | |
| 	FILE *f = tmpfile();
 | |
| 	xf86errno = xf86GetErrno();
 | |
| 	if (!f) return 0;
 | |
| 
 | |
| 	fp = xalloc(sizeof(XF86FILE_priv));
 | |
| 	fp->magic = XF86FILE_magic;
 | |
| 	fp->filehnd = f;
 | |
| 	fp->fileno = fileno(f);
 | |
| 	fp->fname = xf86strdup("*tmpfile*"); /* so that it can be xfree()'d */
 | |
| #ifdef DEBUG
 | |
| 	ErrorF("xf86tmpfile() yields FILE %p XF86FILE %p\n",f,fp);
 | |
| #endif
 | |
| 	return (XF86FILE*)fp;
 | |
| }
 | |
| #endif /* HAS_TMPFILE */
 | |
| 
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86ungetc(int c,XF86FILE* f)
 | |
| {
 | |
| 	XF86FILE_priv* fp = (XF86FILE_priv*)f;
 | |
| 
 | |
| 	_xf86checkhndl(fp,"xf86ungetc");
 | |
| 	return ungetc(c,fp->filehnd);
 | |
| }
 | |
| 
 | |
| /* Misc functions. Some are ANSI C, some are not. */
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86usleep(usec)
 | |
|     unsigned long usec;
 | |
| {
 | |
| #if (defined(SYSV) || defined(SVR4)) && !defined(sun)
 | |
|     syscall(3112, (usec) / 1000 + 1);
 | |
| #else
 | |
|     usleep(usec);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86getsecs(long * secs, long * usecs)
 | |
| {
 | |
| 	struct timeval tv;
 | |
| 
 | |
| 	X_GETTIMEOFDAY(&tv);
 | |
| 	if (secs)
 | |
| 		*secs = tv.tv_sec;
 | |
| 	if (usecs)
 | |
| 		*usecs= tv.tv_usec;
 | |
| 
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86ffs(int mask)
 | |
| {
 | |
| 	int n;
 | |
| 	if (mask == 0) return 0;
 | |
| 	for (n = 1; (mask & 1)==0; n++)
 | |
| 		mask >>= 1;
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| _X_EXPORT char *
 | |
| xf86getenv(const char * a)
 | |
| {
 | |
| 	/* Only allow this when the real and effective uids are the same */
 | |
| 	if (getuid() != geteuid())
 | |
| 		return NULL;
 | |
| 	else
 | |
| 		return(getenv(a));
 | |
| }
 | |
| 
 | |
| _X_EXPORT void *
 | |
| xf86bsearch(const void *key, const void *base, xf86size_t nmemb,
 | |
| 	    xf86size_t size, int (*compar)(const void *, const void *))
 | |
| {
 | |
| 	return bsearch(key, base, (size_t)nmemb, (size_t)size, compar);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86execl(const char *pathname, const char *arg, ...)
 | |
| {
 | |
|     int i;
 | |
|     pid_t pid;
 | |
|     int exit_status;
 | |
|     char *arglist[5];
 | |
|     va_list args;
 | |
|     va_start(args, arg);
 | |
|     arglist[0] = (char*)&args;
 | |
|     i = 1;
 | |
|     while (i < 5 && (arglist[i++] = va_arg(args, char *)) != NULL)
 | |
| 	;
 | |
|     va_end(args);
 | |
| 
 | |
|     if ((pid = fork()) < 0) {
 | |
|         ErrorF("Fork failed (%s)\n", strerror(errno));
 | |
|         return -1;
 | |
|     } else if (pid == 0) { /* child */
 | |
| 	/* 
 | |
| 	 * Make sure that the child doesn't inherit any I/O permissions it
 | |
| 	 * shouldn't have.  It's better to put constraints on the development
 | |
| 	 * of a clock program than to give I/O permissions to a bogus program
 | |
| 	 * in someone's XF86Config file
 | |
| 	 */
 | |
| #ifndef SELF_CONTAINED_WRAPPER
 | |
| 	xf86DisableIO();
 | |
| #endif
 | |
|         if (setuid(getuid()) == -1) {
 | |
| 		ErrorF("xf86Execl: setuid() failed: %s\n", strerror(errno));
 | |
| 		exit(255);
 | |
| 	}
 | |
| #if !defined(SELF_CONTAINED_WRAPPER)
 | |
|         /* set stdin, stdout to the consoleFD, and leave stderr alone */
 | |
|         for (i = 0; i < 2; i++)
 | |
|         {
 | |
|           if (xf86Info.consoleFd != i)
 | |
|           {
 | |
|             close(i);
 | |
|             dup(xf86Info.consoleFd);
 | |
|           }
 | |
|         }
 | |
| #endif
 | |
| 
 | |
| 	execv(pathname, arglist);
 | |
| 	ErrorF("Exec failed for command \"%s\" (%s)\n",
 | |
| 	       pathname, strerror(errno));
 | |
| 	exit(255);
 | |
|     }
 | |
| 
 | |
|     /* parent */
 | |
|     wait(&exit_status);
 | |
|     if (WIFEXITED(exit_status))
 | |
|     {
 | |
| 	switch (WEXITSTATUS(exit_status))
 | |
| 	    {
 | |
| 	    case 0:     /* OK */
 | |
| 		return 0;
 | |
| 	    case 255:   /* exec() failed */
 | |
| 		return(255);
 | |
| 	    default:    /* bad exit status */
 | |
| 		ErrorF("Program \"%s\" had bad exit status %d\n",
 | |
| 		       pathname, WEXITSTATUS(exit_status));
 | |
| 		return(WEXITSTATUS(exit_status));
 | |
| 	    }
 | |
|     }
 | |
|     else if (WIFSIGNALED(exit_status))
 | |
|     {
 | |
| 	ErrorF("Program \"%s\" died on signal %d\n",
 | |
| 	       pathname, WTERMSIG(exit_status));
 | |
| 	return(WTERMSIG(exit_status));
 | |
|     }
 | |
| #ifdef WIFSTOPPED
 | |
|     else if (WIFSTOPPED(exit_status))
 | |
|     {
 | |
| 	ErrorF("Program \"%s\" stopped by signal %d\n",
 | |
| 	       pathname, WSTOPSIG(exit_status));
 | |
| 	return(WSTOPSIG(exit_status));
 | |
|     }
 | |
| #endif
 | |
|     else /* should never get to this point */
 | |
|     {
 | |
| 	ErrorF("Program \"%s\" has unknown exit condition\n",
 | |
| 	       pathname);
 | |
| 	return(1);
 | |
|     }
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86abort(void)
 | |
| {
 | |
| 	ErrorF("Module called abort() function\n");
 | |
| 	abort();
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86exit(int ex)
 | |
| {
 | |
| 	ErrorF("Module called exit() function with value=%d\n",ex);
 | |
| 	exit(ex);
 | |
| }
 | |
| 
 | |
| /* directory handling functions */
 | |
| #define XF86DIR_magic	0x78666876	/* "xfhv" */
 | |
| 
 | |
| typedef struct _xf86_dir_ {
 | |
| 	DIR		*dir;
 | |
| 	INT32		magic;
 | |
| 	XF86DIRENT	*dirent;
 | |
| } XF86DIR_priv;
 | |
| 
 | |
| static void
 | |
| _xf86checkdirhndl(XF86DIR_priv* f,const char *func)
 | |
| {
 | |
| 	if (!f || f->magic != XF86DIR_magic || !f->dir || !f->dirent) {
 | |
| 		FatalError("libc_wrapper error: passed invalid DIR handle to %s",
 | |
| 			func);
 | |
| 		exit(42);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| _X_EXPORT XF86DIR *
 | |
| xf86opendir(const char *name)
 | |
| {
 | |
| 	XF86DIR_priv *dp;
 | |
| 	DIR *dirp;
 | |
| 
 | |
| 	dirp = opendir(name);
 | |
| 	if (!dirp)
 | |
| 		return (XF86DIR*)0;
 | |
| 
 | |
| 	dp = xalloc(sizeof(XF86DIR_priv));
 | |
| 	dp->magic = XF86DIR_magic; /* This time I have this, Dirk! :-) */
 | |
| 	dp->dir = dirp;
 | |
| 	dp->dirent = xalloc(sizeof(struct _xf86dirent));
 | |
| 
 | |
| 	return (XF86DIR*)dp;
 | |
| }
 | |
| 
 | |
| _X_EXPORT XF86DIRENT*
 | |
| xf86readdir(XF86DIR* dirp)
 | |
| {
 | |
| 	XF86DIR_priv* dp = (XF86DIR_priv*)dirp;
 | |
| 	DIRENTRY *de;
 | |
| 	XF86DIRENT* xde;
 | |
| 	int sz;
 | |
| 
 | |
| 	_xf86checkdirhndl(dp,"xf86readdir");
 | |
| 
 | |
| 	de = readdir(dp->dir);
 | |
| 	if (!de)
 | |
| 		return (XF86DIRENT*)0;
 | |
| 	xde = dp->dirent;
 | |
| 	sz = strlen(de->d_name);
 | |
| 	strncpy(xde->d_name,de->d_name, sz>_XF86NAMELEN ? (_XF86NAMELEN+1) : (sz+1));
 | |
| 	xde->d_name[_XF86NAMELEN] = '\0';	/* be sure to have a 0 byte */
 | |
| 	return xde;
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86rewinddir(XF86DIR* dirp)
 | |
| {
 | |
| 	XF86DIR_priv* dp = (XF86DIR_priv*)dirp;
 | |
| 
 | |
| 	_xf86checkdirhndl(dp,"xf86readdir");
 | |
| 	rewinddir(dp->dir);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86closedir(XF86DIR* dir)
 | |
| {
 | |
| 	XF86DIR_priv* dp = (XF86DIR_priv*)dir;
 | |
| 	int n;
 | |
| 
 | |
| 	_xf86checkdirhndl(dp,"xf86readdir");
 | |
| 
 | |
| 	n = closedir(dp->dir);
 | |
| 	dp->magic = 0;
 | |
| 	xfree(dp->dirent);
 | |
| 	xfree(dp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| static mode_t
 | |
| xfToOsChmodMode(xf86mode_t xfmode)
 | |
| {
 | |
|     mode_t mode = 0;
 | |
| 
 | |
|     if (xfmode & XF86_S_ISUID) mode |= S_ISUID;
 | |
|     if (xfmode & XF86_S_ISGID) mode |= S_ISGID;
 | |
|     if (xfmode & XF86_S_ISVTX) mode |= S_ISVTX;
 | |
|     if (xfmode & XF86_S_IRUSR) mode |= S_IRUSR;
 | |
|     if (xfmode & XF86_S_IWUSR) mode |= S_IWUSR;
 | |
|     if (xfmode & XF86_S_IXUSR) mode |= S_IXUSR;
 | |
|     if (xfmode & XF86_S_IRGRP) mode |= S_IRGRP;
 | |
|     if (xfmode & XF86_S_IWGRP) mode |= S_IWGRP;
 | |
|     if (xfmode & XF86_S_IXGRP) mode |= S_IXGRP;
 | |
|     if (xfmode & XF86_S_IROTH) mode |= S_IROTH;
 | |
|     if (xfmode & XF86_S_IWOTH) mode |= S_IWOTH;
 | |
|     if (xfmode & XF86_S_IXOTH) mode |= S_IXOTH;
 | |
| 
 | |
|     return mode;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86chmod(const char *path, xf86mode_t xfmode)
 | |
| {
 | |
|     mode_t mode = xfToOsChmodMode(xfmode);
 | |
|     int    rc   = chmod(path, mode);
 | |
|     
 | |
|     xf86errno   = xf86GetErrno();
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86chown(const char *path, xf86uid_t owner, xf86gid_t group)
 | |
| {
 | |
|     int rc = chown(path, owner, group);
 | |
|     xf86errno = xf86GetErrno();
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86uid_t
 | |
| xf86geteuid(void)
 | |
| {
 | |
|     return geteuid();
 | |
| }
 | |
| 
 | |
| _X_EXPORT xf86gid_t
 | |
| xf86getegid(void)
 | |
| {
 | |
|     return getegid();
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86getpid(void)
 | |
| {
 | |
|     return getpid();
 | |
| }
 | |
| 
 | |
| static mode_t
 | |
| xfToOsMknodMode(xf86mode_t xfmode)
 | |
| {
 | |
|     mode_t mode = xfToOsChmodMode(xfmode);
 | |
| 
 | |
|     if (xfmode & XF86_S_IFREG) mode |= S_IFREG;
 | |
|     if (xfmode & XF86_S_IFCHR) mode |= S_IFCHR;
 | |
|     if (xfmode & XF86_S_IFBLK) mode |= S_IFBLK;
 | |
|     if (xfmode & XF86_S_IFIFO) mode |= S_IFIFO;
 | |
| 
 | |
|     return mode;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int xf86mknod(const char *pathname, xf86mode_t xfmode, xf86dev_t dev)
 | |
| {
 | |
|     mode_t mode = xfToOsMknodMode(xfmode);
 | |
|     int rc      = mknod(pathname, mode, dev);
 | |
|     xf86errno   = xf86GetErrno();
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| _X_EXPORT unsigned int xf86sleep(unsigned int seconds)
 | |
| {
 | |
|     return sleep(seconds);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int xf86mkdir(const char *pathname, xf86mode_t xfmode)
 | |
| {
 | |
|     mode_t mode = xfToOsChmodMode(xfmode);
 | |
|     int    rc   = mkdir(pathname, mode);
 | |
|     
 | |
|     xf86errno   = xf86GetErrno();
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Several math functions */
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86abs(int x)
 | |
| {
 | |
| 	return abs(x);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86acos(double x)
 | |
| {
 | |
| 	return acos(x);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86asin(double x)
 | |
| {
 | |
| 	return asin(x);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86atan(double x)
 | |
| {
 | |
| 	return atan(x);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86atan2(double x,double y)
 | |
| {
 | |
| 	return atan2(x,y);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86atof(const char* s)
 | |
| {
 | |
| 	return atof(s);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86atoi(const char* s)
 | |
| {
 | |
| 	return atoi(s);
 | |
| }
 | |
| 
 | |
| _X_EXPORT long
 | |
| xf86atol(const char* s)
 | |
| {
 | |
| 	return atol(s);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86ceil(double x)
 | |
| {
 | |
| 	return ceil(x);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86cos(double x)
 | |
| {
 | |
| 	return(cos(x));
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86exp(double x)
 | |
| {
 | |
| 	return(exp(x));
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86fabs(double x)
 | |
| {
 | |
|         return(fabs(x));
 | |
| }
 | |
| 
 | |
| _X_EXPORT int 
 | |
| xf86finite(double x)
 | |
| {
 | |
| #ifndef QNX4
 | |
| 	return(finite(x));
 | |
| #else
 | |
| 	/* XXX Replace this with something that really works. */
 | |
| 	return 1;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86floor(double x)
 | |
| {
 | |
| 	return floor(x);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86fmod(double x,double y)
 | |
| {
 | |
| 	return fmod(x,y);
 | |
| }
 | |
| 
 | |
| _X_EXPORT long
 | |
| xf86labs(long x)
 | |
| {
 | |
| 	return labs(x);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86ldexp(double x, int exp)
 | |
| {
 | |
| 	return ldexp(x, exp);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86log(double x)
 | |
| {
 | |
| 	return(log(x));
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86log10(double x)
 | |
| {
 | |
| 	return(log10(x));
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86modf(double x,double* y)
 | |
| {
 | |
| 	return modf(x,y);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86pow(double x, double y)
 | |
| {
 | |
| 	return(pow(x,y));
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86sin(double x)
 | |
| {
 | |
| 	return sin(x);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86sqrt(double x)
 | |
| {
 | |
| 	return(sqrt(x));
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86strtod(const char *s, char **end)
 | |
| {
 | |
| 	return strtod(s,end);
 | |
| }
 | |
| 
 | |
| _X_EXPORT long
 | |
| xf86strtol(const char *s, char **end, int radix)
 | |
| {
 | |
| 	return strtol(s,end,radix);
 | |
| }
 | |
| 
 | |
| _X_EXPORT unsigned long
 | |
| xf86strtoul(const char *s, char **end,int radix)
 | |
| {
 | |
| 	return strtoul(s,end,radix);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86tan(double x)
 | |
| {
 | |
| 	return tan(x);
 | |
| }
 | |
| 
 | |
| /* memory functions */
 | |
| _X_EXPORT void*
 | |
| xf86memchr(const void* s, int c, xf86size_t n)
 | |
| {
 | |
| 	return memchr(s,c,(size_t)n);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86memcmp(const void* s1, const void* s2, xf86size_t n)
 | |
| {
 | |
| 	return(memcmp(s1,s2,(size_t)n));
 | |
| }
 | |
| 
 | |
| _X_EXPORT void*
 | |
| xf86memcpy(void* dest, const void* src, xf86size_t n)
 | |
| {
 | |
| 	return(memcpy(dest,src,(size_t)n));
 | |
| }
 | |
| 
 | |
| _X_EXPORT void*
 | |
| xf86memmove(void* dest, const void* src, xf86size_t n)
 | |
| {
 | |
| 	return(memmove(dest,src,(size_t)n));
 | |
| }
 | |
| 
 | |
| _X_EXPORT void*
 | |
| xf86memset(void* s, int c, xf86size_t n)
 | |
| {
 | |
| 	return(memset(s,c,(size_t)n));
 | |
| }
 | |
| 
 | |
| /* ctype functions */
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86isalnum(int c)
 | |
| {
 | |
| 	return isalnum(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86isalpha(int c)
 | |
| {
 | |
| 	return isalpha(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86iscntrl(int c)
 | |
| {
 | |
| 	return iscntrl(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86isdigit(int c)
 | |
| {
 | |
| 	return isdigit(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86isgraph(int c)
 | |
| {
 | |
| 	return isgraph(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86islower(int c)
 | |
| {
 | |
| 	return islower(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86isprint(int c)
 | |
| {
 | |
| 	return isprint(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86ispunct(int c)
 | |
| {
 | |
| 	return ispunct(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86isspace(int c)
 | |
| {
 | |
| 	return isspace(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86isupper(int c)
 | |
| {
 | |
| 	return isupper(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86isxdigit(int c)
 | |
| {
 | |
| 	return isxdigit(c) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86tolower(int c)
 | |
| {
 | |
| 	return tolower(c);
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86toupper(int c)
 | |
| {
 | |
| 	return toupper(c);
 | |
| }
 | |
| 
 | |
| /* memory allocation functions */
 | |
| _X_EXPORT void*
 | |
| xf86calloc(xf86size_t sz,xf86size_t n)
 | |
| {
 | |
| 	return xcalloc(sz, n);
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86free(void* p)
 | |
| {
 | |
| 	xfree(p);
 | |
| }
 | |
| 
 | |
| _X_EXPORT double
 | |
| xf86frexp(double x, int *exp)
 | |
| {
 | |
|         return frexp(x, exp);
 | |
| }
 | |
| 
 | |
| _X_EXPORT void*
 | |
| xf86malloc(xf86size_t n)
 | |
| {
 | |
| 	return xalloc(n);
 | |
| }
 | |
| 
 | |
| _X_EXPORT void*
 | |
| xf86realloc(void* p, xf86size_t n)
 | |
| {
 | |
| 	return xrealloc(p,n);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * XXX This probably doesn't belong here.
 | |
|  */
 | |
| _X_EXPORT int
 | |
| xf86getpagesize()
 | |
| {
 | |
| 	static int pagesize = -1;
 | |
| 
 | |
| 	if (pagesize != -1)
 | |
| 		return pagesize;
 | |
| 
 | |
| #if defined(_SC_PAGESIZE) || defined(HAS_SC_PAGESIZE)
 | |
| 	pagesize = sysconf(_SC_PAGESIZE);
 | |
| #endif
 | |
| #ifdef _SC_PAGE_SIZE
 | |
| 	if (pagesize == -1)
 | |
| 		pagesize = sysconf(_SC_PAGE_SIZE);
 | |
| #endif
 | |
| #ifdef HAS_GETPAGESIZE
 | |
| 	if (pagesize == -1)
 | |
| 		pagesize = getpagesize();
 | |
| #endif
 | |
| #ifdef PAGE_SIZE
 | |
| 	if (pagesize == -1)
 | |
| 		pagesize = PAGE_SIZE;
 | |
| #endif
 | |
| 	if (pagesize == -1)
 | |
| 		FatalError("xf86getpagesize: Cannot determine page size");
 | |
| 
 | |
| 	return pagesize;
 | |
| }
 | |
| 
 | |
| 
 | |
| #define mapnum(e) case (e): return (xf86_##e)
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86GetErrno ()
 | |
| {
 | |
| 	switch (errno)
 | |
| 	{
 | |
| 		case 0: return 0;
 | |
| 		mapnum (EACCES);
 | |
| 		mapnum (EAGAIN);
 | |
| 		mapnum (EBADF);
 | |
| 		mapnum (EEXIST);
 | |
| 		mapnum (EFAULT);
 | |
| 		mapnum (EINTR);
 | |
| 		mapnum (EINVAL);
 | |
| 		mapnum (EISDIR);
 | |
| 		mapnum (ELOOP);		/* not POSIX 1 */
 | |
| 		mapnum (EMFILE);
 | |
| 		mapnum (ENAMETOOLONG);
 | |
| 		mapnum (ENFILE);
 | |
| 		mapnum (ENOENT);
 | |
| 		mapnum (ENOMEM);
 | |
| 		mapnum (ENOSPC);
 | |
| 		mapnum (ENOTDIR);
 | |
| 		mapnum (EPIPE);
 | |
| 		mapnum (EROFS);
 | |
| 		mapnum (ETXTBSY);	/* not POSIX 1 */
 | |
| 		mapnum (ENOTTY);
 | |
| #ifdef ENOSYS
 | |
| 		mapnum (ENOSYS);
 | |
| #endif
 | |
| 		mapnum (EBUSY);
 | |
| 		mapnum (ENODEV);
 | |
| 		mapnum (EIO);
 | |
| #ifdef ESRCH
 | |
| 		mapnum (ESRCH);
 | |
| #endif
 | |
| #ifdef ENXIO
 | |
| 		mapnum (ENXIO);  
 | |
| #endif
 | |
| #ifdef E2BIG
 | |
| 		mapnum (E2BIG);    
 | |
| #endif
 | |
| #ifdef ENOEXEC
 | |
| 		mapnum (ENOEXEC);
 | |
| #endif
 | |
| #ifdef ECHILD
 | |
| 		mapnum (ECHILD);
 | |
| #endif
 | |
| #ifdef ENOTBLK
 | |
| 		mapnum (ENOTBLK);
 | |
| #endif
 | |
| #ifdef EXDEV
 | |
| 		mapnum (EXDEV); 
 | |
| #endif
 | |
| #ifdef EFBIG
 | |
| 		mapnum (EFBIG);
 | |
| #endif
 | |
| #ifdef ESPIPE
 | |
| 		mapnum (ESPIPE);
 | |
| #endif
 | |
| #ifdef EMLINK
 | |
| 		mapnum (EMLINK);
 | |
| #endif
 | |
| #ifdef EDOM
 | |
| 		mapnum (EDOM);
 | |
| #endif
 | |
| #ifdef ERANGE
 | |
| 		mapnum (ERANGE);
 | |
| #endif
 | |
|      		default:
 | |
| 			return (xf86_UNKNOWN);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| #undef mapnum
 | |
| 
 | |
| 
 | |
| 
 | |
| #ifdef HAVE_SYSV_IPC
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86shmget(xf86key_t key, int size, int xf86shmflg)
 | |
| {
 | |
|     int shmflg;
 | |
|     int ret;
 | |
|     
 | |
|     /* This copies the permissions (SHM_R, SHM_W for u, g, o). */
 | |
|     shmflg = xf86shmflg & 0777;
 | |
| 
 | |
|     if (key == XF86IPC_PRIVATE) key = IPC_PRIVATE;
 | |
| 
 | |
|     if (xf86shmflg & XF86IPC_CREAT) shmflg |= IPC_CREAT;
 | |
|     if (xf86shmflg & XF86IPC_EXCL) shmflg |= IPC_EXCL;
 | |
|     if (xf86shmflg & XF86IPC_NOWAIT) shmflg |= IPC_NOWAIT;
 | |
|     ret = shmget((key_t) key, size, shmflg);
 | |
| 
 | |
|     if (ret == -1)
 | |
| 	xf86errno = xf86GetErrno();
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| _X_EXPORT char *
 | |
| xf86shmat(int id, char *addr, int xf86shmflg)
 | |
| {
 | |
|     int shmflg = 0;
 | |
|     pointer ret;
 | |
|     
 | |
| #ifdef SHM_RDONLY
 | |
|     if (xf86shmflg & XF86SHM_RDONLY) shmflg |= SHM_RDONLY;
 | |
| #endif
 | |
| #ifdef SHM_RND
 | |
|     if (xf86shmflg & XF86SHM_RND)    shmflg |= SHM_RND;
 | |
| #endif
 | |
| #ifdef SHM_REMAP
 | |
|     if (xf86shmflg & XF86SHM_REMAP)  shmflg |= SHM_REMAP;
 | |
| #endif
 | |
| 
 | |
|     ret = shmat(id,addr,shmflg);
 | |
| 
 | |
|     if (ret == (pointer) -1)
 | |
| 	xf86errno = xf86GetErrno();
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86shmdt(char *addr)
 | |
| {
 | |
|     int ret;
 | |
| 
 | |
|     ret = shmdt(addr);
 | |
| 
 | |
|     if (ret == -1) 
 | |
| 	xf86errno = xf86GetErrno();
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * for now only implement the rmid command.
 | |
|  */
 | |
| _X_EXPORT int
 | |
| xf86shmctl(int id, int xf86cmd, pointer buf)
 | |
| {
 | |
|     int cmd;
 | |
|     int ret;
 | |
|     
 | |
|     switch (xf86cmd) {
 | |
|     case XF86IPC_RMID:
 | |
| 	cmd = IPC_RMID;
 | |
| 	break;
 | |
|     default:
 | |
| 	return 0;
 | |
|     }
 | |
|     
 | |
|     ret = shmctl(id, cmd, buf);
 | |
| 
 | |
|     if (ret == -1)
 | |
| 	xf86errno = xf86GetErrno();
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| #else
 | |
| 
 | |
| int
 | |
| xf86shmget(xf86key_t key, int size, int xf86shmflg)
 | |
| {
 | |
|     xf86errno = ENOSYS;
 | |
|     
 | |
|     return -1;
 | |
| }
 | |
| 
 | |
| char *
 | |
| xf86shmat(int id, char *addr, int xf86shmflg)
 | |
| {
 | |
|     xf86errno = ENOSYS;
 | |
| 
 | |
|     return (char *)-1;
 | |
| }
 | |
| 
 | |
| int
 | |
| xf86shmctl(int id, int xf86cmd, pointer buf)
 | |
| {
 | |
|     xf86errno = ENOSYS;
 | |
| 
 | |
|     return -1;
 | |
| }
 | |
| 
 | |
| int
 | |
| xf86shmdt(char *addr)
 | |
| {
 | |
|     xf86errno = ENOSYS;
 | |
| 
 | |
|     return -1;
 | |
| }
 | |
| #endif /* HAVE_SYSV_IPC */
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86getjmptype()
 | |
| {
 | |
| #ifdef HAS_GLIBC_SIGSETJMP
 | |
|     return 1;
 | |
| #else
 | |
|     return 0;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| #ifdef HAS_GLIBC_SIGSETJMP
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86setjmp(xf86jmp_buf env)
 | |
| {
 | |
| #if defined(__GLIBC__) && (__GLIBC__ >= 2)
 | |
|     return __sigsetjmp((void *)env, xf86setjmp1_arg2());
 | |
| #else
 | |
|     return xf86setjmp1(env, xf86setjmp1_arg2());
 | |
| #endif
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86setjmp0(xf86jmp_buf env)
 | |
| {
 | |
|     FatalError("setjmp: type 0 called instead of type %d", xf86getjmptype());
 | |
| }
 | |
| 
 | |
| #if !defined(__GLIBC__) || (__GLIBC__ < 2)	/* libc5 */
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86setjmp1(xf86jmp_buf env, int arg2)
 | |
| {
 | |
|     __sigjmp_save((void *)env, arg2);
 | |
|     return __setjmp((void *)env);
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #else	/* HAS_GLIBC_SIGSETJMP */
 | |
| 
 | |
| int
 | |
| xf86setjmp1(xf86jmp_buf env, int arg2)
 | |
| {
 | |
|     FatalError("setjmp: type 1 called instead of type %d", xf86getjmptype());
 | |
| }
 | |
| 
 | |
| int 
 | |
| xf86setjmp0(xf86jmp_buf env)
 | |
| {
 | |
|   return setjmp((void *)env);
 | |
| }
 | |
| 
 | |
| #endif  /* HAS_GLIBC_SIGSETJMP */
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86setjmp1_arg2()
 | |
| {
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86setjmperror(xf86jmp_buf env)
 | |
| {
 | |
|     FatalError("setjmp: don't know how to handle setjmp() type %d",
 | |
| 	       xf86getjmptype());
 | |
| }
 | |
| 
 | |
| long
 | |
| xf86random()
 | |
| {
 | |
|     return random();
 | |
| }
 |