Actual source code: ex13.c
petsc-3.6.1 2015-08-06
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: PetscStrlen(dir,&dlen);
23: last = dir + dlen - 1;
24: while (last > dir && *last == '/') *last-- = 0; /* drop trailing slashes */
25: while (last > dir && *last != '/') last--; /* seek backward to next slash */
26: if (last > dir) {
27: *last = 0;
28: base = last + 1;
29: } else { /* Current directory */
30: dir[0] = '.';
31: dir[1] = '\0';
32: base = path;
33: }
34: #if defined(PETSC_HAVE_REALPATH)
35: if (!realpath(dir,rpath)) {
36: perror("ex13: realpath");
37: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"realpath()");
38: }
39: #else
40: PetscStrncpy(rpath,dir,sizeof(rpath));
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;
59: int rval;
62: /* dynamically allocate so valgrind and PETSc can check for overflow */
63: PetscMalloc(len,&buf);
64: PetscGetFullPath(path,buf,len);
65: PetscSNPrintf(cmd,sizeof(cmd),"printf %%s %s",path);
66: PetscPOpen(PETSC_COMM_SELF,NULL,cmd,"r",&fp);
67: if (!fgets(spath,sizeof(spath),fp)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in shell command: %s",cmd);
68: PetscPClose(PETSC_COMM_SELF,fp,&rval);
69: RealpathPhonyFile(spath,rpath,len);
70: PetscStrcmp(rpath,buf,&match);
71: if (!match) {
72: PetscPrintf(PETSC_COMM_SELF,"$(realpath %s | head -c %d) %s != %s\n",path,(int)len-1,rpath,buf);
73: }
74: if (used) {PetscStrlen(buf,used);}
75: PetscFree(buf);
76: return(0);
77: }
81: static PetscErrorCode Check(const char *path)
82: {
84: size_t used;
87: CheckLen(path,PETSC_MAX_PATH_LEN,&used);
88: CheckLen(path,used-1,NULL);
89: return(0);
90: }
91: #endif
95: int main(int argc,char **argv)
96: {
97: #if defined(PETSC_HAVE_POPEN)
99: char user[256],buf[512];
100: #endif
102: PetscInitialize(&argc,&argv,(char*)0,help);
103: #if defined(PETSC_HAVE_POPEN)
104: Check("~/file-name");
105: PetscGetUserName(user,256);
106: PetscSNPrintf(buf,sizeof(buf),"~%s/file-name",user);
107: Check(buf);
108: Check("/dev/null");
109: Check("./this-dir");
110: Check("also-this-dir");
111: #endif
112: PetscFinalize();
113: return 0;
114: }