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(), PetscSynchronizedFGets(), PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
41: PetscFPrintf()
42: @*/
43: PetscErrorCode PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp)
44: {
46: PetscMPIInt rank;
47: FILE *fd;
48: char fname[PETSC_MAX_PATH_LEN],tname[PETSC_MAX_PATH_LEN];
51: MPI_Comm_rank(comm,&rank);
52: if (!rank) {
53: PetscTruth isstdout,isstderr;
54: PetscStrcmp(name,"stdout",&isstdout);
55: PetscStrcmp(name,"stderr",&isstderr);
56: if (isstdout || !name) {
57: fd = PETSC_STDOUT;
58: } else if (isstderr) {
59: fd = PETSC_STDERR;
60: } else {
61: PetscStrreplace(PETSC_COMM_SELF,name,tname,PETSC_MAX_PATH_LEN);
62: PetscFixFilename(tname,fname);
63: PetscInfo1(0,"Opening file %s\n",fname);
64: fd = fopen(fname,mode);
65: if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Unable to open file %s\n",fname);
66: }
67: } else fd = 0;
68: *fp = fd;
69: return(0);
70: }
74: /*@
75: PetscFClose - Has the first processor in the communicator close a
76: file; all others do nothing.
78: Collective on MPI_Comm
80: Input Parameters:
81: + comm - the communicator
82: - fd - the file, opened with PetscFOpen()
84: Level: developer
86: Fortran Note:
87: This routine is not supported in Fortran.
89: Concepts: files^closing ASCII
90: Concepts: closing file
92: .seealso: PetscFOpen()
93: @*/
94: PetscErrorCode PetscFClose(MPI_Comm comm,FILE *fd)
95: {
97: PetscMPIInt rank;
98: int err;
101: MPI_Comm_rank(comm,&rank);
102: if (!rank && fd != PETSC_STDOUT && fd != PETSC_STDERR) {
103: err = fclose(fd);
104: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
105: }
106: return(0);
107: }
109: #if defined(PETSC_HAVE_POPEN)
113: /*@C
114: PetscPClose - Closes (ends) a program on processor zero run with PetscPOpen()
116: Collective on MPI_Comm, but only process 0 runs the command
118: Input Parameters:
119: + comm - MPI communicator, only processor zero runs the program
120: - fp - the file pointer where program input or output may be read or PETSC_NULL if don't care
122: Level: intermediate
124: Notes:
125: Does not work under Windows
127: .seealso: PetscFOpen(), PetscFClose(), PetscPOpen()
129: @*/
130: PetscErrorCode PetscPClose(MPI_Comm comm,FILE *fd)
131: {
133: PetscMPIInt rank;
134: int err;
137: MPI_Comm_rank(comm,&rank);
138: if (!rank) {
139: char buf[1024];
140: while (fgets(buf,1024,fd)) {;} /* wait till it prints everything */
141: err = pclose(fd);
142: if (err) SETERRQ1(PETSC_ERR_SYS,"pclose() failed on process %D",err);
143: }
144: return(0);
145: }
150: /*@C
151: PetscPOpen - Runs a program on processor zero and sends either its input or output to
152: a file.
154: Collective on MPI_Comm, but only process 0 runs the command
156: Input Parameters:
157: + comm - MPI communicator, only processor zero runs the program
158: . machine - machine to run command on or PETSC_NULL, or string with 0 in first location
159: . program - name of program to run
160: - mode - either r or w
162: Output Parameter:
163: . fp - the file pointer where program input or output may be read or PETSC_NULL if don't care
165: Level: intermediate
167: Notes:
168: Use PetscPClose() to close the file pointer when you are finished with it
169: Does not work under Windows
171: The program string may contain ${DISPLAY}, ${HOMEDIRECTORY} or ${WORKINGDIRECTORY}; these
172: will be replaced with relevent values.
174: .seealso: PetscFOpen(), PetscFClose(), PetscPClose()
176: @*/
177: PetscErrorCode PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp)
178: {
180: PetscMPIInt rank;
181: size_t i,len,cnt;
182: char commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN];
183: FILE *fd;
187: /* all processors have to do the string manipulation because PetscStrreplace() is a collective operation */
188: if (machine && machine[0]) {
189: PetscStrcpy(command,"ssh ");
190: PetscStrcat(command,machine);
191: PetscStrcat(command," \" setenv DISPLAY ${DISPLAY}; ");
192: /*
193: Copy program into command but protect the " with a \ in front of it
194: */
195: PetscStrlen(command,&cnt);
196: PetscStrlen(program,&len);
197: for (i=0; i<len; i++) {
198: if (program[i] == '\"') {
199: command[cnt++] = '\\';
200: }
201: command[cnt++] = program[i];
202: }
203: command[cnt] = 0;
204: PetscStrcat(command,"\"");
205: } else {
206: PetscStrcpy(command,program);
207: }
209: PetscStrreplace(comm,command,commandt,1024);
210:
211: MPI_Comm_rank(comm,&rank);
212: if (!rank) {
213: PetscInfo1(0,"Running command :%s\n",commandt);
214: if (!(fd = popen(commandt,mode))) {
215: SETERRQ1(PETSC_ERR_LIB,"Cannot run command %s",commandt);
216: }
217: if (fp) *fp = fd;
218: }
219: return(0);
220: }
222: #endif