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