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: }