Actual source code: mpiuopen.c
1: #define PETSC_DLL
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: PetscErrorCode PETSC_DLLEXPORT PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp)
43: {
45: PetscMPIInt rank;
46: FILE *fd;
47: char fname[PETSC_MAX_PATH_LEN],tname[PETSC_MAX_PATH_LEN];
50: MPI_Comm_rank(comm,&rank);
51: if (!rank) {
52: PetscTruth isstdout,isstderr;
53: PetscStrcmp(name,"stdout",&isstdout);
54: PetscStrcmp(name,"stderr",&isstderr);
55: if (isstdout || !name) {
56: fd = stdout;
57: } else if (isstderr) {
58: fd = stderr;
59: } else {
60: PetscStrreplace(PETSC_COMM_SELF,name,tname,PETSC_MAX_PATH_LEN);
61: PetscFixFilename(tname,fname);
62: PetscLogInfo((0,"PetscFOpen:Opening file %s\n",fname));
63: fd = fopen(fname,mode);
64: if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Unable to open file %s\n",fname);
65: }
66: } else fd = 0;
67: *fp = fd;
68: return(0);
69: }
73: /*@C
74: PetscFClose - Has the first processor in the communicator close a
75: file; all others do nothing.
77: Collective on MPI_Comm
79: Input Parameters:
80: + comm - the communicator
81: - fd - the file, opened with PetscFOpen()
83: Level: developer
85: Fortran Note:
86: This routine is not supported in Fortran.
88: Concepts: files^closing ASCII
89: Concepts: closing file
91: .seealso: PetscFOpen()
92: @*/
93: PetscErrorCode PETSC_DLLEXPORT PetscFClose(MPI_Comm comm,FILE *fd)
94: {
96: PetscMPIInt rank;
99: MPI_Comm_rank(comm,&rank);
100: if (!rank && fd != stdout && fd != stderr) fclose(fd);
101: return(0);
102: }
104: #if defined(PETSC_HAVE_POPEN)
108: /*@C
109: PetscPClose - Closes (ends) a program on processor zero run with PetscPOpen()
111: Collective on MPI_Comm, but only process 0 runs the command
113: Input Parameters:
114: + comm - MPI communicator, only processor zero runs the program
115: - fp - the file pointer where program input or output may be read or PETSC_NULL if don't care
117: Level: intermediate
119: Notes:
120: Does not work under Windows
122: .seealso: PetscFOpen(), PetscFClose(), PetscPOpen()
124: @*/
125: PetscErrorCode PETSC_DLLEXPORT PetscPClose(MPI_Comm comm,FILE *fd)
126: {
128: PetscMPIInt rank;
131: MPI_Comm_rank(comm,&rank);
132: if (!rank) {
133: char buf[1024];
134: while (fgets(buf,1024,fd)) {;} /* wait till it prints everything */
135: pclose(fd);
136: }
137: return(0);
138: }
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: Use PetscPClose() to close the file pointer when you are finished with it
162: Does not work under Windows
164: The program string may contain ${DISPLAY}, ${HOMEDIRECTORY} or ${WORKINGDIRECTORY}; these
165: will be replaced with relevent values.
167: .seealso: PetscFOpen(), PetscFClose(), PetscPClose()
169: @*/
170: PetscErrorCode PETSC_DLLEXPORT PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp)
171: {
173: PetscMPIInt rank;
174: size_t i,len,cnt;
175: char commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN];
176: FILE *fd;
180: /* all processors have to do the string manipulation because PetscStrreplace() is a collective operation */
181: if (machine && machine[0]) {
182: PetscStrcpy(command,"ssh ");
183: PetscStrcat(command,machine);
184: PetscStrcat(command," \" setenv DISPLAY ${DISPLAY}; ");
185: /*
186: Copy program into command but protect the " with a \ in front of it
187: */
188: PetscStrlen(command,&cnt);
189: PetscStrlen(program,&len);
190: for (i=0; i<len; i++) {
191: if (program[i] == '\"') {
192: command[cnt++] = '\\';
193: }
194: command[cnt++] = program[i];
195: }
196: command[cnt] = 0;
197: PetscStrcat(command,"\"");
198: } else {
199: PetscStrcpy(command,program);
200: }
202: PetscStrreplace(comm,command,commandt,1024);
203:
204: MPI_Comm_rank(comm,&rank);
205: if (!rank) {
206: PetscLogInfo((0,"PetscPOpen:Running command :%s\n",commandt));
207: if (!(fd = popen(commandt,mode))) {
208: SETERRQ1(PETSC_ERR_LIB,"Cannot run command %s",commandt);
209: }
210: if (fp) *fp = fd;
211: }
212: return(0);
213: }
215: #endif