Actual source code: ex13.c

petsc-dev 2014-02-02
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:   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: }