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: /*@C
 14:     PetscFOpen - Has the first process in the communicator open a file;
 15:     all others do nothing.

 17:     Collective on MPI_Comm

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

 24:     Output Parameter:
 25: .   fp - the file pointer

 27:     Level: developer

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

 35:     Concepts: opening ASCII file
 36:     Concepts: files^opening ASCII

 38: .seealso: PetscFClose()
 39: @*/
 40: int PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp)
 41: {
 42:   int  rank,ierr;
 43:   FILE *fd;
 44:   char fname[256],tname[256];

 47:   MPI_Comm_rank(comm,&rank);
 48:   if (!rank) {
 49:     PetscTruth isstdout,isstderr;
 50:     PetscStrcmp(name,"stdout",&isstdout);
 51:     PetscStrcmp(name,"stderr",&isstderr);
 52:     if (isstdout || !name) {
 53:       fd = stdout;
 54:     } else if (isstderr) {
 55:       fd = stderr;
 56:     } else {
 57:       PetscStrreplace(PETSC_COMM_SELF,name,tname,256);
 58:       PetscFixFilename(tname,fname);
 59:       PetscLogInfo(0,"Opening file %sn",fname);
 60:       fd   = fopen(fname,mode);
 61:     }
 62:   } else fd = 0;
 63:   *fp = fd;
 64:   return(0);
 65: }

 67: /*@C
 68:     PetscFClose - Has the first processor in the communicator close a 
 69:     file; all others do nothing.

 71:     Collective on MPI_Comm

 73:     Input Parameters:
 74: +   comm - the communicator
 75: -   fd - the file, opened with PetscFOpen()

 77:    Level: developer

 79:     Fortran Note:
 80:     This routine is not supported in Fortran.

 82:     Concepts: files^closing ASCII
 83:     Concepts: closing file

 85: .seealso: PetscFOpen()
 86: @*/
 87: int PetscFClose(MPI_Comm comm,FILE *fd)
 88: {
 89:   int  rank,ierr;

 92:   MPI_Comm_rank(comm,&rank);
 93:   if (!rank && fd != stdout && fd != stderr) fclose(fd);
 94:   return(0);
 95: }

 97: int PetscPClose(MPI_Comm comm,FILE *fd)
 98: {
 99:   int  rank,ierr;

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

115: /*@C
116:       PetscPOpen - Runs a program on processor zero and sends either its input or output to 
117:           a file.

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

121:    Input Parameters:
122: +   comm - MPI communicator, only processor zero runs the program
123: .   machine - machine to run command on or PETSC_NULL, or string with 0 in first location
124: .   program - name of program to run
125: -   mode - either r or w

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

130:    Level: intermediate

132:    Notes:
133:        Does not work under Windows

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

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

140: @*/
141: int PetscPOpen(MPI_Comm comm,char *machine,char *program,const char mode[],FILE **fp)
142: {
143:   int  ierr,rank,i,len,cnt;
144:   char commandt[1024],command[1024];
145: #if defined(PETSC_HAVE_POPEN)
146:   FILE *fd;
147: #endif


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

173:   PetscStrreplace(comm,command,commandt,1024);
174: 
175:   MPI_Comm_rank(comm,&rank);
176:   if (!rank) {
177:     PetscLogInfo(0,"Running command :%sn",commandt);

179: #if defined(PETSC_HAVE_POPEN)
180:     if (!(fd = popen(commandt,mode))) {
181:        SETERRQ1(1,"Cannot run command %s",commandt);
182:     }
183:     if (fp) *fp = fd;
184: #else 
185:     SETERRQ(1,"Cannot run programs, no popen()");
186: #endif
187:   }
188:   return(0);
189: }