Actual source code: mpiuopen.c
1: /*
2: Some PETSc utilites routines to add simple parallel IO capability
3: */
4: #include petsc.h
5: #include petscsys.h
6: #include <stdarg.h>
7: #if defined(PETSC_HAVE_STDLIB_H)
8: #include <stdlib.h>
9: #endif
10: #include "petscfix.h"
14: /*@C
15: PetscFOpen - Has the first process in the communicator open a file;
16: all others do nothing.
18: Collective on MPI_Comm
20: Input Parameters:
21: + comm - the communicator
22: . name - the filename
23: - mode - the mode for fopen(), usually "w"
25: Output Parameter:
26: . fp - the file pointer
28: Level: developer
30: Notes:
31: PETSC_NULL (0), "stderr" or "stdout" may be passed in as the filename
32:
33: Fortran Note:
34: This routine is not supported in Fortran.
36: Concepts: opening ASCII file
37: Concepts: files^opening ASCII
39: .seealso: PetscFClose()
40: @*/
41: PetscErrorCode PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp)
42: {
44: int rank;
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(PETSC_ERR_FILE_OPEN,"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: PetscErrorCode PetscFClose(MPI_Comm comm,FILE *fd)
93: {
95: int rank;
98: MPI_Comm_rank(comm,&rank);
99: if (!rank && fd != stdout && fd != stderr) fclose(fd);
100: return(0);
101: }
105: /*@C
106: PetscPClose - Closes (ends) a program on processor zero run with PetscPOpen()
108: Collective on MPI_Comm, but only process 0 runs the command
110: Input Parameters:
111: + comm - MPI communicator, only processor zero runs the program
112: - fp - the file pointer where program input or output may be read or PETSC_NULL if don't care
114: Level: intermediate
116: Notes:
117: Does not work under Windows
119: .seealso: PetscFOpen(), PetscFClose(), PetscPOpen()
121: @*/
122: PetscErrorCode PetscPClose(MPI_Comm comm,FILE *fd)
123: {
125: int rank;
128: MPI_Comm_rank(comm,&rank);
129: if (!rank) {
130: char buf[1024];
131: while (fgets(buf,1024,fd)) {;} /* wait till it prints everything */
132: #if defined(PETSC_HAVE_POPEN)
133: pclose(fd);
134: #else
135: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run programs, no popen() on this computing system");
136: #endif
137: }
138: return(0);
139: }
143: /*@C
144: PetscPOpen - Runs a program on processor zero and sends either its input or output to
145: a file.
147: Collective on MPI_Comm, but only process 0 runs the command
149: Input Parameters:
150: + comm - MPI communicator, only processor zero runs the program
151: . machine - machine to run command on or PETSC_NULL, or string with 0 in first location
152: . program - name of program to run
153: - mode - either r or w
155: Output Parameter:
156: . fp - the file pointer where program input or output may be read or PETSC_NULL if don't care
158: Level: intermediate
160: Notes:
161: Does not work under Windows
163: The program string may contain ${DISPLAY}, ${HOMEDIRECTORY} or ${WORKINGDIRECTORY}; these
164: will be replaced with relevent values.
166: .seealso: PetscFOpen(), PetscFClose(), PetscPClose()
168: @*/
169: PetscErrorCode PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp)
170: {
172: int rank;
173: size_t i,len,cnt;
174: char commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN];
175: #if defined(PETSC_HAVE_POPEN)
176: FILE *fd;
177: #endif
181: /* all processors have to do the string manipulation because PetscStrreplace() is a collective operation */
182: if (machine && machine[0]) {
183: PetscStrcpy(command,"rsh ");
184: PetscStrcat(command,machine);
185: PetscStrcat(command," \" setenv DISPLAY ${DISPLAY}; ");
186: /*
187: Copy program into command but protect the " with a \ in front of it
188: */
189: PetscStrlen(command,&cnt);
190: PetscStrlen(program,&len);
191: for (i=0; i<len; i++) {
192: if (program[i] == '\"') {
193: command[cnt++] = '\\';
194: }
195: command[cnt++] = program[i];
196: }
197: command[cnt] = 0;
198: PetscStrcat(command,"\"");
199: } else {
200: PetscStrcpy(command,program);
201: }
203: PetscStrreplace(comm,command,commandt,1024);
204:
205: MPI_Comm_rank(comm,&rank);
206: if (!rank) {
207: PetscLogInfo(0,"Running command :%s\n",commandt);
209: #if defined(PETSC_HAVE_POPEN)
210: if (!(fd = popen(commandt,mode))) {
211: SETERRQ1(PETSC_ERR_LIB,"Cannot run command %s",commandt);
212: }
213: if (fp) *fp = fd;
214: #else
215: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run programs, no popen() on this system");
216: #endif
217: }
218: return(0);
219: }