/******************************************************************************/
/* */
/* X r d P o s i x P r e l o a d 3 2 . c c */
/* */
/* (c) 2005 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#ifdef _LARGEFILE_SOURCE
#undef _LARGEFILE_SOURCE
#endif
#ifdef _LARGEFILE64_SOURCE
#undef _LARGEFILE64_SOURCE
#endif
#ifdef _FILE_OFFSET_BITS
#undef _FILE_OFFSET_BITS
#endif
#define XRDPOSIXPRELOAD32
#include
#include
#include
#include
#include
#include
#include
#include
#if defined(__APPLE__) || defined(__FreeBSD__)
#include
#include
#else
#include
#endif
#include "XrdPosix/XrdPosixExtern.hh"
#include "XrdPosix/XrdPosixLinkage.hh"
#include "XrdPosix/XrdPosixOsDep.hh"
#include "XrdPosix/XrdPosixXrootd.hh"
#include "XrdSys/XrdSysHeaders.hh"
#include "XrdSys/XrdSysPlatform.hh"
/******************************************************************************/
/* G l o b a l D e c l a r a t i o n s */
/******************************************************************************/
extern XrdPosixLinkage Xunix;
namespace {bool isLite = (getenv("XRD_POSIX_PRELOAD_LITE") != 0);}
/******************************************************************************/
/* 6 4 - t o 3 2 B i t C o n v e r s i o n s */
/******************************************************************************/
/******************************************************************************/
/* X r d P o s i x _ C o p y D i r e n t */
/******************************************************************************/
// Macos is a curious beast. It is not an LP64 platform but offsets are
// defined as 64 bits anyway. So, the dirent structure is 64-bit conformable
// making CopyDirent() superfluous. In Solaris x86 there are no 32 bit interfaces.
//
#if !defined(__LP64__) && !defined(_LP64)
#if !defined(__APPLE__) && !defined(SUNX86) && !defined(__FreeBSD__)
int XrdPosix_CopyDirent(struct dirent *dent, struct dirent64 *dent64)
{
const unsigned long long LLMask = 0xffffffff00000000LL;
int isdiff = (dent->d_name-(char *)dent) != (dent64->d_name-(char *)dent64);
if (isdiff && ((dent64->d_ino & LLMask) || (dent64->d_off & LLMask)))
{errno = EOVERFLOW; return EOVERFLOW;}
if (isdiff || (void *)dent != (void *)dent64)
{dent->d_ino = dent64->d_ino;
dent->d_off = dent64->d_off;
dent->d_reclen = dent64->d_reclen;
strcpy(dent->d_name, dent64->d_name);
}
return 0;
}
#endif
#endif
/******************************************************************************/
/* X r d P o s i x _ C o p y S t a t */
/******************************************************************************/
// Macos is a curious beast. It is not an LP64 platform but stat sizes are
// defined as 64 bits anyway. So, the stat structure is 64-bit conformable
// making CopyStat() seemingly superfluous. However, starting in Darwin 10.5
// stat and stat64 are defined separately making it necessary to use CopyStat().
// In Solaris x86 there are no 32 bit interfaces.
//
#if !defined(__LP64__) && !defined(_LP64)
#if !defined(SUNX86) && !defined(__FreeBSD__)
int XrdPosix_CopyStat(struct stat *buf, struct stat64 &buf64)
{
const unsigned long long LLMask = 0xffffffff00000000LL;
const int INTMax = 0x7fffffff;
if (buf64.st_size & LLMask)
if (buf64.st_mode & S_IFREG || buf64.st_mode & S_IFDIR)
{errno = EOVERFLOW; return -1;}
else buf->st_size = INTMax;
else buf->st_size = buf64.st_size; /* 64: File size in bytes */
buf->st_ino = buf64.st_ino & LLMask ? INTMax : buf64.st_ino;
buf->st_blocks= buf64.st_blocks & LLMask ? INTMax : buf64.st_blocks;
buf->st_mode = buf64.st_mode; /* File mode (see mknod(2)) */
buf->st_dev = buf64.st_dev;
buf->st_rdev = buf64.st_rdev; /* ID of device */
buf->st_nlink = buf64.st_nlink; /* Number of links */
buf->st_uid = buf64.st_uid; /* User ID of the file's owner */
buf->st_gid = buf64.st_gid; /* Group ID of the file's group */
buf->st_atime = buf64.st_atime; /* Time of last access */
buf->st_mtime = buf64.st_mtime; /* Time of last data modification */
buf->st_ctime = buf64.st_ctime; /* Time of last file status change */
buf->st_blksize=buf64.st_blksize; /* Preferred I/O block size */
return 0;
}
#endif
#endif
/******************************************************************************/
/* c r e a t */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
int creat(const char *path, mode_t mode)
{
static int Init = Xunix.Init(&Init);
return XrdPosix_Open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
}
}
#endif
/******************************************************************************/
/* f c n t l */
/******************************************************************************/
extern "C"
{
int fcntl(int fd, int cmd, ...)
{
static int Init = Xunix.Init(&Init);
va_list ap;
void *theArg;
if (XrdPosixXrootd::myFD(fd)) return 0;
va_start(ap, cmd);
theArg = va_arg(ap, void *);
va_end(ap);
return Xunix.Fcntl(fd, cmd, theArg);
}
}
/******************************************************************************/
/* f o p e n */
/******************************************************************************/
/*
extern "C"
{
FILE *fopen(const char *path, const char *mode)
{
static int Init = Xunix.Init(&Init);
return XrdPosix_Fopen(path, mode);
}
}
*/
/******************************************************************************/
/* f s e e k o */
/******************************************************************************/
#ifndef SUNX86
extern "C"
{
int fseeko(FILE *stream, off_t offset, int whence)
{
static int Init = Xunix.Init(&Init);
return XrdPosix_Fseeko(stream, offset, whence);
}
}
#endif
/******************************************************************************/
/* f s t a t */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
#if defined __linux__ && __GNUC__ && __GNUC__ >= 2
int __fxstat(int ver, int fildes, struct stat *buf)
#elif defined(__solaris__) && defined(__i386)
int _fxstat(int ver, int fildes, struct stat *buf)
#else
int fstat( int fildes, struct stat *buf)
#endif
{
static int Init = Xunix.Init(&Init);
#ifdef __linux__
if (!XrdPosixXrootd::myFD(fildes)) return Xunix.Fstat(ver, fildes, buf);
#else
if (!XrdPosixXrootd::myFD(fildes)) return Xunix.Fstat( fildes, buf);
#endif
#if defined(__LP64__) || defined(_LP64)
return XrdPosix_Fstat(fildes, buf );
#else
int rc;
struct stat64 buf64;
if ((rc = XrdPosix_Fstat(fildes, (struct stat *)&buf64))) return rc;
return XrdPosix_CopyStat(buf, buf64);
#endif
}
}
#endif
/******************************************************************************/
/* f t e l l o */
/******************************************************************************/
#ifndef SUNX86
extern "C"
{
off_t ftello(FILE *stream)
{
static int Init = Xunix.Init(&Init);
return static_cast(XrdPosix_Ftello(stream));
}
}
#endif
/******************************************************************************/
/* f t r u n c a t e */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
int ftruncate(int fildes, off_t offset)
{
static int Init = Xunix.Init(&Init);
return XrdPosix_Ftruncate(fildes, offset);
}
}
#endif
/******************************************************************************/
/* l s e e k */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
off_t lseek(int fildes, off_t offset, int whence)
{
static int Init = Xunix.Init(&Init);
return XrdPosix_Lseek(fildes, offset, whence);
}
}
#endif
/******************************************************************************/
/* l s t a t */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
#if defined __GNUC__ && __GNUC__ >= 2 && defined(__linux__)
int __lxstat(int ver, const char *path, struct stat *buf)
#elif defined(__solaris__) && defined(__i386)
int _lxstat(int ver, const char *path, struct stat *buf)
#else
int lstat( const char *path, struct stat *buf)
#endif
{
static int Init = Xunix.Init(&Init);
if (!XrdPosix_isMyPath(path))
#ifdef __linux__
return Xunix.Lstat(ver, path, buf);
#else
return Xunix.Lstat( path, buf);
#endif
#if defined(__LP64__) || defined(_LP64)
return XrdPosix_Lstat(path, buf );
#else
struct stat64 buf64;
int rc;
if ((rc = XrdPosix_Lstat(path, (struct stat *)&buf64))) return rc;
return XrdPosix_CopyStat(buf, buf64);
#endif
}
}
#endif
/******************************************************************************/
/* o p e n */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
int open(const char *path, int oflag, ...)
{
static int Init = Xunix.Init(&Init);
va_list ap;
int mode;
va_start(ap, oflag);
mode = va_arg(ap, int);
va_end(ap);
return XrdPosix_Open(path, oflag, mode);
}
}
#endif
/******************************************************************************/
/* p r e a d */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
{
static int Init = Xunix.Init(&Init);
return XrdPosix_Pread(fildes, buf, nbyte, offset);
}
}
#endif
/******************************************************************************/
/* r e a d d i r */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
struct dirent* readdir(DIR *dirp)
{
static int Init = Xunix.Init(&Init);
struct dirent64 *dp64;
if ( isLite )
{
if (!(dp64 = Xunix.Readdir64(dirp))) return 0;
}
else
if (!(dp64 = XrdPosix_Readdir64(dirp))) return 0;
#if !defined(__APPLE__) && !defined(_LP64) && !defined(__LP64__)
if (XrdPosix_CopyDirent((struct dirent *)dp64, dp64)) return 0;
#endif
return (struct dirent *)dp64;
}
}
#endif
/******************************************************************************/
/* r e a d d i r _ r */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
{
static int Init = Xunix.Init(&Init);
#if defined(__APPLE__) || defined(__LP64__) || defined(_LP64)
return XrdPosix_Readdir_r(dirp, entry, result);
#else
char buff[sizeof(struct dirent64) + 2048];
struct dirent64 *dp64 = (struct dirent64 *)buff;
struct dirent64 *mydirent;
int rc;
if ( isLite )
{
if ((rc = Xunix.Readdir64_r(dirp, dp64, &mydirent))) return rc;
}
else
if ((rc = XrdPosix_Readdir64_r(dirp, dp64, &mydirent))) return rc;
if (!mydirent) {*result = 0; return 0;}
if ((rc = XrdPosix_CopyDirent(entry, dp64))) return rc;
*result = entry;
return 0;
#endif
}
}
#endif
/******************************************************************************/
/* p w r i t e */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
{
static int Init = Xunix.Init(&Init);
return XrdPosix_Pwrite(fildes, buf, nbyte, offset);
}
}
#endif
/******************************************************************************/
/* s t a t */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
#if defined __GNUC__ && __GNUC__ >= 2
int __xstat(int ver, const char *path, struct stat *buf)
#elif defined(__solaris__) && defined(__i386)
int _xstat(int ver, const char *path, struct stat *buf)
#else
int stat( const char *path, struct stat *buf)
#endif
{
static int Init = Xunix.Init(&Init);
if (!XrdPosix_isMyPath(path))
#ifdef __linux__
return Xunix.Stat(ver, path, buf);
#else
return Xunix.Stat( path, buf);
#endif
#if defined(__LP64__) || defined(_LP64)
return XrdPosix_Stat(path, buf );
#else
struct stat64 buf64;
int rc;
if ((rc = XrdPosix_Stat(path, (struct stat *)&buf64))) return rc;
return XrdPosix_CopyStat(buf, buf64);
#endif
}
}
#endif
/******************************************************************************/
/* s t a t f s */
/******************************************************************************/
#if !defined(__solaris__) && !defined(__APPLE__) && !defined(__FreeBSD__)
extern "C"
{
int statfs( const char *path, struct statfs *buf)
{
static int Init = Xunix.Init(&Init);
struct statfs64 buf64;
int rc;
if ((rc = XrdPosix_Statfs(path, (struct statfs *)&buf64))) return rc;
memset(buf, 0, sizeof(struct statfs));
buf->f_type = buf64.f_type;
buf->f_bsize = buf64.f_bsize;
buf->f_blocks = buf64.f_blocks;
buf->f_bfree = buf64.f_bfree;
buf->f_files = buf64.f_files;
buf->f_ffree = buf64.f_ffree;
buf->f_fsid = buf64.f_fsid;
buf->f_namelen = buf64.f_namelen;
return 0;
}
}
#endif
/******************************************************************************/
/* s t a t v f s */
/******************************************************************************/
#if !defined(__APPLE__) && !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
int statvfs( const char *path, struct statvfs *buf)
{
static int Init = Xunix.Init(&Init);
struct statvfs64 buf64;
int rc;
if ((rc = XrdPosix_Statvfs(path, (struct statvfs *)&buf64))) return rc;
memset(buf, 0, sizeof(struct statvfs));
buf->f_flag = buf64.f_flag;
buf->f_bsize = buf64.f_bsize;
buf->f_blocks = buf64.f_blocks;
buf->f_bfree = buf64.f_bfree;
buf->f_files = buf64.f_files;
buf->f_ffree = buf64.f_ffree;
buf->f_fsid = buf64.f_fsid;
buf->f_namemax = buf64.f_namemax;
return 0;
}
}
#endif
/******************************************************************************/
/* t r u n c a t e */
/******************************************************************************/
#if !defined(SUNX86) && !defined(__FreeBSD__)
extern "C"
{
int truncate(const char *path, off_t offset)
{
static int Init = Xunix.Init(&Init);
return XrdPosix_Truncate(path, offset);
}
}
#endif