Actual source code: mpiuopen.c

      1: #define PETSC_DLL
      2: /*
      3:       Some PETSc utilites routines to add simple parallel IO capability
      4: */
     5:  #include petsc.h
     6:  #include petscsys.h
      7: #include <stdarg.h>
      8: #if defined(PETSC_HAVE_STDLIB_H)
      9: #include <stdlib.h>
     10: #endif
     11: #include "petscfix.h"

     15: /*@C
     16:     PetscFOpen - Has the first process in the communicator open a file;
     17:     all others do nothing.

     19:     Collective on MPI_Comm

     21:     Input Parameters:
     22: +   comm - the communicator
     23: .   name - the filename
     24: -   mode - the mode for fopen(), usually "w"

     26:     Output Parameter:
     27: .   fp - the file pointer

     29:     Level: developer

     31:     Notes:
     32:        PETSC_NULL (0), "stderr" or "stdout" may be passed in as the filename
     33:
     34:     Fortran Note:
     35:     This routine is not supported in Fortran.

     37:     Concepts: opening ASCII file
     38:     Concepts: files^opening ASCII

     40: .seealso: PetscFClose()
     41: @*/
     42: PetscErrorCode PETSC_DLLEXPORT PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp)
     43: {
     45:   PetscMPIInt    rank;
     46:   FILE           *fd;
     47:   char           fname[PETSC_MAX_PATH_LEN],tname[PETSC_MAX_PATH_LEN];

     50:   MPI_Comm_rank(comm,&rank);
     51:   if (!rank) {
     52:     PetscTruth isstdout,isstderr;
     53:     PetscStrcmp(name,"stdout",&isstdout);
     54:     PetscStrcmp(name,"stderr",&isstderr);
     55:     if (isstdout || !name) {
     56:       fd = stdout;
     57:     } else if (isstderr) {
     58:       fd = stderr;
     59:     } else {
     60:       PetscStrreplace(PETSC_COMM_SELF,name,tname,PETSC_MAX_PATH_LEN);
     61:       PetscFixFilename(tname,fname);
     62:       PetscLogInfo((0,"PetscFOpen:Opening file %s\n",fname));
     63:       fd   = fopen(fname,mode);
     64:       if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Unable to open file %s\n",fname);
     65:     }
     66:   } else fd = 0;
     67:   *fp = fd;
     68:   return(0);
     69: }

     73: /*@C
     74:     PetscFClose - Has the first processor in the communicator close a
     75:     file; all others do nothing.

     77:     Collective on MPI_Comm

     79:     Input Parameters:
     80: +   comm - the communicator
     81: -   fd - the file, opened with PetscFOpen()

     83:    Level: developer

     85:     Fortran Note:
     86:     This routine is not supported in Fortran.

     88:     Concepts: files^closing ASCII
     89:     Concepts: closing file

     91: .seealso: PetscFOpen()
     92: @*/
     93: PetscErrorCode PETSC_DLLEXPORT PetscFClose(MPI_Comm comm,FILE *fd)
     94: {
     96:   PetscMPIInt    rank;

     99:   MPI_Comm_rank(comm,&rank);
    100:   if (!rank && fd != stdout && fd != stderr) fclose(fd);
    101:   return(0);
    102: }

    104: #if defined(PETSC_HAVE_POPEN)

    108: /*@C
    109:       PetscPClose - Closes (ends) a program on processor zero run with PetscPOpen()

    111:      Collective on MPI_Comm, but only process 0 runs the command

    113:    Input Parameters:
    114: +   comm - MPI communicator, only processor zero runs the program
    115: -   fp - the file pointer where program input or output may be read or PETSC_NULL if don't care

    117:    Level: intermediate

    119:    Notes:
    120:        Does not work under Windows

    122: .seealso: PetscFOpen(), PetscFClose(), PetscPOpen()

    124: @*/
    125: PetscErrorCode PETSC_DLLEXPORT PetscPClose(MPI_Comm comm,FILE *fd)
    126: {
    128:   PetscMPIInt    rank;

    131:   MPI_Comm_rank(comm,&rank);
    132:   if (!rank) {
    133:     char buf[1024];
    134:     while (fgets(buf,1024,fd)) {;} /* wait till it prints everything */
    135:     pclose(fd);
    136:   }
    137:   return(0);
    138: }

    143: /*@C
    144:       PetscPOpen - Runs a program on processor zero and sends either its input or output to
    145:           a file.

    147:      Collective on MPI_Comm, but only process 0 runs the command

    149:    Input Parameters:
    150: +   comm - MPI communicator, only processor zero runs the program
    151: .   machine - machine to run command on or PETSC_NULL, or string with 0 in first location
    152: .   program - name of program to run
    153: -   mode - either r or w

    155:    Output Parameter:
    156: .   fp - the file pointer where program input or output may be read or PETSC_NULL if don't care

    158:    Level: intermediate

    160:    Notes:
    161:        Use PetscPClose() to close the file pointer when you are finished with it
    162:        Does not work under Windows

    164:        The program string may contain ${DISPLAY}, ${HOMEDIRECTORY} or ${WORKINGDIRECTORY}; these
    165:     will be replaced with relevent values.

    167: .seealso: PetscFOpen(), PetscFClose(), PetscPClose()

    169: @*/
    170: PetscErrorCode PETSC_DLLEXPORT PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp)
    171: {
    173:   PetscMPIInt    rank;
    174:   size_t         i,len,cnt;
    175:   char           commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN];
    176:   FILE           *fd;

    180:   /* all processors have to do the string manipulation because PetscStrreplace() is a collective operation */
    181:   if (machine && machine[0]) {
    182:     PetscStrcpy(command,"ssh ");
    183:     PetscStrcat(command,machine);
    184:     PetscStrcat(command," \" setenv DISPLAY ${DISPLAY}; ");
    185:     /*
    186:         Copy program into command but protect the " with a \ in front of it
    187:     */
    188:     PetscStrlen(command,&cnt);
    189:     PetscStrlen(program,&len);
    190:     for (i=0; i<len; i++) {
    191:       if (program[i] == '\"') {
    192:         command[cnt++] = '\\';
    193:       }
    194:       command[cnt++] = program[i];
    195:     }
    196:     command[cnt] = 0;
    197:     PetscStrcat(command,"\"");
    198:   } else {
    199:     PetscStrcpy(command,program);
    200:   }

    202:   PetscStrreplace(comm,command,commandt,1024);
    203:
    204:   MPI_Comm_rank(comm,&rank);
    205:   if (!rank) {
    206:     PetscLogInfo((0,"PetscPOpen:Running command :%s\n",commandt));
    207:     if (!(fd = popen(commandt,mode))) {
    208:        SETERRQ1(PETSC_ERR_LIB,"Cannot run command %s",commandt);
    209:     }
    210:     if (fp) *fp = fd;
    211:   }
    212:   return(0);
    213: }

    215: #endif