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