Actual source code: ftest.c
petsc-3.14.6 2021-03-30
2: #include <petscsys.h>
3: #include <errno.h>
4: #if defined(PETSC_HAVE_PWD_H)
5: #include <pwd.h>
6: #endif
7: #include <ctype.h>
8: #include <sys/stat.h>
9: #if defined(PETSC_HAVE_UNISTD_H)
10: #include <unistd.h>
11: #endif
12: #if defined(PETSC_HAVE_SYS_UTSNAME_H)
13: #include <sys/utsname.h>
14: #endif
15: #if defined(PETSC_HAVE_IO_H)
16: #include <io.h>
17: #endif
18: #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H)
19: #include <sys/systeminfo.h>
20: #endif
22: #if defined(PETSC_HAVE__ACCESS) || defined(PETSC_HAVE_ACCESS)
24: static PetscErrorCode PetscTestOwnership(const char fname[], char mode, uid_t fuid, gid_t fgid, int fmode, PetscBool *flg)
25: {
26: int m = R_OK;
30: if (mode == 'r') m = R_OK;
31: else if (mode == 'w') m = W_OK;
32: else if (mode == 'x') m = X_OK;
33: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Mode must be one of r, w, or x");
34: #if defined(PETSC_HAVE_ACCESS)
35: if (!access(fname, m)) {
36: PetscInfo1(NULL,"System call access() succeeded on file %s\n",fname);
37: *flg = PETSC_TRUE;
38: } else {
39: PetscInfo1(NULL,"System call access() failed on file %s\n",fname);
40: *flg = PETSC_FALSE;
41: }
42: #else
43: if (m == X_OK) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP, "Unable to check execute permission for file %s", fname);
44: if (!_access(fname, m)) *flg = PETSC_TRUE;
45: #endif
46: return(0);
47: }
49: #else /* PETSC_HAVE_ACCESS or PETSC_HAVE__ACCESS */
51: static PetscErrorCode PetscTestOwnership(const char fname[], char mode, uid_t fuid, gid_t fgid, int fmode, PetscBool *flg)
52: {
53: uid_t uid;
54: gid_t *gid = NULL;
55: int numGroups;
56: int rbit = S_IROTH;
57: int wbit = S_IWOTH;
58: int ebit = S_IXOTH;
60: #if !defined(PETSC_MISSING_GETGROUPS)
61: int err;
62: #endif
65: /* Get the number of supplementary group IDs */
66: #if !defined(PETSC_MISSING_GETGROUPS)
67: numGroups = getgroups(0, gid); if (numGroups < 0) SETERRQ(PETSC_COMM_SELF,numGroups, "Unable to count supplementary group IDs");
68: PetscMalloc1(numGroups+1, &gid);
69: #else
70: numGroups = 0;
71: #endif
73: /* Get the (effective) user and group of the caller */
74: uid = geteuid();
75: gid[0] = getegid();
77: /* Get supplementary group IDs */
78: #if !defined(PETSC_MISSING_GETGROUPS)
79: err = getgroups(numGroups, gid+1); if (err < 0) SETERRQ(PETSC_COMM_SELF,err, "Unable to obtain supplementary group IDs");
80: #endif
82: /* Test for accessibility */
83: if (fuid == uid) {
84: rbit = S_IRUSR;
85: wbit = S_IWUSR;
86: ebit = S_IXUSR;
87: } else {
88: int g;
90: for (g = 0; g <= numGroups; g++) {
91: if (fgid == gid[g]) {
92: rbit = S_IRGRP;
93: wbit = S_IWGRP;
94: ebit = S_IXGRP;
95: break;
96: }
97: }
98: }
99: PetscFree(gid);
101: if (mode == 'r') {
102: if (fmode & rbit) *flg = PETSC_TRUE;
103: } else if (mode == 'w') {
104: if (fmode & wbit) *flg = PETSC_TRUE;
105: } else if (mode == 'x') {
106: if (fmode & ebit) *flg = PETSC_TRUE;
107: }
108: return(0);
109: }
111: #endif /* PETSC_HAVE_ACCESS */
113: static PetscErrorCode PetscGetFileStat(const char fname[], uid_t *fileUid, gid_t *fileGid, int *fileMode,PetscBool *exists)
114: {
115: struct stat statbuf;
119: *fileMode = 0;
120: *exists = PETSC_FALSE;
121: #if defined(PETSC_HAVE_STAT_NO_CONST)
122: stat((char*) fname, &statbuf);
123: #else
124: stat(fname, &statbuf);
125: #endif
126: if (ierr) {
127: #if defined(EOVERFLOW)
128: if (errno == EOVERFLOW) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"EOVERFLOW in stat(), configure PETSc --with-large-file-io=1 to support files larger than 2GiB");
129: #endif
130: PetscInfo1(NULL,"System call stat() failed on file %s\n",fname);
131: *exists = PETSC_FALSE;
132: } else {
133: PetscInfo1(NULL,"System call stat() succeeded on file %s\n",fname);
134: *exists = PETSC_TRUE;
135: *fileUid = statbuf.st_uid;
136: *fileGid = statbuf.st_gid;
137: *fileMode = statbuf.st_mode;
138: }
139: return(0);
140: }
142: /*@C
143: PetscTestFile - checks for the existence of a file
145: Not Collective
147: Input Parameter:
148: + fname - the filename
149: - mode - either 'r', 'w', 'x' or '\0'
151: Output Parameter:
152: . flg - the file exists and satisfies the mode
154: Level: intermediate
156: Notes: if mode is '\0', no permissions checks are performed
158: .seealso: PetscTestDirectory(), PetscLs()
159: @*/
160: PetscErrorCode PetscTestFile(const char fname[], char mode, PetscBool *flg)
161: {
162: uid_t fuid;
163: gid_t fgid;
164: int fmode;
166: PetscBool exists;
169: *flg = PETSC_FALSE;
170: if (!fname) return(0);
172: PetscGetFileStat(fname, &fuid, &fgid, &fmode, &exists);
173: if (!exists) return(0);
174: /* Except for systems that have this broken stat macros (rare), this is the correct way to check for a regular file */
175: if (!S_ISREG(fmode)) return(0);
176: /* return if asked to check for existence only */
177: if (mode == '\0') { *flg = exists; return(0); }
178: PetscTestOwnership(fname, mode, fuid, fgid, fmode, flg);
179: return(0);
180: }
182: /*@C
183: PetscTestDirectory - checks for the existence of a directory
185: Not Collective
187: Input Parameter:
188: + dirname - the directory name
189: - mode - either 'r', 'w', or 'x'
191: Output Parameter:
192: . flg - the directory exists and satisfies the mode
194: Level: intermediate
196: .seealso: PetscTestFile(), PetscLs()
197: @*/
198: PetscErrorCode PetscTestDirectory(const char dirname[],char mode,PetscBool *flg)
199: {
200: uid_t fuid;
201: gid_t fgid;
202: int fmode;
204: PetscBool exists;
207: *flg = PETSC_FALSE;
208: if (!dirname) return(0);
210: PetscGetFileStat(dirname, &fuid, &fgid, &fmode,&exists);
211: if (!exists) return(0);
212: /* Except for systems that have this broken stat macros (rare), this
213: is the correct way to check for a directory */
214: if (!S_ISDIR(fmode)) return(0);
216: PetscTestOwnership(dirname, mode, fuid, fgid, fmode, flg);
217: return(0);
218: }
220: /*@C
221: PetscLs - produce a listing of the files in a directory
223: Collective
225: Input Parameter:
226: + comm - the MPI communicator
227: . dirname - the directory name
228: - tlen - the length of the buffer found[]
230: Output Parameter:
231: + found - listing of files
232: - flg - the directory exists
234: Level: intermediate
236: .seealso: PetscTestFile(), PetscLs()
237: @*/
238: PetscErrorCode PetscLs(MPI_Comm comm,const char dirname[],char found[],size_t tlen,PetscBool *flg)
239: {
241: size_t len;
242: char *f,program[PETSC_MAX_PATH_LEN];
243: FILE *fp;
246: PetscStrcpy(program,"ls ");
247: PetscStrcat(program,dirname);
248: #if defined(PETSC_HAVE_POPEN)
249: PetscPOpen(comm,NULL,program,"r",&fp);
250: #else
251: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
252: #endif
253: f = fgets(found,tlen,fp);
254: if (f) *flg = PETSC_TRUE;
255: else *flg = PETSC_FALSE;
256: while (f) {
257: PetscStrlen(found,&len);
258: f = fgets(found+len,tlen-len,fp);
259: }
260: if (*flg) {PetscInfo2(NULL,"ls on %s gives \n%s\n",dirname,found);}
261: #if defined(PETSC_HAVE_POPEN)
262: PetscPClose(comm,fp);
263: #else
264: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
265: #endif
266: return(0);
267: }