/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c,v 1.102 2003/11/19 03:52:58 dawes Exp $ */ /* * 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 #endif #if defined(linux) && !defined(__GLIBC__) #undef __STRICT_ANSI__ #endif #include #ifdef __UNIXOS2__ #define I_NEED_OS2_H #endif #include #include #include #include #if defined(__bsdi__) #undef _POSIX_SOURCE #undef _ANSI_SOURCE #endif #include #include #ifdef sun #include #endif #include #include #include #include "os.h" #include #include #include #include #include #include #ifdef __UNIXOS2__ #define NO_MMAP #include #endif #ifdef HAS_SVR3_MMAPDRV #define NO_MMAP #ifdef SELF_CONTAINED_WRAPPER #include #include #include #if !defined(_NEED_SYSI86) # include # include #endif #include struct kd_memloc MapDSC; int mmapFd = -2; #else extern struct kd_memloc MapDSC; extern int mmapFd; #endif #endif #ifndef NO_MMAP #include #ifndef MAP_FAILED #define MAP_FAILED ((caddr_t)-1) #endif #endif #if !defined(ISC) #include #endif #define NEED_XF86_TYPES #define NEED_XF86_PROTOTYPES #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 #else #ifdef SYSV #include #else #ifdef USG #include #else #include #ifndef dirent #define dirent direct #endif #endif #endif #endif typedef struct dirent DIRENTRY; #ifdef __UNIXOS2__ #define _POSIX_SOURCE #endif #ifdef ISC202 #include #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 #include #undef _POSIX_SOURCE #else #if (defined(ISC) && defined(_POSIX_SOURCE)) || defined(Lynx) || (defined (__alpha__) && defined(linux)) #include #endif #include #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 #include #endif #include #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 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 */ double xf86hypot(double x, double y) { return(hypot(x,y)); } void xf86qsort(void *base, xf86size_t nmemb, xf86size_t size, int (*comp)(const void *, const void *)) { qsort(base, nmemb, size, comp); } /* string functions */ char* xf86strcat(char* dest, const char* src) { return(strcat(dest,src)); } char* xf86strchr(const char* s, int c) { return strchr(s,c); } int xf86strcmp(const char* s1, const char* s2) { return strcmp(s1,s2); } /* Just like the BSD version. It assumes that tolower() is ANSI-compliant */ 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); } char* xf86strcpy(char* dest, const char* src) { return strcpy(dest,src); } xf86size_t xf86strcspn(const char* s1, const char* s2) { return (xf86size_t)strcspn(s1,s2); } xf86size_t xf86strlen(const char* s) { return (xf86size_t)strlen(s); } xf86size_t xf86strlcat(char *dest, const char *src, xf86size_t size) { return(strlcat(dest, src, size)); } xf86size_t xf86strlcpy(char *dest, const char *src, xf86size_t size) { return strlcpy(dest, src, size); } char* xf86strncat(char* dest, const char* src, xf86size_t n) { return strncat(dest,src,(size_t)n); } 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 */ 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; } char* xf86strncpy(char* dest, const char* src, xf86size_t n) { return strncpy(dest,src,(size_t)n); } char* xf86strpbrk(const char* s1, const char* s2) { return strpbrk(s1,s2); } char* xf86strrchr(const char* s, int c) { return strrchr(s,c); } xf86size_t xf86strspn(const char* s1, const char* s2) { return strspn(s1,s2); } char* xf86strstr(const char* s1, const char* s2) { return strstr(s1,s2); } char* xf86strtok(char* s1, const char* s2) { return strtok(s1,s2); } char* xf86strdup(const char* s) { return xstrdup(s); } 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; } 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; } void xf86bzero(void* s, unsigned int n) { memset(s, 0, n); } #ifdef HAVE_VSSCANF int xf86sscanf(char *s, const char *format, ...) #else 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 */ 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; } 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; } int xf86close(int fd) { int status = close(fd); xf86errno = xf86GetErrno(); return status; } 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); } int xf86ioctl(int fd, unsigned long request, pointer argp) { int status = ioctl(fd, request, argp); xf86errno = xf86GetErrno(); return status; } xf86ssize_t xf86read(int fd, void *buf, xf86size_t nbytes) { xf86ssize_t n = read(fd, buf, (size_t)nbytes); xf86errno = xf86GetErrno(); return n; } xf86ssize_t xf86write(int fd, const void *buf, xf86size_t nbytes) { xf86ssize_t n = write(fd, buf, (size_t)nbytes); xf86errno = xf86GetErrno(); return n; } 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 } 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 } 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; } 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; } 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; XF86FILE_priv stdhnd[3] = { { 0, XF86FILE_magic, NULL, "$stdinp$" }, { 0, XF86FILE_magic, NULL, "$stdout$" }, { 0, XF86FILE_magic, NULL, "$stderr$" } }; XF86FILE* xf86stdin = (XF86FILE*)&stdhnd[0]; XF86FILE* xf86stdout = (XF86FILE*)&stdhnd[1]; 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; } 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); } } 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; } int xf86printf(const char *format, ...) { int ret; va_list args; va_start(args, format); ret = printf(format,args); va_end(args); return ret; } 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; } 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); } int xf86vsprintf(char *s, const char *format, va_list ap) { return vsprintf(s, format, ap); } int xf86vsnprintf(char *s, xf86size_t len, const char *format, va_list ap) { return vsnprintf(s, (size_t)len, format, ap); } #ifdef HAVE_VFSCANF int xf86fscanf(XF86FILE* f, const char *format, ...) #else 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 } char * xf86fgets(char *buf, INT32 n, XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86fgets"); return fgets(buf,(int)n,fp->filehnd); } int xf86fputs(const char *buf, XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86fputs"); return fputs(buf,fp->filehnd); } int xf86getc(XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86getc"); return getc(fp->filehnd); } int xf86fgetc(XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86fgetc"); return fgetc(fp->filehnd); } int xf86fputc(int c,XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86fputc"); return fputc(c,fp->filehnd); } int xf86fflush(XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86fflush"); return fflush(fp->filehnd); } 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); } 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); } 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); } 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; 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); #ifndef __UNIXOS2__ mapnum (ETXTBSY); /* not POSIX 1 */ #endif 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()); */ long xf86fpossize() { return sizeof(fpos_t); } 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 } 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 } void xf86perror(const char *s) { perror(s); } int xf86remove(const char *s) { #ifdef _POSIX_SOURCE return remove(s); #else return unlink(s); #endif } 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 } void xf86rewind(XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86fsetpos"); rewind(fp->filehnd); } void xf86clearerr(XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86clearerr"); clearerr(fp->filehnd); } int xf86feof(XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86feof"); return feof(fp->filehnd); } int xf86ferror(XF86FILE* f) { XF86FILE_priv* fp = (XF86FILE_priv*)f; _xf86checkhndl(fp,"xf86ferror"); return ferror(fp->filehnd); } 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; } 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 } 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); } 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 */ 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. */ void xf86usleep(usec) unsigned long usec; { #if (defined(SYSV) || defined(SVR4)) && !defined(sun) syscall(3112, (usec) / 1000 + 1); #else usleep(usec); #endif } 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; } int xf86ffs(int mask) { int n; if (mask == 0) return 0; for (n = 1; (mask & 1)==0; n++) mask >>= 1; return n; } 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)); } 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); } int xf86execl(const char *pathname, const char *arg, ...) { #ifndef __UNIXOS2__ 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); } #else return(1); #endif /* __UNIXOS2__ Disable this crazy business for now */ } void xf86abort(void) { ErrorF("Module called abort() function\n"); abort(); } 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); } } 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; } 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; } void xf86rewinddir(XF86DIR* dirp) { XF86DIR_priv* dp = (XF86DIR_priv*)dirp; _xf86checkdirhndl(dp,"xf86readdir"); rewinddir(dp->dir); } 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; #ifndef __UNIXOS2__ if (xfmode & XF86_S_ISVTX) mode |= S_ISVTX; #endif 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; } int xf86chmod(const char *path, xf86mode_t xfmode) { mode_t mode = xfToOsChmodMode(xfmode); int rc = chmod(path, mode); xf86errno = xf86GetErrno(); return rc; } int xf86chown(const char *path, xf86uid_t owner, xf86gid_t group) { #ifndef __UNIXOS2__ int rc = chown(path, owner, group); #else int rc = 0; #endif xf86errno = xf86GetErrno(); return rc; } xf86uid_t xf86geteuid(void) { return geteuid(); } xf86gid_t xf86getegid(void) { return getegid(); } 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; #ifndef __UNIXOS2__ if (xfmode & XF86_S_IFBLK) mode |= S_IFBLK; #endif if (xfmode & XF86_S_IFIFO) mode |= S_IFIFO; return mode; } int xf86mknod(const char *pathname, xf86mode_t xfmode, xf86dev_t dev) { mode_t mode = xfToOsMknodMode(xfmode); #ifndef __UNIXOS2__ int rc = mknod(pathname, mode, dev); #else int rc = 0; #endif xf86errno = xf86GetErrno(); return rc; } unsigned int xf86sleep(unsigned int seconds) { return sleep(seconds); } 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 */ int xf86abs(int x) { return abs(x); } double xf86acos(double x) { return acos(x); } double xf86asin(double x) { return asin(x); } double xf86atan(double x) { return atan(x); } double xf86atan2(double x,double y) { return atan2(x,y); } double xf86atof(const char* s) { return atof(s); } int xf86atoi(const char* s) { return atoi(s); } long xf86atol(const char* s) { return atol(s); } double xf86ceil(double x) { return ceil(x); } double xf86cos(double x) { return(cos(x)); } double xf86exp(double x) { return(exp(x)); } double xf86fabs(double x) { return(fabs(x)); } int xf86finite(double x) { #ifndef QNX4 #ifndef __UNIXOS2__ return(finite(x)); #else return(isfinite(x)); #endif /* __UNIXOS2__ */ #else /* XXX Replace this with something that really works. */ return 1; #endif } double xf86floor(double x) { return floor(x); } double xf86fmod(double x,double y) { return fmod(x,y); } long xf86labs(long x) { return labs(x); } double xf86ldexp(double x, int exp) { return ldexp(x, exp); } double xf86log(double x) { return(log(x)); } double xf86log10(double x) { return(log10(x)); } double xf86modf(double x,double* y) { return modf(x,y); } double xf86pow(double x, double y) { return(pow(x,y)); } double xf86sin(double x) { return sin(x); } double xf86sqrt(double x) { return(sqrt(x)); } double xf86strtod(const char *s, char **end) { return strtod(s,end); } long xf86strtol(const char *s, char **end, int radix) { return strtol(s,end,radix); } unsigned long xf86strtoul(const char *s, char **end,int radix) { return strtoul(s,end,radix); } double xf86tan(double x) { return tan(x); } /* memory functions */ void* xf86memchr(const void* s, int c, xf86size_t n) { return memchr(s,c,(size_t)n); } int xf86memcmp(const void* s1, const void* s2, xf86size_t n) { return(memcmp(s1,s2,(size_t)n)); } void* xf86memcpy(void* dest, const void* src, xf86size_t n) { return(memcpy(dest,src,(size_t)n)); } void* xf86memmove(void* dest, const void* src, xf86size_t n) { return(memmove(dest,src,(size_t)n)); } void* xf86memset(void* s, int c, xf86size_t n) { return(memset(s,c,(size_t)n)); } /* ctype functions */ int xf86isalnum(int c) { return isalnum(c) ? 1 : 0; } int xf86isalpha(int c) { return isalpha(c) ? 1 : 0; } int xf86iscntrl(int c) { return iscntrl(c) ? 1 : 0; } int xf86isdigit(int c) { return isdigit(c) ? 1 : 0; } int xf86isgraph(int c) { return isgraph(c) ? 1 : 0; } int xf86islower(int c) { return islower(c) ? 1 : 0; } int xf86isprint(int c) { return isprint(c) ? 1 : 0; } int xf86ispunct(int c) { return ispunct(c) ? 1 : 0; } int xf86isspace(int c) { return isspace(c) ? 1 : 0; } int xf86isupper(int c) { return isupper(c) ? 1 : 0; } int xf86isxdigit(int c) { return isxdigit(c) ? 1 : 0; } int xf86tolower(int c) { return tolower(c); } int xf86toupper(int c) { return toupper(c); } /* memory allocation functions */ void* xf86calloc(xf86size_t sz,xf86size_t n) { return xcalloc(sz, n); } void xf86free(void* p) { xfree(p); } double xf86frexp(double x, int *exp) { return frexp(x, exp); } void* xf86malloc(xf86size_t n) { return xalloc(n); } void* xf86realloc(void* p, xf86size_t n) { return xrealloc(p,n); } /* * XXX This probably doesn't belong here. */ 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) 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); #ifndef __UNIXOS2__ mapnum (ETXTBSY); /* not POSIX 1 */ #endif 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 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; } 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; } int xf86shmdt(char *addr) { int ret; ret = shmdt(addr); if (ret == -1) xf86errno = xf86GetErrno(); return ret; } /* * for now only implement the rmid command. */ 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 */ int xf86getjmptype() { #ifdef HAS_GLIBC_SIGSETJMP return 1; #else return 0; #endif } #ifdef HAS_GLIBC_SIGSETJMP int xf86setjmp(xf86jmp_buf env) { #if defined(__GLIBC__) && (__GLIBC__ >= 2) return __sigsetjmp((void *)env, xf86setjmp1_arg2()); #else return xf86setjmp1(env, xf86setjmp1_arg2()); #endif } int xf86setjmp0(xf86jmp_buf env) { FatalError("setjmp: type 0 called instead of type %d", xf86getjmptype()); } #if !defined(__GLIBC__) || (__GLIBC__ < 2) /* libc5 */ 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 */ int xf86setjmp1_arg2() { return 1; } int xf86setjmperror(xf86jmp_buf env) { FatalError("setjmp: don't know how to handle setjmp() type %d", xf86getjmptype()); }