Actual source code: ex13.c
petsc-3.4.5 2014-06-29
1: static char help[] = "Demonstrates PETSc path routines.\n";
3: #include <petscsys.h>
7: /* realpath(3) requires the path to exist, but GNU coreutils' realpath(1) only needs the containing directory to exist.
8: * So split path into (dir, base) and only use realpath(3) on dir.
9: *
10: */
11: static PetscErrorCode RealpathPhonyFile(const char *path,char *buf,size_t len)
12: {
13: char dir[PETSC_MAX_PATH_LEN],rpath[PETSC_MAX_PATH_LEN],*last;
14: const char *base;
15: size_t dlen;
19: PetscStrncpy(dir,path,sizeof dir);
20: dir[sizeof dir-1] = 0;
21: PetscStrlen(dir,&dlen);
22: last = dir + dlen - 1;
23: while (last > dir && *last == '/') *last-- = 0; /* drop trailing slashes */
24: while (last > dir && *last != '/') last--; /* seek backward to next slash */
25: if (last > dir) {
26: *last = 0;
27: base = last + 1;
28: } else { /* Current directory */
29: dir[0] = '.';
30: dir[1] = '\0';
31: base = path;
32: }
33: #if defined(PETSC_HAVE_REALPATH)
34: if (!realpath(dir,rpath)) {
35: perror("ex13: realpath");
36: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"realpath()");
37: }
38: #else
39: PetscStrncpy(rpath,dir,sizeof rpath);
40: rpath[sizeof rpath-1] = 0;
41: #endif
42: PetscStrlen(rpath,&dlen);
43: PetscMemcpy(buf,rpath,PetscMin(dlen,len-1));
44: buf[PetscMin(dlen,len-1)] = '/';
45: PetscStrncpy(buf+PetscMin(dlen+1,len-1),base,PetscMax(len-dlen-1,0));
46: buf[len-1] = 0;
47: return(0);
48: }
53: static PetscErrorCode CheckLen(const char *path,size_t len,size_t *used)
54: {
55: char *buf,cmd[4096],spath[PETSC_MAX_PATH_LEN],rpath[PETSC_MAX_PATH_LEN];
57: FILE *fp;
58: PetscBool match;
61: /* dynamically allocate so valgrind and PETSc can check for overflow */
62: PetscMalloc(len,&buf);
63: PetscGetFullPath(path,buf,len);
64: PetscSNPrintf(cmd,sizeof cmd,"printf %%s %s",path);
65: PetscPOpen(PETSC_COMM_SELF,NULL,cmd,"r",&fp);
66: if (!fgets(spath,sizeof spath,fp)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in shell command: %s",cmd);
67: PetscPClose(PETSC_COMM_SELF,fp,NULL);
68: RealpathPhonyFile(spath,rpath,len);
69: PetscStrcmp(rpath,buf,&match);
70: if (!match) {
71: PetscPrintf(PETSC_COMM_SELF,"$(realpath %s | head -c %d) %s != %s\n",path,(int)len-1,rpath,buf);
72: }
73: if (used) {PetscStrlen(buf,used);}
74: PetscFree(buf);
75: return(0);
76: }
80: static PetscErrorCode Check(const char *path)
81: {
83: size_t used;
86: CheckLen(path,PETSC_MAX_PATH_LEN,&used);
87: CheckLen(path,used-1,NULL);
88: return(0);
89: }
93: int main(int argc,char **argv)
94: {
96: char user[256],buf[512];
98: PetscInitialize(&argc,&argv,(char*)0,help);
99: Check("~/file-name");
100: PetscGetUserName(user,256);
101: PetscSNPrintf(buf,sizeof buf,"~%s/file-name",user);
102: Check(buf);
103: Check("/dev/null");
104: Check("./this-dir");
105: Check("also-this-dir");
106: PetscFinalize();
107: return 0;
108: }