Actual source code: ex13.c

petsc-3.4.3 2013-10-15
  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: }