XRootD
XrdPosixPreload32.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d P o s i x P r e l o a d 3 2 . c c */
4 /* */
5 /* (c) 2005 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #if defined(__clang__) && defined(_FORTIFY_SOURCE)
32 #undef _FORTIFY_SOURCE
33 #endif
34 
35 #if defined(__LP64__) || defined(_LP64)
36 
37 #if !defined(MUSL)
38 #ifdef _LARGEFILE_SOURCE
39 #undef _LARGEFILE_SOURCE
40 #endif
41 
42 #ifdef _LARGEFILE64_SOURCE
43 #undef _LARGEFILE64_SOURCE
44 #endif
45 
46 #ifdef _FILE_OFFSET_BITS
47 #undef _FILE_OFFSET_BITS
48 #endif
49 
50 #ifdef _TIME_BITS
51 #undef _TIME_BITS
52 #endif
53 #endif
54 
55 #define XRDPOSIXPRELOAD32
56 
57 #include <cerrno>
58 #include <dirent.h>
59 #include <cstdio>
60 #include <cstdarg>
61 #include <sys/stat.h>
62 #include <sys/types.h>
63 #include <unistd.h>
64 #include <cstdlib>
65 
66 #if defined(__APPLE__) || defined(__FreeBSD__)
67 #include <sys/param.h>
68 #include <sys/mount.h>
69 #else
70 #include <sys/statfs.h>
71 #endif
72 
77 #include "XrdSys/XrdSysHeaders.hh"
78 #include "XrdSys/XrdSysPlatform.hh"
79 
80 /******************************************************************************/
81 /* G l o b a l D e c l a r a t i o n s */
82 /******************************************************************************/
83 
84 extern XrdPosixLinkage Xunix;
85 
86 namespace {bool isLite = (getenv("XRD_POSIX_PRELOAD_LITE") != 0);}
87 
88 /******************************************************************************/
89 /* 6 4 - t o 3 2 B i t C o n v e r s i o n s */
90 /******************************************************************************/
91 /******************************************************************************/
92 /* X r d P o s i x _ C o p y D i r e n t */
93 /******************************************************************************/
94 
95 // Macos is a curious beast. It is not an LP64 platform but offsets are
96 // defined as 64 bits anyway. So, the dirent structure is 64-bit conformable
97 // making CopyDirent() superfluous. In Solaris x86 there are no 32 bit interfaces.
98 //
99 #if !defined(__LP64__) && !defined(_LP64)
100 #if !defined(__APPLE__) && !defined(SUNX86) && !defined(__FreeBSD__) && !(defined(__FreeBSD_kernel__) && defined(__GLIBC__))
101 int XrdPosix_CopyDirent(struct dirent *dent, struct dirent64 *dent64)
102 {
103  const unsigned long long LLMask = 0xffffffff00000000LL;
104  int isdiff = (dent->d_name-(char *)dent) != (dent64->d_name-(char *)dent64);
105 
106 #if defined(__GNU__)
107  if (isdiff && (dent64->d_ino & LLMask))
108 #else
109  if (isdiff && ((dent64->d_ino & LLMask) || (dent64->d_off & LLMask)))
110 #endif
111  {errno = EOVERFLOW; return EOVERFLOW;}
112 
113  if (isdiff || (void *)dent != (void *)dent64)
114  {dent->d_ino = dent64->d_ino;
115 #if !defined(__GNU__)
116  dent->d_off = dent64->d_off;
117 #endif
118  dent->d_reclen = dent64->d_reclen;
119  dent->d_type = dent64->d_type;
120 #if defined(__GNU__)
121  dent->d_namlen = dent64->d_namlen;
122 #endif
123  strcpy(dent->d_name, dent64->d_name);
124  }
125  return 0;
126 }
127 #endif
128 #endif
129 
130 /******************************************************************************/
131 /* X r d P o s i x _ C o p y S t a t */
132 /******************************************************************************/
133 
134 // Macos is a curious beast. It is not an LP64 platform but stat sizes are
135 // defined as 64 bits anyway. So, the stat structure is 64-bit conformable
136 // making CopyStat() seemingly superfluous. However, starting in Darwin 10.5
137 // stat and stat64 are defined separately making it necessary to use CopyStat().
138 // In Solaris x86 there are no 32 bit interfaces.
139 //
140 #if !defined(__LP64__) && !defined(_LP64)
141 #if !defined(SUNX86) && !defined(__FreeBSD__)
142 int XrdPosix_CopyStat(struct stat *buf, struct stat64 &buf64)
143 {
144  const unsigned long long LLMask = 0xffffffff00000000LL;
145  const int INTMax = 0x7fffffff;
146 
147  if (buf64.st_size & LLMask)
148  if (buf64.st_mode & S_IFREG || buf64.st_mode & S_IFDIR)
149  {errno = EOVERFLOW; return -1;}
150  else buf->st_size = INTMax;
151  else buf->st_size = buf64.st_size; /* 64: File size in bytes */
152 
153  buf->st_ino = buf64.st_ino & LLMask ? INTMax : buf64.st_ino;
154  buf->st_blocks= buf64.st_blocks & LLMask ? INTMax : buf64.st_blocks;
155  buf->st_mode = buf64.st_mode; /* File mode (see mknod(2)) */
156  buf->st_dev = buf64.st_dev;
157  buf->st_rdev = buf64.st_rdev; /* ID of device */
158  buf->st_nlink = buf64.st_nlink; /* Number of links */
159  buf->st_uid = buf64.st_uid; /* User ID of the file's owner */
160  buf->st_gid = buf64.st_gid; /* Group ID of the file's group */
161  buf->st_atime = buf64.st_atime; /* Time of last access */
162  buf->st_mtime = buf64.st_mtime; /* Time of last data modification */
163  buf->st_ctime = buf64.st_ctime; /* Time of last file status change */
164  buf->st_blksize=buf64.st_blksize; /* Preferred I/O block size */
165  return 0;
166 }
167 #endif
168 #endif
169 
170 /******************************************************************************/
171 /* c r e a t */
172 /******************************************************************************/
173 
174 #if !defined(SUNX86) && !defined(__FreeBSD__)
175 extern "C"
176 {
177 int creat(const char *path, mode_t mode)
178 {
179  static int Init = Xunix.Init(&Init);
180 
181  return XrdPosix_Open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
182 }
183 }
184 #endif
185 
186 /******************************************************************************/
187 /* f c n t l */
188 /******************************************************************************/
189 
190 extern "C"
191 {
192 int fcntl(int fd, int cmd, ...)
193 {
194  static int Init = Xunix.Init(&Init);
195  va_list ap;
196  void *theArg;
197 
198  if (XrdPosixXrootd::myFD(fd)) return 0;
199  va_start(ap, cmd);
200  theArg = va_arg(ap, void *);
201  va_end(ap);
202  return Xunix.Fcntl(fd, cmd, theArg);
203 }
204 }
205 
206 /******************************************************************************/
207 /* f o p e n */
208 /******************************************************************************/
209 /*
210 extern "C"
211 {
212 FILE *fopen(const char *path, const char *mode)
213 {
214  static int Init = Xunix.Init(&Init);
215 
216  return XrdPosix_Fopen(path, mode);
217 }
218 }
219 */
220 
221 
222 /******************************************************************************/
223 /* f s e e k o */
224 /******************************************************************************/
225 
226 #ifndef SUNX86
227 extern "C"
228 {
229 int fseeko(FILE *stream, off_t offset, int whence)
230 {
231  static int Init = Xunix.Init(&Init);
232 
233  return XrdPosix_Fseeko(stream, offset, whence);
234 }
235 }
236 #endif
237 
238 /******************************************************************************/
239 /* f s t a t */
240 /******************************************************************************/
241 
242 #if !defined(SUNX86) && !defined(__FreeBSD__)
243 extern "C"
244 {
245 #if defined __linux__ && __GNUC__ && __GNUC__ >= 2
246 int __fxstat(int ver, int fildes, struct stat *buf)
247 #elif defined(__solaris__) && defined(__i386)
248 int _fxstat(int ver, int fildes, struct stat *buf)
249 #else
250 int fstat( int fildes, struct stat *buf)
251 #endif
252 {
253  static int Init = Xunix.Init(&Init);
254 
255 #if defined(__linux__) and defined(_STAT_VER)
256  if (!XrdPosixXrootd::myFD(fildes)) return Xunix.Fstat(ver, fildes, buf);
257 #else
258  if (!XrdPosixXrootd::myFD(fildes)) return Xunix.Fstat( fildes, buf);
259 #endif
260 
261 #if defined(__LP64__) || defined(_LP64)
262  return XrdPosix_Fstat(fildes, buf );
263 #else
264  int rc;
265  struct stat64 buf64;
266  if ((rc = XrdPosix_Fstat(fildes, (struct stat *)&buf64))) return rc;
267  return XrdPosix_CopyStat(buf, buf64);
268 #endif
269 }
270 }
271 #endif
272 
273 
274 /******************************************************************************/
275 /* f t e l l o */
276 /******************************************************************************/
277 
278 #ifndef SUNX86
279 extern "C"
280 {
281 off_t ftello(FILE *stream)
282 {
283  static int Init = Xunix.Init(&Init);
284 
285  return static_cast<off_t>(XrdPosix_Ftello(stream));
286 }
287 }
288 #endif
289 
290 /******************************************************************************/
291 /* f t r u n c a t e */
292 /******************************************************************************/
293 
294 #if !defined(SUNX86) && !defined(__FreeBSD__)
295 extern "C"
296 {
297 int ftruncate(int fildes, off_t offset)
298 {
299  static int Init = Xunix.Init(&Init);
300 
301  return XrdPosix_Ftruncate(fildes, offset);
302 }
303 }
304 #endif
305 
306 /******************************************************************************/
307 /* l s e e k */
308 /******************************************************************************/
309 
310 #if !defined(SUNX86) && !defined(__FreeBSD__)
311 extern "C"
312 {
313 off_t lseek(int fildes, off_t offset, int whence)
314 {
315  static int Init = Xunix.Init(&Init);
316 
317  return XrdPosix_Lseek(fildes, offset, whence);
318 }
319 }
320 #endif
321 
322 /******************************************************************************/
323 /* l s t a t */
324 /******************************************************************************/
325 
326 #if !defined(SUNX86) && !defined(__FreeBSD__)
327 extern "C"
328 {
329 #if defined __GNUC__ && __GNUC__ >= 2 && defined(__linux__)
330 int __lxstat(int ver, const char *path, struct stat *buf)
331 #elif defined(__solaris__) && defined(__i386)
332 int _lxstat(int ver, const char *path, struct stat *buf)
333 #else
334 int lstat( const char *path, struct stat *buf)
335 #endif
336 {
337  static int Init = Xunix.Init(&Init);
338 
339  if (!XrdPosix_isMyPath(path))
340 #if defined(__linux__) and defined(_STAT_VER)
341  return Xunix.Lstat(ver, path, buf);
342 #else
343  return Xunix.Lstat( path, buf);
344 #endif
345 
346 #if defined(__LP64__) || defined(_LP64)
347  return XrdPosix_Lstat(path, buf );
348 #else
349  struct stat64 buf64;
350  int rc;
351 
352  if ((rc = XrdPosix_Lstat(path, (struct stat *)&buf64))) return rc;
353  return XrdPosix_CopyStat(buf, buf64);
354 #endif
355 }
356 }
357 #endif
358 
359 /******************************************************************************/
360 /* o p e n */
361 /******************************************************************************/
362 
363 #if !defined(SUNX86) && !defined(__FreeBSD__)
364 extern "C"
365 {
366 int open(const char *path, int oflag, ...)
367 {
368  static int Init = Xunix.Init(&Init);
369  va_list ap;
370  int mode;
371 
372  va_start(ap, oflag);
373  mode = va_arg(ap, int);
374  va_end(ap);
375  return XrdPosix_Open(path, oflag, mode);
376 }
377 }
378 #endif
379 
380 /******************************************************************************/
381 /* p r e a d */
382 /******************************************************************************/
383 
384 #if !defined(SUNX86) && !defined(__FreeBSD__)
385 extern "C"
386 {
387 ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
388 {
389  static int Init = Xunix.Init(&Init);
390 
391  return XrdPosix_Pread(fildes, buf, nbyte, offset);
392 }
393 }
394 #endif
395 
396 /******************************************************************************/
397 /* r e a d d i r */
398 /******************************************************************************/
399 
400 #if !defined(SUNX86) && !defined(__FreeBSD__)
401 extern "C"
402 {
403 struct dirent* readdir(DIR *dirp)
404 {
405  static int Init = Xunix.Init(&Init);
406  struct dirent64 *dp64;
407 
408  if ( isLite )
409  {
410  if (!(dp64 = Xunix.Readdir64(dirp))) return 0;
411  }
412  else
413  if (!(dp64 = XrdPosix_Readdir64(dirp))) return 0;
414 
415 #if !defined(__APPLE__) && !defined(_LP64) && !defined(__LP64__) && !(defined(__FreeBSD_kernel__) && defined(__GLIBC__))
416  if (XrdPosix_CopyDirent((struct dirent *)dp64, dp64)) return 0;
417 #endif
418 
419  return (struct dirent *)dp64;
420 }
421 }
422 #endif
423 
424 /******************************************************************************/
425 /* r e a d d i r _ r */
426 /******************************************************************************/
427 
428 #if !defined(SUNX86) && !defined(__FreeBSD__)
429 extern "C"
430 {
431 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
432 {
433  static int Init = Xunix.Init(&Init);
434 #if defined(__APPLE__) || defined(__LP64__) || defined(_LP64) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
435  return XrdPosix_Readdir_r(dirp, entry, result);
436 #else
437  char buff[sizeof(struct dirent64) + 2048];
438  struct dirent64 *dp64 = (struct dirent64 *)buff;
439  struct dirent64 *mydirent;
440  int rc;
441 
442  if ( isLite )
443  {
444  if ((rc = Xunix.Readdir64_r(dirp, dp64, &mydirent))) return rc;
445  }
446  else
447  if ((rc = XrdPosix_Readdir64_r(dirp, dp64, &mydirent))) return rc;
448 
449  if (!mydirent) {*result = 0; return 0;}
450 
451  if ((rc = XrdPosix_CopyDirent(entry, dp64))) return rc;
452 
453  *result = entry;
454  return 0;
455 #endif
456 }
457 }
458 #endif
459 
460 /******************************************************************************/
461 /* p w r i t e */
462 /******************************************************************************/
463 
464 #if !defined(SUNX86) && !defined(__FreeBSD__)
465 extern "C"
466 {
467 ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
468 {
469  static int Init = Xunix.Init(&Init);
470 
471  return XrdPosix_Pwrite(fildes, buf, nbyte, offset);
472 }
473 }
474 #endif
475 
476 /******************************************************************************/
477 /* s t a t */
478 /******************************************************************************/
479 
480 #if !defined(SUNX86) && !defined(__FreeBSD__)
481 extern "C"
482 {
483 #if defined __GNUC__ && __GNUC__ >= 2
484 int __xstat(int ver, const char *path, struct stat *buf)
485 #elif defined(__solaris__) && defined(__i386)
486 int _xstat(int ver, const char *path, struct stat *buf)
487 #else
488 int stat( const char *path, struct stat *buf)
489 #endif
490 {
491  static int Init = Xunix.Init(&Init);
492 
493  if (!XrdPosix_isMyPath(path))
494 #ifdef __linux__
495  return Xunix.Stat(ver, path, buf);
496 #else
497  return Xunix.Stat( path, buf);
498 #endif
499 
500 #if defined(__LP64__) || defined(_LP64)
501  return XrdPosix_Stat(path, buf );
502 #else
503  struct stat64 buf64;
504  int rc;
505  if ((rc = XrdPosix_Stat(path, (struct stat *)&buf64))) return rc;
506  return XrdPosix_CopyStat(buf, buf64);
507 #endif
508 }
509 }
510 #endif
511 
512 /******************************************************************************/
513 /* s t a t f s */
514 /******************************************************************************/
515 
516 #if !defined(__solaris__) && !defined(__APPLE__) && !defined(__FreeBSD__)
517 extern "C"
518 {
519 int statfs( const char *path, struct statfs *buf)
520 {
521  static int Init = Xunix.Init(&Init);
522  struct statfs64 buf64;
523  int rc;
524 
525  if ((rc = XrdPosix_Statfs(path, (struct statfs *)&buf64))) return rc;
526  memset(buf, 0, sizeof(struct statfs));
527  buf->f_type = buf64.f_type;
528  buf->f_bsize = buf64.f_bsize;
529  buf->f_blocks = buf64.f_blocks;
530  buf->f_bfree = buf64.f_bfree;
531  buf->f_files = buf64.f_files;
532  buf->f_ffree = buf64.f_ffree;
533  buf->f_fsid = buf64.f_fsid;
534 #if defined(__FreeBSD_kernel__) && defined(__GLIBC__)
535  buf->f_namemax = buf64.f_namemax;
536 #else
537  buf->f_namelen = buf64.f_namelen;
538 #endif
539  return 0;
540 }
541 }
542 #endif
543 
544 /******************************************************************************/
545 /* s t a t v f s */
546 /******************************************************************************/
547 
548 #if !defined(__APPLE__) && !defined(SUNX86) && !defined(__FreeBSD__)
549 extern "C"
550 {
551 int statvfs( const char *path, struct statvfs *buf)
552 {
553  static int Init = Xunix.Init(&Init);
554  struct statvfs64 buf64;
555  int rc;
556  if ((rc = XrdPosix_Statvfs(path, (struct statvfs *)&buf64))) return rc;
557  memset(buf, 0, sizeof(struct statvfs));
558  buf->f_flag = buf64.f_flag;
559  buf->f_bsize = buf64.f_bsize;
560  buf->f_blocks = buf64.f_blocks;
561  buf->f_bfree = buf64.f_bfree;
562  buf->f_files = buf64.f_files;
563  buf->f_ffree = buf64.f_ffree;
564  buf->f_fsid = buf64.f_fsid;
565  buf->f_namemax = buf64.f_namemax;
566  return 0;
567 }
568 }
569 #endif
570 
571 /******************************************************************************/
572 /* t r u n c a t e */
573 /******************************************************************************/
574 
575 #if !defined(SUNX86) && !defined(__FreeBSD__)
576 extern "C"
577 {
578 int truncate(const char *path, off_t offset)
579 {
580  static int Init = Xunix.Init(&Init);
581 
582  return XrdPosix_Truncate(path, offset);
583 }
584 }
585 #endif
586 
587 #endif
int statvfs64(const char *path, struct statvfs64 *buf)
int statfs64(const char *path, struct statfs64 *buf)
int stat64(const char *path, struct stat64 *buf)
int XrdPosix_Statfs(const char *path, struct statfs *buf)
Definition: XrdPosix.cc:940
int XrdPosix_Truncate(const char *path, off_t offset)
Definition: XrdPosix.cc:1000
int XrdPosix_isMyPath(const char *path)
Definition: XrdPosix.cc:1080
long long XrdPosix_Ftello(FILE *stream)
Definition: XrdPosix.cc:481
int XrdPosix_Open(const char *path, int oflag,...)
Definition: XrdPosix.cc:639
ssize_t XrdPosix_Pread(int fildes, void *buf, size_t nbyte, off_t offset)
Definition: XrdPosix.cc:715
int XrdPosix_Readdir64_r(DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
Definition: XrdPosix.cc:815
int XrdPosix_Stat(const char *path, struct stat *buf)
Definition: XrdPosix.cc:914
int XrdPosix_Readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
Definition: XrdPosix.cc:806
ssize_t XrdPosix_Pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
Definition: XrdPosix.cc:731
int XrdPosix_Lstat(const char *path, struct stat *buf)
Definition: XrdPosix.cc:588
int XrdPosix_Statvfs(const char *path, struct statvfs *buf)
Definition: XrdPosix.cc:962
int XrdPosix_Fstat(int fildes, struct stat *buf)
Definition: XrdPosix.cc:414
off_t XrdPosix_Lseek(int fildes, off_t offset, int whence)
Definition: XrdPosix.cc:572
XrdPosixLinkage Xunix
int XrdPosix_Ftruncate(int fildes, long long offset)
Definition: XrdPosix.cc:498
struct dirent64 * XrdPosix_Readdir64(DIR *dirp)
Definition: XrdPosix.cc:790
int XrdPosix_Fseeko(FILE *stream, long long offset, int whence)
Definition: XrdPosix.cc:396
#define lseek(a, b, c)
Definition: XrdPosix.hh:52
#define fstat(a, b)
Definition: XrdPosix.hh:62
#define fseeko(a, b, c)
Definition: XrdPosix.hh:60
#define readdir_r(a, b, c)
Definition: XrdPosix.hh:89
#define open
Definition: XrdPosix.hh:76
#define statvfs(a, b)
Definition: XrdPosix.hh:105
#define stat(a, b)
Definition: XrdPosix.hh:101
#define ftello(a)
Definition: XrdPosix.hh:68
#define readdir(a)
Definition: XrdPosix.hh:86
#define ftruncate(a, b)
Definition: XrdPosix.hh:70
#define truncate(a, b)
Definition: XrdPosix.hh:111
#define pwrite(a, b, c, d)
Definition: XrdPosix.hh:107
#define statfs(a, b)
Definition: XrdPosix.hh:103
#define pread(a, b, c, d)
Definition: XrdPosix.hh:80
Retv_Fcntl(* Fcntl)(Args_Fcntl)
int Init(int *X=0)
Retv_Readdir64(* Readdir64)(Args_Readdir64)
Retv_Stat(* Stat)(Args_Stat)
Retv_Readdir64_r(* Readdir64_r)(Args_Readdir64_r)
Retv_Lstat(* Lstat)(Args_Lstat)
Retv_Fstat(* Fstat)(Args_Fstat)
static bool myFD(int fd)