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"

 13: #undef __FUNCT__  
 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 %sn",fname);
 62:       fd   = fopen(fname,mode);
 63:     }
 64:   } else fd = 0;
 65:   *fp = fd;
 66:   return(0);
 67: }

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

 75:     Collective on MPI_Comm

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

 81:    Level: developer

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

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

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

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

101: #undef __FUNCT__  
103: int PetscPClose(MPI_Comm comm,FILE *fd)
104: {
105:   int  rank,ierr;

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

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

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

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

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

138:    Level: intermediate

140:    Notes:
141:        Does not work under Windows

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

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

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


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

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

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