Actual source code: ex13.c

petsc-3.6.4 2016-04-12
Report Typos and Errors
  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: }