Actual source code: mpiuopen.c

  1: /*$Id: mpiuopen.c,v 1.38 2001/03/23 23:20:30 balay Exp $*/
  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: int PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp)
 43: {
 44:   int  rank,ierr;
 45:   FILE *fd;
 46:   char fname[PETSC_MAX_PATH_LEN],tname[PETSC_MAX_PATH_LEN];

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

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

 76:     Collective on MPI_Comm

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

 82:    Level: developer

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

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

 90: .seealso: PetscFOpen()
 91: @*/
 92: int PetscFClose(MPI_Comm comm,FILE *fd)
 93: {
 94:   int  rank,ierr;

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

104: int PetscPClose(MPI_Comm comm,FILE *fd)
105: {
106:   int  rank,ierr;

109:   MPI_Comm_rank(comm,&rank);
110:   if (!rank) {
111:     char buf[1024];
112:     while (fgets(buf,1024,fd)) {;} /* wait till it prints everything */
113: #if defined(PETSC_HAVE_POPEN)
114:     pclose(fd);
115: #else
116:     SETERRQ(1,"Cannot run programs, no popen()");
117: #endif
118:   }
119:   return(0);
120: }

124: /*@C
125:       PetscPOpen - Runs a program on processor zero and sends either its input or output to 
126:           a file.

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

130:    Input Parameters:
131: +   comm - MPI communicator, only processor zero runs the program
132: .   machine - machine to run command on or PETSC_NULL, or string with 0 in first location
133: .   program - name of program to run
134: -   mode - either r or w

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

139:    Level: intermediate

141:    Notes:
142:        Does not work under Windows

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

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

149: @*/
150: int PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp)
151: {
152:   int  ierr,rank,i,len,cnt;
153:   char commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN];
154: #if defined(PETSC_HAVE_POPEN)
155:   FILE *fd;
156: #endif


160:   /* all processors have to do the string manipulation because PetscStrreplace() is a collective operation */
161:   if (machine && machine[0]) {
162:     PetscStrcpy(command,"rsh ");
163:     PetscStrcat(command,machine);
164:     PetscStrcat(command," \" setenv DISPLAY ${DISPLAY}; ");
165:     /*
166:         Copy program into command but protect the " with a \ in front of it 
167:     */
168:     PetscStrlen(command,&cnt);
169:     PetscStrlen(program,&len);
170:     for (i=0; i<len; i++) {
171:       if (program[i] == '\"') {
172:         command[cnt++] = '\\';
173:       }
174:       command[cnt++] = program[i];
175:     }
176:     command[cnt] = 0;
177:     PetscStrcat(command,"\"");
178:   } else {
179:     PetscStrcpy(command,program);
180:   }

182:   PetscStrreplace(comm,command,commandt,1024);
183: 
184:   MPI_Comm_rank(comm,&rank);
185:   if (!rank) {
186:     PetscLogInfo(0,"Running command :%s\n",commandt);

188: #if defined(PETSC_HAVE_POPEN)
189:     if (!(fd = popen(commandt,mode))) {
190:        SETERRQ1(1,"Cannot run command %s",commandt);
191:     }
192:     if (fp) *fp = fd;
193: #else 
194:     SETERRQ(1,"Cannot run programs, no popen()");
195: #endif
196:   }
197:   return(0);
198: }