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