XRootD
Loading...
Searching...
No Matches
XrdPosix.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d P o s i x . 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#include <cstdarg>
32#include <cstdio>
33#include <cstdlib>
34#include <sys/param.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <sys/syscall.h>
38#include <limits.h>
39#include <fcntl.h>
40#include <unistd.h>
41#include <sys/uio.h>
42
47#include "XrdSys/XrdSysStatx.hh"
48
49/******************************************************************************/
50/* G l o b a l O b j e c t s */
51/******************************************************************************/
52
54
56
58
59/******************************************************************************/
60/* U t i l i t y F u n c t i o n s */
61/******************************************************************************/
62
63#ifdef MUSL
64#include <stdio_ext.h>
65#endif
66
67static inline void fseterr(FILE *fp)
68{
69 /* Most systems provide FILE as a struct and the necessary bitmask in
70 <stdio.h>, because they need it for implementing getc() and putc() as
71 fast macros. This function is based on gnulib's fseterr.c */
72#if defined _IO_ERR_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
73 /* GNU libc, BeOS, Haiku, Linux libc5 */
74 fp->_flags |= _IO_ERR_SEEN;
75#elif defined __sferror || defined __APPLE__ || defined __DragonFly__ || defined __FreeBSD__ || defined __ANDROID__
76 /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
77 fp->_flags |= __SERR;
78#elif defined _IOERR
79 /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */
80 fp->_flag |= _IOERR;
81#elif defined __UCLIBC__ /* uClibc */
82 fp->__modeflags |= __FLAG_ERROR;
83#elif defined MUSL /* musl libc */
84 __fseterr(fp);
85#else
86 #error "Unsupported platform! Please report it as a bug."
87#endif
88}
89
90static inline void fseteof(FILE *fp)
91{
92 /* Most systems provide FILE as a struct and the necessary bitmask in
93 <stdio.h>, because they need it for implementing getc() and putc() as
94 fast macros. */
95#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
96 /* GNU libc, BeOS, Haiku, Linux libc5 */
97 fp->_flags |= _IO_EOF_SEEN;
98#elif defined __sferror || defined __APPLE__ || defined __DragonFly__ || defined __ANDROID__
99 /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
100 fp->_flags |= __SEOF;
101#elif defined _IOEOF
102 /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */
103 fp->_flag |= _IOEOF;
104#elif defined __UCLIBC__ /* uClibc */
105 fp->__modeflags |= __FLAG_EOF;
106#else
107 (void) fseek(fp, 0L, SEEK_END);
108#endif
109}
110
111/******************************************************************************/
112/* X r d R e s o l v e L i n k */
113/******************************************************************************/
114static ssize_t XrdResolveLink(const char *path, char *resolved, size_t rsize)
115{
116 // Make sure a path was passed
117 //
118 if (!path) {
119 errno = EINVAL;
120 return -1;
121 }
122
123 char unref[2049], filename[2049];
124 char *result = realpath(path, nullptr);
125
126 if (result) {
127 strlcpy(filename, result, sizeof(filename));
128 free(result);
129 } else {
130 bzero(filename, sizeof(filename));
131 bzero(unref, sizeof(unref));
132
133 strlcpy(filename, path, sizeof(filename));
134
135 // if it is a link, follow it until the end
136 int i = 0;
137 errno = 0;
138 while (readlink(filename, unref, sizeof(unref)) > 0 && ++i < 10) {
139 strlcpy(filename, unref, sizeof(filename));
140 bzero(unref, sizeof(unref)); // reset unref buffer
141 }
142 if (i == 10) {
143 errno = ELOOP;
144 return -1;
145 }
146 // succeed only if we found a file (EINVAL returned),
147 // or a link to a remote file (ENOENT returned)
148 if (errno != EINVAL && errno != ENOENT)
149 return -1;
150 }
151 size_t len = strlen(filename);
152 if (len > rsize) {
153 errno = ENAMETOOLONG;
154 return -1;
155 }
156 strlcpy(resolved, filename, rsize);
157 return len;
158}
159
160/******************************************************************************/
161/* X r d P o s i x _ A c c e s s */
162/******************************************************************************/
163extern "C"
164{
165int XrdPosix_Access(const char *path, int amode)
166{
167 char *myPath, buff[2048];
168 char unref[2049];
169
170 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
171 if (res > 0) {
172 // Return the results of a mkdir of a Unix file system
173 //
174 if (!(myPath = XrootPath.URL(unref, buff, sizeof(buff))))
175 return Xunix.Access( path, amode);
176
177 // Return the results of our version of access()
178 //
179 return Xroot.Access(myPath, amode);
180 } else {
181 return res;
182 }
183}
184}
185
186/******************************************************************************/
187/* X r d P o s i x _ A c l */
188/******************************************************************************/
189
190// This is a required addition for Solaris 10+ systems
191
192extern "C"
193{
194int XrdPosix_Acl(const char *path, int cmd, int nentries, void *aclbufp)
195{
196 char unref[2049];
197
198 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
199 if (res < 0) return res;
200 return (XrootPath.URL(unref, 0, 0)
201 ? Xunix.Acl("/tmp", cmd,nentries,aclbufp)
202 : Xunix.Acl(path, cmd,nentries,aclbufp));
203}
204}
205
206/******************************************************************************/
207/* X r d P o s i x _ C h d i r */
208/******************************************************************************/
209
210extern "C"
211{
212int XrdPosix_Chdir(const char *path)
213{
214 int rc;
215 char unref[2049];
216
217 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
218 if (res < 0) return res;
219
220 // Set the working directory if the actual chdir succeeded
221 //
222 if (!(rc = Xunix.Chdir(path))) XrootPath.CWD(unref);
223 return rc;
224}
225}
226
227/******************************************************************************/
228/* X r d P o s i x _ C l o s e */
229/******************************************************************************/
230
231extern "C"
232{
233int XrdPosix_Close(int fildes)
234{
235
236// Return result of the close
237//
238 return (Xroot.myFD(fildes) ? Xroot.Close(fildes) : Xunix.Close(fildes));
239}
240}
241
242/******************************************************************************/
243/* X r d P o s i x _ C l o s e d i r */
244/******************************************************************************/
245
246extern "C"
247{
248int XrdPosix_Closedir(DIR *dirp)
249{
250
251 return (Xroot.isXrootdDir(dirp) ? Xroot.Closedir(dirp)
252 : Xunix.Closedir(dirp));
253}
254}
255
256/******************************************************************************/
257/* X r d P o s i x _ C r e a t */
258/******************************************************************************/
259
260extern "C"
261{
262int XrdPosix_Creat(const char *path, mode_t mode)
263{
264 extern int XrdPosix_Open(const char *path, int oflag, ...);
265
266 return XrdPosix_Open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
267}
268}
269
270/******************************************************************************/
271/* X r d P o s i x _ F c l o s e */
272/******************************************************************************/
273
274extern "C"
275{
276int XrdPosix_Fclose(FILE *stream)
277{
278 int nullfd = fileno(stream);
279
280// Close the associated file
281//
282 if (Xroot.myFD(nullfd)) Xroot.Close(nullfd);
283
284// Now close the stream
285//
286 return Xunix.Fclose(stream);
287}
288}
289
290/******************************************************************************/
291/* X r d P o s i x _ F c n t l */
292/******************************************************************************/
293
294extern "C"
295{
296int XrdPosix_Fcntl(int fd, int cmd, ...)
297{
298 va_list ap;
299 void *theArg;
300
301 if (Xroot.myFD(fd)) return 0;
302 va_start(ap, cmd);
303 theArg = va_arg(ap, void *);
304 va_end(ap);
305 return Xunix.Fcntl64(fd, cmd, theArg);
306}
307}
308
309/******************************************************************************/
310/* X r d P o s i x _ F d a t a s y n c */
311/******************************************************************************/
312
313extern "C"
314{
315int XrdPosix_Fdatasync(int fildes)
316{
317
318// Return the result of the sync
319//
320 return (Xroot.myFD(fildes) ? Xroot.Fsync(fildes)
321 : Xunix.Fsync(fildes));
322}
323}
324
325/******************************************************************************/
326/* X r d P o s i x _ F g e t x a t t r */
327/******************************************************************************/
328
329#if defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
330extern "C"
331{
332ssize_t XrdPosix_Fgetxattr (int fd, const char *name, void *value, size_t size)
333{
334 if (Xroot.myFD(fd)) {errno = ENOTSUP; return -1;}
335 return Xunix.Fgetxattr(fd, name, value, size);
336}
337}
338#endif
339
340/******************************************************************************/
341/* X r d P o s i x _ F f l u s h */
342/******************************************************************************/
343
344extern "C"
345{
346int XrdPosix_Fflush(FILE *stream)
347{
348
349// Return the result of the fseek
350//
351 if (!stream || !Xroot.myFD(fileno(stream)))
352 return Xunix.Fflush(stream);
353
354 return Xroot.Fsync(fileno(stream));
355}
356}
357
358/******************************************************************************/
359/* X r d P o s i x _ F o p e n */
360/******************************************************************************/
361
362#define ISMODE(x) !strcmp(mode, x)
363
364extern "C"
365{
366FILE *XrdPosix_Fopen(const char *path, const char *mode)
367{
368 char *myPath, buff[2048];
369 int erc, fd, omode;
370 FILE *stream;
371
372 char unref[2049];
373
374 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
375 if (res < 0) return 0;
376
377// Transfer to unix if this is not our path
378//
379 if (!(myPath = XrootPath.URL(unref, buff, sizeof(buff))))
380 return Xunix.Fopen64(path, mode);
381
382// Translate the mode flags
383//
384 if (ISMODE("r") || ISMODE("rb")) omode = O_RDONLY;
385 else if (ISMODE("w") || ISMODE("wb")) omode = O_WRONLY
386 | O_CREAT | O_TRUNC;
387 else if (ISMODE("a") || ISMODE("ab")) omode = O_WRONLY
388 | O_CREAT | O_APPEND;
389 else if (ISMODE("r+") || ISMODE("rb+") || ISMODE("r+b")) omode = O_RDWR;
390 else if (ISMODE("w+") || ISMODE("wb+") || ISMODE("w+b")) omode = O_RDWR
391 | O_CREAT | O_TRUNC;
392 else if (ISMODE("a+") || ISMODE("ab+") || ISMODE("a+b")) omode = O_RDWR
393 | O_CREAT | O_APPEND;
394 else {errno = EINVAL; return 0;}
395
396// Now open the file
397//
398 if ((fd = Xroot.Open(myPath, omode | XrdPosixXrootd::isStream , 0)) < 0)
399 return 0;
400
401// First obtain a free stream
402//
403 if (!(stream = fdopen(fd, mode)))
404 {erc = errno; Xroot.Close(fd); errno = erc;}
405
406// All done
407//
408 return stream;
409}
410}
411
412/******************************************************************************/
413/* X r d P o s i x _ F r e a d */
414/******************************************************************************/
415
416extern "C"
417{
418size_t XrdPosix_Fread(void *ptr, size_t size, size_t nitems, FILE *stream)
419{
420 ssize_t bytes;
421 size_t rc = 0;
422 int fd = fileno(stream);
423
424 if (!Xroot.myFD(fd)) return Xunix.Fread(ptr, size, nitems, stream);
425
426 bytes = Xroot.Read(fd, ptr, size*nitems);
427
428// Get the right return code. Note that we cannot emulate the flags in sunx86
429//
430 if (bytes > 0 && size) rc = bytes/size;
431 else if (bytes < 0) fseterr(stream);
432 else fseteof(stream);
433
434 return rc;
435}
436}
437
438/******************************************************************************/
439/* X r d P o s i x _ F s e e k */
440/******************************************************************************/
441
442extern "C"
443{
444int XrdPosix_Fseek(FILE *stream, long offset, int whence)
445{
446
447// Return the result of the fseek
448//
449 if (!Xroot.myFD(fileno(stream)))
450 return Xunix.Fseek( stream, offset, whence);
451
452 return (Xroot.Lseek(fileno(stream), offset, whence) < 0 ? -1 : 0);
453}
454}
455
456/******************************************************************************/
457/* X r d P o s i x _ F s e e k o */
458/******************************************************************************/
459
460extern "C"
461{
462int XrdPosix_Fseeko(FILE *stream, long long offset, int whence)
463{
464
465// Return the result of the fseek
466//
467 if (!Xroot.myFD(fileno(stream)))
468 return Xunix.Fseeko64(stream, offset, whence);
469
470 return (Xroot.Lseek(fileno(stream), offset, whence) < 0 ? -1 : 0);
471}
472}
473
474/******************************************************************************/
475/* X r d P o s i x _ F s t a t */
476/******************************************************************************/
477
478extern "C"
479{
480 int XrdPosix_Fstat(int fildes, struct stat *buf)
481 {
482 if (Xroot.myFD(fildes)){
483 return(Xroot.Fstat(fildes, buf));
484 } else {
485#ifdef SYS_fstat
486 return syscall(SYS_fstat, fildes, buf);
487#else
488 errno = ENOSYS;
489 return -1;
490#endif
491 }
492 }
493 int XrdPosix_FstatV(int ver, int fildes, struct stat *buf)
494 {
495 if (Xroot.myFD(fildes)){
496 return(Xroot.Fstat(fildes, buf));
497 } else {
498#ifdef SYS_fstat
499 return syscall(SYS_fstat, fildes, buf);
500#else
501 errno = ENOSYS;
502 return -1;
503#endif
504 }
505 }
506}
507
508/******************************************************************************/
509/* X r d P o s i x _ F s t a t a t */
510/******************************************************************************/
511
512extern "C"
513{
514 int XrdPosix_Fstatat(int dirfd, const char *path, struct stat *buf, int flags)
515{
516 if (path && *path) {
517 char buff[2048];
518 char unref[2049];
519
520 if (!(flags & AT_SYMLINK_NOFOLLOW)) {
521 // We need to follow until path is no longer a link
522 ssize_t res = XrdResolveLink(path, unref, sizeof(unref));
523 if (res < 0) return res;
524 // links are pointing to file unref now which is not a link
525 } else {
526 strncpy(unref, path, 2048);
527 }
528 if (char *myPath = XrootPath.URL(unref, buff, sizeof(buff))) {
529 int ret = Xroot.Stat(myPath, (struct stat *)buf);
530 return (ret);
531 } else {
532 // not a root file
533#ifdef SYS_newfstatat
534 return syscall(SYS_newfstatat, dirfd, path, buf, flags);
535#else
536#ifdef SYS_fstatat
537 return syscall(SYS_fstatat, dirfd, path, buf, flags);
538#else
539 errno = ENOSYS;
540 return -1;
541#endif
542#endif
543 }
544 } else {
545 errno = EFAULT;
546 }
547 return -1;
548}
549}
550
551/******************************************************************************/
552/* X r d P o s i x _ F s y n c */
553/******************************************************************************/
554
555extern "C"
556{
557int XrdPosix_Fsync(int fildes)
558{
559
560// Return the result of the sync
561//
562 return (Xroot.myFD(fildes) ? Xroot.Fsync(fildes)
563 : Xunix.Fsync(fildes));
564}
565}
566
567/******************************************************************************/
568/* X r d P o s i x _ F t e l l */
569/******************************************************************************/
570
571extern "C"
572{
573long XrdPosix_Ftell(FILE *stream)
574{
575
576// Return the result of the tell
577//
578 if (!Xroot.myFD(fileno(stream))) return Xunix.Ftell(stream);
579
580 return static_cast<long>(Xroot.Lseek(fileno(stream), 0, SEEK_CUR));
581}
582}
583
584/******************************************************************************/
585/* X r d P o s i x _ F t e l l o */
586/******************************************************************************/
587
588extern "C"
589{
590long long XrdPosix_Ftello(FILE *stream)
591{
592
593// Return the result of the tell
594//
595 if (!Xroot.myFD(fileno(stream))) return Xunix.Ftello64(stream);
596
597 return Xroot.Lseek(fileno(stream), 0, SEEK_CUR);
598}
599}
600
601/******************************************************************************/
602/* X r d P o s i x _ F t r u n c a t e */
603/******************************************************************************/
604
605extern "C"
606{
607int XrdPosix_Ftruncate(int fildes, long long offset)
608{
609
610// Return the result of the ftruncate
611//
612 return (Xroot.myFD(fildes) ? Xroot.Ftruncate (fildes, offset)
613 : Xunix.Ftruncate64(fildes, offset));
614}
615}
616
617/******************************************************************************/
618/* X r d P o s i x _ F w r i t e */
619/******************************************************************************/
620
621extern "C"
622{
623size_t XrdPosix_Fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream)
624{
625 size_t bytes, rc = 0;
626 int fd = fileno(stream);
627
628 if (!Xroot.myFD(fd)) return Xunix.Fwrite(ptr, size, nitems, stream);
629
630 bytes = Xroot.Write(fd, ptr, size*nitems);
631
632// Get the right return code.
633//
634 if (bytes > 0 && size) rc = bytes/size;
635 else fseterr(stream);
636
637 return rc;
638}
639}
640
641/******************************************************************************/
642/* X r d P o s i x _ G e t x a t t r */
643/******************************************************************************/
644
645#if defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
646extern "C"
647{
648ssize_t XrdPosix_Getxattr (const char *path, const char *name, void *value, size_t size)
649{
650 char *myPath, buff[2048];
651 char unref[2049];
652
653 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
654 if (res < 0) return res;
655 if (!(myPath = XrootPath.URL(unref, buff, sizeof(buff))))
656 return Xunix.Getxattr(path, name, value, size);
657
658 return Xroot.Getxattr(myPath, name, value, size);
659}
660}
661#endif
662
663/******************************************************************************/
664/* X r d P o s i x _ L g e t x a t t r */
665/******************************************************************************/
666
667#if defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
668extern "C"
669{
670ssize_t XrdPosix_Lgetxattr (const char *path, const char *name, void *value, size_t size)
671{
672 char unref[2049];
673
674 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
675 if (res < 0) return res;
676
677 if (XrootPath.URL(unref, 0, 0)) {errno = ENOTSUP; return -1;}
678 return Xunix.Lgetxattr(path, name, value, size);
679}
680}
681#endif
682
683/******************************************************************************/
684/* X r d P o s i x _ L s e e k */
685/******************************************************************************/
686
687extern "C"
688{
689off_t XrdPosix_Lseek(int fildes, off_t offset, int whence)
690{
691
692// Return the operation of the seek
693//
694 return (Xroot.myFD(fildes) ? Xroot.Lseek (fildes, offset, whence)
695 : Xunix.Lseek64(fildes, offset, whence));
696}
697}
698
699/******************************************************************************/
700/* X r d P o s i x _ L s t a t */
701/******************************************************************************/
702
703extern "C"
704{
705int XrdPosix_Lstat(const char *path, struct stat *buf)
706{
707 char *myPath, buff[2048];
708
709// Make sure a path was passed
710//
711 if (!path) {errno = EFAULT; return -1;}
712
713// Return the results of an open of a Unix file
714//
715 myPath = XrootPath.URL(path, buff, sizeof(buff));
716 if (myPath){
717 return Xroot.Stat(myPath, buf);
718 } else {
719#ifdef SYS_lstat
720 return syscall(SYS_lstat, path, buf);
721#else
722 errno = ENOSYS;
723 return -1;
724#endif
725 }
726}
727}
728
729/******************************************************************************/
730/* X r d P o s i x _ M k d i r */
731/******************************************************************************/
732
733extern "C"
734{
735int XrdPosix_Mkdir(const char *path, mode_t mode)
736{
737 char *myPath, buff[2048];
738 char unref[2049];
739
740 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
741 if (res < 0) return res;
742
743// Return the results of a mkdir of a Unix file system
744//
745 if (!(myPath = XrootPath.URL(unref, buff, sizeof(buff))))
746 return Xunix.Mkdir(path, mode);
747
748// Return the results of an mkdir of an xrootd file system
749//
750 return Xroot.Mkdir(myPath, mode);
751}
752}
753
754/******************************************************************************/
755/* X r d P o s i x _ O p e n */
756/******************************************************************************/
757
758extern "C"
759{
760int XrdPosix_Open(const char *path, int oflag, ...)
761{
762 char *myPath, buff[2048];
763 char unref[2049];
764 va_list ap;
765 int mode;
766 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
767 if (res < 0) return res;
768 // Return the results of an open of a Unix file
769 //
770 if (!(myPath = XrootPath.URL(unref, buff, sizeof(buff))))
771 {if (!(oflag & O_CREAT)) return Xunix.Open64(unref, oflag);
772 va_start(ap, oflag);
773 mode = va_arg(ap, int);
774 va_end(ap);
775 return Xunix.Open64(unref, oflag, (mode_t)mode);
776 }
777
778 // Return the results of an open of an xrootd file
779 //
780 if (!(oflag & O_CREAT)) return Xroot.Open(myPath, oflag);
781 va_start(ap, oflag);
782 mode = va_arg(ap, int);
783 va_end(ap);
784 return Xroot.Open(myPath, oflag, (mode_t)mode);
785}
786}
787
788/******************************************************************************/
789/* X r d P o s i x _ O p e n a t */
790/******************************************************************************/
791
792extern "C"
793{
794int XrdPosix_Openat(int dirfd, const char *path, int flag, ...)
795{
796 char *myPath, buff[2048];
797 char unref[2049];
798 va_list ap;
799 int mode;
800 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
801 if (res < 0) return res;
802
803 if (!(myPath = XrootPath.URL(unref, buff, sizeof(buff)))){
804 mode_t mode = 0;
805 if (flag & (O_CREAT)) {
806 va_start(ap, flag);
807 mode = va_arg(ap, int);
808 va_end(ap);
809 }
810#ifdef SYS_openat
811 return (syscall(SYS_openat, dirfd, path, flag, (mode_t)mode));
812#else
813 errno = ENOSYS;
814 return -1;
815#endif
816 } else {
817 // Return the results of an open of an xrootd file
818 //
819 if (!(flag & O_CREAT)) return Xroot.Open(myPath, flag);
820 va_start(ap, flag);
821 mode = va_arg(ap, int);
822 va_end(ap);
823 return Xroot.Open(myPath, flag, (mode_t)mode);
824 }
825}
826}
827
828/******************************************************************************/
829/* X r d P o s i x _ O p e n d i r */
830/******************************************************************************/
831
832extern "C"
833{
834DIR* XrdPosix_Opendir(const char *path)
835{
836 char *myPath, buff[2048];
837 char unref[2049];
838
839 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
840 if (res < 0) return NULL;
841
842// Unix opendir
843//
844 if (!(myPath = XrootPath.URL(unref, buff, sizeof(buff))))
845 return Xunix.Opendir(path);
846
847// Xrootd opendir
848//
849 return Xroot.Opendir(myPath);
850}
851}
852
853/******************************************************************************/
854/* X r d P o s i x _ P a t h c o n f */
855/******************************************************************************/
856
857// This is a required addition for Solaris 10+ systems
858
859extern "C"
860{
861long XrdPosix_Pathconf(const char *path, int name)
862{
863 char unref[2049];
864
865 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
866 if (res < 0) return res;
867
868 return (XrootPath.URL(unref, 0, 0) ? Xunix.Pathconf("/tmp", name)
869 : Xunix.Pathconf(unref, name));
870}
871}
872
873/******************************************************************************/
874/* X r d P o s i x _ P r e a d */
875/******************************************************************************/
876
877extern "C"
878{
879ssize_t XrdPosix_Pread(int fildes, void *buf, size_t nbyte, off_t offset)
880{
881
882// Return the results of the read
883//
884 return (Xroot.myFD(fildes) ? Xroot.Pread (fildes, buf, nbyte, offset)
885 : Xunix.Pread64(fildes, buf, nbyte, offset));
886}
887}
888
889/******************************************************************************/
890/* X r d P o s i x _ P w r i t e */
891/******************************************************************************/
892
893extern "C"
894{
895ssize_t XrdPosix_Pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
896{
897
898// Return the results of the write
899//
900 return (Xroot.myFD(fildes) ? Xroot.Pwrite (fildes, buf, nbyte, offset)
901 : Xunix.Pwrite64(fildes, buf, nbyte, offset));
902}
903}
904
905/******************************************************************************/
906/* X r d P o s i x _ R e a d */
907/******************************************************************************/
908
909extern "C"
910{
911ssize_t XrdPosix_Read(int fildes, void *buf, size_t nbyte)
912{
913
914// Return the results of the read
915//
916 return (Xroot.myFD(fildes) ? Xroot.Read(fildes, buf, nbyte)
917 : Xunix.Read(fildes, buf, nbyte));
918}
919}
920
921/******************************************************************************/
922/* X r d P o s i x _ R e a d v */
923/******************************************************************************/
924
925extern "C"
926{
927ssize_t XrdPosix_Readv(int fildes, const struct iovec *iov, int iovcnt)
928{
929
930// Return results of the readv
931//
932 return (Xroot.myFD(fildes) ? Xroot.Readv(fildes, iov, iovcnt)
933 : Xunix.Readv(fildes, iov, iovcnt));
934}
935}
936
937/******************************************************************************/
938/* X r d P o s i x _ R e a d d i r */
939/******************************************************************************/
940
941extern "C"
942{
943// On some platforms both 32- and 64-bit versions are callable. so do the same
944//
945struct dirent * XrdPosix_Readdir (DIR *dirp)
946{
947
948// Return result of readdir
949//
950 return (Xroot.isXrootdDir(dirp) ? Xroot.Readdir(dirp)
951 : Xunix.Readdir(dirp));
952}
953
954struct dirent64 * XrdPosix_Readdir64(DIR *dirp)
955{
956
957// Return result of readdir
958//
959 return (Xroot.isXrootdDir(dirp) ? Xroot.Readdir64(dirp)
960 : Xunix.Readdir64(dirp));
961}
962}
963
964/******************************************************************************/
965/* X r d P o s i x _ R e a d d i r _ r */
966/******************************************************************************/
967
968extern "C"
969{
970int XrdPosix_Readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
971{
972
973// Return result of readdir
974//
975 return (Xroot.isXrootdDir(dirp) ? Xroot.Readdir_r(dirp,entry,result)
976 : Xunix.Readdir_r(dirp,entry,result));
977}
978
979int XrdPosix_Readdir64_r(DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
980{
981
982// Return result of readdir
983//
984 return (Xroot.isXrootdDir(dirp) ? Xroot.Readdir64_r(dirp,entry,result)
985 : Xunix.Readdir64_r(dirp,entry,result));
986}
987}
988
989/******************************************************************************/
990/* X r d P o s i x _ R e n a m e */
991/******************************************************************************/
992
993extern "C"
994{
995int XrdPosix_Rename(const char *oldpath, const char *newpath)
996{
997 char *oldPath, buffold[2048], *newPath, buffnew[2048];
998
999// Make sure a path was passed
1000//
1001 if (!oldpath || !newpath) {errno = EFAULT; return -1;}
1002
1003// Return the results of a mkdir of a Unix file system
1004//
1005 if (!(oldPath = XrootPath.URL(oldpath, buffold, sizeof(buffold)))
1006 || !(newPath = XrootPath.URL(newpath, buffnew, sizeof(buffnew))))
1007 return Xunix.Rename(oldpath, newpath);
1008
1009// Return the results of an mkdir of an xrootd file system
1010//
1011 return Xroot.Rename(oldPath, newPath);
1012}
1013}
1014
1015/******************************************************************************/
1016/* X r d P o s i x _ R e w i n d d i r */
1017/******************************************************************************/
1018
1019extern "C"
1020{
1021void XrdPosix_Rewinddir(DIR *dirp)
1022{
1023
1024// Return result of rewind
1025//
1026 return (Xroot.isXrootdDir(dirp) ? Xroot.Rewinddir(dirp)
1027 : Xunix.Rewinddir(dirp));
1028}
1029}
1030
1031/******************************************************************************/
1032/* X r d P o s i x _ R m d i r */
1033/******************************************************************************/
1034
1035extern "C"
1036{
1037int XrdPosix_Rmdir(const char *path)
1038{
1039 char *myPath, buff[2048];
1040
1041// Make sure a path was passed
1042//
1043 if (!path) {errno = EFAULT; return -1;}
1044
1045// Return the results of a mkdir of a Unix file system
1046//
1047 if (!(myPath = XrootPath.URL(path, buff, sizeof(buff))))
1048 return Xunix.Rmdir(path);
1049
1050// Return the results of an mkdir of an xrootd file system
1051//
1052 return Xroot.Rmdir(myPath);
1053}
1054}
1055
1056/******************************************************************************/
1057/* X r d P o s i x _ S e e k d i r */
1058/******************************************************************************/
1059
1060extern "C"
1061{
1062void XrdPosix_Seekdir(DIR *dirp, long loc)
1063{
1064
1065// Call seekdir
1066//
1067 (Xroot.isXrootdDir(dirp) ? Xroot.Seekdir(dirp, loc)
1068 : Xunix.Seekdir(dirp, loc));
1069}
1070}
1071
1072/******************************************************************************/
1073/* X r d P o s i x _ S t a t */
1074/******************************************************************************/
1075
1076extern "C"
1077{
1078int XrdPosix_Stat(const char *path, struct stat *buf)
1079{
1080 char buff[2048];
1081 char unref[2049];
1082
1083 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
1084 if (res < 0) return res;
1085
1086 // links are pointing to file unref now which is not a link
1087 if (char *myPath = XrootPath.URL(unref, buff, sizeof(buff))) {
1088 int ret = Xroot.Stat(myPath, buf);
1089 return (ret);
1090 } else {
1091 // not a root file
1092#ifdef SYS_stat
1093 return syscall(SYS_stat, path, buf);
1094#else
1095 errno = ENOSYS;
1096 return -1;
1097#endif
1098 }
1099}
1100}
1101
1102extern "C"
1103{
1104int XrdPosix_Statx(int dirfd, const char *path, int flags,
1105 unsigned int mask, XrdSysStatx *stx)
1106{
1107 if (path && *path) {
1108 char buff[2048];
1109 char unref[2049];
1110
1111 if (!(flags & AT_SYMLINK_NOFOLLOW)) {
1112 // We need to follow until path is no longer a link
1113 ssize_t res = XrdResolveLink(path, unref, sizeof(unref));
1114 if (res < 0) return res;
1115 } else {
1116 strncpy(unref, path, 2048);
1117 }
1118 if (char *myPath = XrootPath.URL(unref, buff, sizeof(buff))) {
1119 struct stat st{};
1120 if (int ret = XrdPosix_Stat(myPath, &st))
1121 return ret;
1122 XrdSysStatxHelpers::Stat2Statx(st, *stx);
1123 return 0;
1124 } else {
1125#ifdef SYS_statx
1126 int ret = syscall(SYS_statx, dirfd, path, flags, mask, stx);
1127 return ret;
1128#else
1129 errno = ENOSYS;
1130 return -1;
1131#endif
1132 }
1133 } else {
1134 errno = EFAULT;
1135 }
1136 return -1;
1137}
1138}
1139
1140/******************************************************************************/
1141/* X r d P o s i x _ S t a t f s */
1142/******************************************************************************/
1143
1144extern "C"
1145{
1146int XrdPosix_Statfs(const char *path, struct statfs *buf)
1147{
1148 char *myPath, buff[2048];
1149
1150 char unref[2049];
1151
1152 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
1153 if (res < 0) return res;
1154
1155// Return the results of an open of a Unix file
1156//
1157 return ((myPath = XrootPath.URL(unref, buff, sizeof(buff)))
1158 ? Xroot.Statfs(myPath, buf)
1159 : Xunix.Statfs64(path, (struct statfs64 *)buf));
1160}
1161}
1162
1163/******************************************************************************/
1164/* X r d P o s i x _ S t a t v f s */
1165/******************************************************************************/
1166
1167extern "C"
1168{
1169int XrdPosix_Statvfs(const char *path, struct statvfs *buf)
1170{
1171 char *myPath, buff[2048];
1172 char unref[2049];
1173
1174 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
1175 if (res < 0) return res;
1176
1177// Return the results of an open of a Unix file
1178//
1179 return ((myPath = XrootPath.URL(unref, buff, sizeof(buff)))
1180 ? Xroot.Statvfs(myPath, buf)
1181 : Xunix.Statvfs64(path, (struct statvfs64 *)buf));
1182}
1183}
1184
1185/******************************************************************************/
1186/* X r d P o s i x _ T e l l d i r */
1187/******************************************************************************/
1188
1189extern "C"
1190{
1191long XrdPosix_Telldir(DIR *dirp)
1192{
1193
1194// Return result of telldir
1195//
1196 return (Xroot.isXrootdDir(dirp) ? Xroot.Telldir(dirp)
1197 : Xunix.Telldir(dirp));
1198}
1199}
1200
1201/******************************************************************************/
1202/* X r d P o s i x _ T r u n c a t e */
1203/******************************************************************************/
1204
1205extern "C"
1206{
1207int XrdPosix_Truncate(const char *path, off_t offset)
1208{
1209 char *myPath, buff[2048];
1210 char unref[2049];
1211
1212 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
1213 if (res < 0) return res;
1214
1215// Return the results of a truncate of a Unix file system
1216//
1217 if (!(myPath = XrootPath.URL(unref, buff, sizeof(buff))))
1218 return Xunix.Truncate64(path, offset);
1219
1220// Return the results of an truncate of an xrootd file system
1221//
1222 return Xroot.Truncate(myPath, offset);
1223}
1224}
1225
1226/******************************************************************************/
1227/* X r d P o s i x _ U n l i n k */
1228/******************************************************************************/
1229
1230extern "C"
1231{
1232int XrdPosix_Unlink(const char *path)
1233{
1234 char *myPath, buff[2048];
1235 char unref[2049];
1236
1237 ssize_t res=XrdResolveLink(path, unref, sizeof(unref));
1238 if (res < 0) return res;
1239
1240// Return the result of a unlink of a Unix file
1241//
1242 if (!(myPath = XrootPath.URL(unref, buff, sizeof(buff))))
1243 return Xunix.Unlink(path);
1244
1245// Return the results of an unlink of an xrootd file
1246//
1247 return Xroot.Unlink(myPath);
1248}
1249}
1250
1251/******************************************************************************/
1252/* X r d P o s i x _ W r i t e */
1253/******************************************************************************/
1254
1255extern "C"
1256{
1257ssize_t XrdPosix_Write(int fildes, const void *buf, size_t nbyte)
1258{
1259
1260// Return the results of the write
1261//
1262 return (Xroot.myFD(fildes) ? Xroot.Write(fildes, buf, nbyte)
1263 : Xunix.Write(fildes, buf, nbyte));
1264}
1265}
1266
1267/******************************************************************************/
1268/* X r d P o s i x _ W r i t e v */
1269/******************************************************************************/
1270
1271extern "C"
1272{
1273ssize_t XrdPosix_Writev(int fildes, const struct iovec *iov, int iovcnt)
1274{
1275
1276// Return results of the writev
1277//
1278 return (Xroot.myFD(fildes) ? Xroot.Writev(fildes, iov, iovcnt)
1279 : Xunix.Writev(fildes, iov, iovcnt));
1280}
1281}
1282
1283/******************************************************************************/
1284/* X r d P o s i x _ i s M y P a t h */
1285/******************************************************************************/
1286
1287int XrdPosix_isMyPath(const char *path)
1288{
1289 return (0 != XrootPath.URL(path, 0, 0));
1290}
1291
1292/******************************************************************************/
1293/* X r d P o s i x _ U R L */
1294/******************************************************************************/
1295
1296char *XrdPosix_URL(const char *path, char *buff, int blen)
1297{
1298 return XrootPath.URL(path, buff, blen);
1299}
int statvfs64(const char *path, struct statvfs64 *buf)
int statfs64(const char *path, struct statfs64 *buf)
int XrdPosix_Statfs(const char *path, struct statfs *buf)
Definition XrdPosix.cc:1146
int XrdPosix_Truncate(const char *path, off_t offset)
Definition XrdPosix.cc:1207
ssize_t XrdPosix_Read(int fildes, void *buf, size_t nbyte)
Definition XrdPosix.cc:911
#define ISMODE(x)
Definition XrdPosix.cc:362
int XrdPosix_Closedir(DIR *dirp)
Definition XrdPosix.cc:248
int XrdPosix_Fsync(int fildes)
Definition XrdPosix.cc:557
ssize_t XrdPosix_Readv(int fildes, const struct iovec *iov, int iovcnt)
Definition XrdPosix.cc:927
static void fseterr(FILE *fp)
Definition XrdPosix.cc:67
int XrdPosix_isMyPath(const char *path)
Definition XrdPosix.cc:1287
long long XrdPosix_Ftello(FILE *stream)
Definition XrdPosix.cc:590
int XrdPosix_Open(const char *path, int oflag,...)
Definition XrdPosix.cc:760
void XrdPosix_Rewinddir(DIR *dirp)
Definition XrdPosix.cc:1021
ssize_t XrdPosix_Pread(int fildes, void *buf, size_t nbyte, off_t offset)
Definition XrdPosix.cc:879
int XrdPosix_Readdir64_r(DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
Definition XrdPosix.cc:979
int XrdPosix_Close(int fildes)
Definition XrdPosix.cc:233
int XrdPosix_Openat(int dirfd, const char *path, int flag,...)
Definition XrdPosix.cc:794
void XrdPosix_Seekdir(DIR *dirp, long loc)
Definition XrdPosix.cc:1062
int XrdPosix_Rmdir(const char *path)
Definition XrdPosix.cc:1037
int XrdPosix_Chdir(const char *path)
Definition XrdPosix.cc:212
int XrdPosix_Stat(const char *path, struct stat *buf)
Definition XrdPosix.cc:1078
int XrdPosix_Rename(const char *oldpath, const char *newpath)
Definition XrdPosix.cc:995
int XrdPosix_Fcntl(int fd, int cmd,...)
Definition XrdPosix.cc:296
int XrdPosix_Fseek(FILE *stream, long offset, int whence)
Definition XrdPosix.cc:444
long XrdPosix_Ftell(FILE *stream)
Definition XrdPosix.cc:573
static void fseteof(FILE *fp)
Definition XrdPosix.cc:90
int XrdPosix_Readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
Definition XrdPosix.cc:970
XrdPosixXrootd Xroot
Definition XrdPosix.cc:53
int XrdPosix_Mkdir(const char *path, mode_t mode)
Definition XrdPosix.cc:735
static ssize_t XrdResolveLink(const char *path, char *resolved, size_t rsize)
Definition XrdPosix.cc:114
int XrdPosix_Fflush(FILE *stream)
Definition XrdPosix.cc:346
DIR * XrdPosix_Opendir(const char *path)
Definition XrdPosix.cc:834
ssize_t XrdPosix_Writev(int fildes, const struct iovec *iov, int iovcnt)
Definition XrdPosix.cc:1273
XrdPosixXrootPath XrootPath
Definition XrdPosix.cc:55
long XrdPosix_Telldir(DIR *dirp)
Definition XrdPosix.cc:1191
int XrdPosix_FstatV(int ver, int fildes, struct stat *buf)
Definition XrdPosix.cc:493
ssize_t XrdPosix_Pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
Definition XrdPosix.cc:895
int XrdPosix_Lstat(const char *path, struct stat *buf)
Definition XrdPosix.cc:705
int XrdPosix_Fstatat(int dirfd, const char *path, struct stat *buf, int flags)
Definition XrdPosix.cc:514
int XrdPosix_Creat(const char *path, mode_t mode)
Definition XrdPosix.cc:262
int XrdPosix_Statx(int dirfd, const char *path, int flags, unsigned int mask, XrdSysStatx *stx)
Definition XrdPosix.cc:1104
int XrdPosix_Statvfs(const char *path, struct statvfs *buf)
Definition XrdPosix.cc:1169
int XrdPosix_Acl(const char *path, int cmd, int nentries, void *aclbufp)
Definition XrdPosix.cc:194
int XrdPosix_Fstat(int fildes, struct stat *buf)
Definition XrdPosix.cc:480
off_t XrdPosix_Lseek(int fildes, off_t offset, int whence)
Definition XrdPosix.cc:689
ssize_t XrdPosix_Write(int fildes, const void *buf, size_t nbyte)
Definition XrdPosix.cc:1257
XrdPosixLinkage Xunix
FILE * XrdPosix_Fopen(const char *path, const char *mode)
Definition XrdPosix.cc:366
size_t XrdPosix_Fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream)
Definition XrdPosix.cc:623
int XrdPosix_Fclose(FILE *stream)
Definition XrdPosix.cc:276
int XrdPosix_Fdatasync(int fildes)
Definition XrdPosix.cc:315
int XrdPosix_Ftruncate(int fildes, long long offset)
Definition XrdPosix.cc:607
long XrdPosix_Pathconf(const char *path, int name)
Definition XrdPosix.cc:861
int XrdPosix_Unlink(const char *path)
Definition XrdPosix.cc:1232
char * XrdPosix_URL(const char *path, char *buff, int blen)
Definition XrdPosix.cc:1296
struct dirent64 * XrdPosix_Readdir64(DIR *dirp)
Definition XrdPosix.cc:954
size_t XrdPosix_Fread(void *ptr, size_t size, size_t nitems, FILE *stream)
Definition XrdPosix.cc:418
int XrdPosix_Fseeko(FILE *stream, long long offset, int whence)
Definition XrdPosix.cc:462
int XrdPosix_Access(const char *path, int amode)
Definition XrdPosix.cc:165
struct dirent * XrdPosix_Readdir(DIR *dirp)
Definition XrdPosix.cc:945
#define fseek(a, b, c)
Definition XrdPosix.hh:58
#define statvfs(a, b)
Definition XrdPosix.hh:111
#define stat(a, b)
Definition XrdPosix.hh:105
#define statfs(a, b)
Definition XrdPosix.hh:109
#define dirfd(x)
size_t strlcpy(char *dst, const char *src, size_t sz)
POSIX interface to XRootD with some extensions, as noted.
static const int isStream