XRootD
XrdSysFAttrSun.icc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S y s F A t t r S u n . i c c */
4 /* */
5 /* (c) 2010 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 <dirent.h>
32 #include <cerrno>
33 #include <fcntl.h>
34 #include <cstring>
35 #include <unistd.h>
36 #include <sys/stat.h>
37 #include <sys/types.h>
38 
39 #include "XrdSys/XrdSysFAttr.hh"
40 
41 /******************************************************************************/
42 /* P l a t f o r m D e p e n d e n c i e s */
43 /******************************************************************************/
44 
45 #ifndef ENOATTR
46 #define ENOATTR ENODATA
47 #endif
48 
49 /******************************************************************************/
50 /* X r d S y s F A t t r : : D e l */
51 /******************************************************************************/
52 
53 int XrdSysFAttr::Del(const char *Aname, const char *Path, int fd)
54 {
55  int ec = 0;
56 
57 // Open the directory associated with the path or file descriptor
58 //
59  fd = (fd < 0 ? attropen(Path, ".", O_RDONLY)
60  : openat( fd, ".", O_RDONLY|O_XATTR));
61 
62 // If the preceding open failed, diagnose the problem.
63 //
64  if (fd < 0) return Diagnose("open to remove", Aname, Path, errno);
65 
66 // Now unlink the attribute file
67 //
68  if (unlinkat(fd, Aname, 0) < 0) ec = Diagnose("remove", Aname, Path, errno);
69 
70 // All done
71 //
72  close(fd);
73  return ec;
74 }
75 
76 /******************************************************************************/
77 /* X r d S y s F A t t r : : G e t */
78 /******************************************************************************/
79 
80 int XrdSysFAttr::Get(const char *Aname, void *Aval, int Avsz,
81  const char *Path, int fd)
82 {
83  int ec = 0;
84 
85 // Open the directory associated with the path or file descriptor
86 //
87  fd = (fd < 0 ? attropen(Path, Aname, O_RDONLY)
88  : openat( fd, Aname, O_RDONLY|O_XATTR));
89 
90 // If the preceding open failed, diagnose the problem.
91 //
92  if (fd < 0) return Diagnose("open to get", Aname, Path, errno);
93  }
94 
95 // If a size was passed, then read the variable data. Otherwise, the caller
96 // wants to know the size of the attribute data. So, return that.
97 //
98  if (Avsz) {if ((ec = read(fd, Aval, Avsz)) < 0) ec = -errno;}
99  else {struct stat Stat;
100  ec = (fstat(fd, &Stat) ? -errno : Stat.st_size);
101  }
102 
103 // Close the underlying directory and diagnose any errors and return result.
104 //
105  close(fd);
106  if (ec < 0) ec = Diagnose("get", Aname, Path, -ec);
107  return ec;
108 }
109 
110 
111 /******************************************************************************/
112 /* X r d S y s F A t t r : : L i s t */
113 /******************************************************************************/
114 #if SOLARIS_VERSION < 11
115 #if !defined(__XOPEN_OR_POSIX)
116 #define dirfd(x) x->dd_fd
117 #else
118 #define dirfd(x) x->d_fd
119 #endif
120 #endif
121 
122 int XrdSysFAttr::List(AList **aPL, const char *Path, int fd, int getSz)
123 {
124  AList *aNew;
125  DIR *dP;
126  struct dirent *dEnt;
127  struct stat Stat;
128  int rc, maxSz = 0;
129 
130 // Open the directory associated with the path or file descriptor
131 //
132  *aPL = 0;
133  fd = (fd < 0 ? attropen(Path, ".", O_RDONLY)
134  : openat( fd, ".", O_RDONLY|O_XATTR));
135 
136 // If the preceding open failed, diagnose the problem. We ignore ENOATTR.
137 //
138  if (fd < 0)
139  {if (errno == ENOATTR) return 0;
140  return Diagnose("open to list", "*", Path, errno);
141  }
142 
143 // Now open the attribute directory
144 //
145  if (!(dP = fdopendir(fd)))
146  {rc = errno; close(fd);
147  if (rc == ENOATTR) return 0;
148  return Diagnose("open to list", "*", Path, rc);
149  }
150 
151 // Now list the directory entries (less dot and dot-dot) as attributes.
152 // If the size is wanted, we do this here to avoid multiple opens.
153 //
154  while((dEnt = readdir(dP)))
155  {if ( (strcmp(".", dEnt->d_name) && strcmp("..", dEnt->d_name))
156  && (aNew = getEnt(Path, fd, dEnt->d_name, *aPL, 0)))
157  {if (getSz)
158  {if (fstatat(dirfd(dP), dEnt->d_name, &Stat, 0))
159  {Diagnose("stat", dEnt->d_name, Path, errno); continue;}
160  aNew->Vlen = Stat.st_size;
161  if (maxSz < aNew->Vlen) maxSz = aNew->Vlen;
162  }
163  *aPL = aNew;
164  }
165  }
166 
167 // All done
168 //
169  closedir(dP); close(fd);
170  return maxSz;
171 }
172 
173 /******************************************************************************/
174 /* X r d S y s F A t t r : : S e t */
175 /******************************************************************************/
176 
177 int XrdSysFAttr::Set(const char *Aname, const void *Aval, int Avsz,
178  const char *Path, int fd, int isNew)
179 {
180  static const mode_t aMode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
181  int oFlag = O_CREAT|O_RDWR|O_TRUNC|O_XATTR | (isNew ? O_EXCL : 0);
182  int ec = 0;
183 
184 // Open the directory associated with the path or file descriptor
185 //
186  fd = (fd < 0 ? attropen(Path, Aname, oFlag, aMode)
187  : openat( fd, Aname, oFlag, aMode));
188 
189 // If the preceding open failed, diagnose the problem.
190 //
191  if (fd < 0) return Diagnose("open to set", Aname, Path, errno);
192 
193 // Write the data, the caller should have made sure the file was truncated.
194 //
195  if (write(fd, Aval, Avsz) < 0) ec = Diagnose("set", Aname, Path, errno);
196 
197 // All done, close the file and return result
198 //
199  close(fd);
200  return ec;
201 }
struct stat Stat
Definition: XrdCks.cc:49
int stat(const char *path, struct stat *buf)
struct dirent * readdir(DIR *dirp)
int fstat(int fildes, struct stat *buf)
ssize_t write(int fildes, const void *buf, size_t nbyte)
int closedir(DIR *dirp)
ssize_t read(int fildes, void *buf, size_t nbyte)
XrdOucString Path
#define ENOATTR
#define dirfd(x)
close(fd)