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(), PetscSynchronizedFGets(), PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
 41:           PetscFPrintf()
 42: @*/
 43: PetscErrorCode  PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp)
 44: {
 46:   PetscMPIInt    rank;
 47:   FILE           *fd;
 48:   char           fname[PETSC_MAX_PATH_LEN],tname[PETSC_MAX_PATH_LEN];

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

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

 78:     Collective on MPI_Comm

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

 84:    Level: developer

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

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

 92: .seealso: PetscFOpen()
 93: @*/
 94: PetscErrorCode  PetscFClose(MPI_Comm comm,FILE *fd)
 95: {
 97:   PetscMPIInt    rank;
 98:   int            err;

101:   MPI_Comm_rank(comm,&rank);
102:   if (!rank && fd != PETSC_STDOUT && fd != PETSC_STDERR) {
103:     err = fclose(fd);
104:     if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
105:   }
106:   return(0);
107: }

109: #if defined(PETSC_HAVE_POPEN)

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

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

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

122:    Level: intermediate

124:    Notes:
125:        Does not work under Windows

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

129: @*/
130: PetscErrorCode  PetscPClose(MPI_Comm comm,FILE *fd)
131: {
133:   PetscMPIInt    rank;
134:   int            err;

137:   MPI_Comm_rank(comm,&rank);
138:   if (!rank) {
139:     char buf[1024];
140:     while (fgets(buf,1024,fd)) {;} /* wait till it prints everything */
141:     err = pclose(fd);
142:     if (err) SETERRQ1(PETSC_ERR_SYS,"pclose() failed on process %D",err);
143:   }
144:   return(0);
145: }


150: /*@C
151:       PetscPOpen - Runs a program on processor zero and sends either its input or output to 
152:           a file.

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

156:    Input Parameters:
157: +   comm - MPI communicator, only processor zero runs the program
158: .   machine - machine to run command on or PETSC_NULL, or string with 0 in first location
159: .   program - name of program to run
160: -   mode - either r or w

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

165:    Level: intermediate

167:    Notes:
168:        Use PetscPClose() to close the file pointer when you are finished with it
169:        Does not work under Windows

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

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

176: @*/
177: PetscErrorCode  PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp)
178: {
180:   PetscMPIInt    rank;
181:   size_t         i,len,cnt;
182:   char           commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN];
183:   FILE           *fd;


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

209:   PetscStrreplace(comm,command,commandt,1024);
210: 
211:   MPI_Comm_rank(comm,&rank);
212:   if (!rank) {
213:     PetscInfo1(0,"Running command :%s\n",commandt);
214:     if (!(fd = popen(commandt,mode))) {
215:        SETERRQ1(PETSC_ERR_LIB,"Cannot run command %s",commandt);
216:     }
217:     if (fp) *fp = fd;
218:   }
219:   return(0);
220: }

222: #endif