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" 12 13 #undef __FUNCT__ 14 #define __FUNCT__ "PetscFOpen" 15 /*@C 16 PetscFOpen - Has the first process in the communicator open a file; 17 all others do nothing. 18 19 Collective on MPI_Comm 20 21 Input Parameters: 22 + comm - the communicator 23 . name - the filename 24 - mode - the mode for fopen(), usually "w" 25 26 Output Parameter: 27 . fp - the file pointer 28 29 Level: developer 30 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. 36 37 Concepts: opening ASCII file 38 Concepts: files^opening ASCII 39 40 .seealso: PetscFClose() 41 @*/ 42 PetscErrorCode PETSC_DLLEXPORT PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp) 43 { 44 PetscErrorCode ierr; 45 PetscMPIInt rank; 46 FILE *fd; 47 char fname[PETSC_MAX_PATH_LEN],tname[PETSC_MAX_PATH_LEN]; 48 49 PetscFunctionBegin; 50 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 51 if (!rank) { 52 PetscTruth isstdout,isstderr; 53 ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr); 54 ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr); 55 if (isstdout || !name) { 56 fd = stdout; 57 } else if (isstderr) { 58 fd = stderr; 59 } else { 60 ierr = PetscStrreplace(PETSC_COMM_SELF,name,tname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 61 ierr = PetscFixFilename(tname,fname);CHKERRQ(ierr); 62 ierr = PetscVerboseInfo((0,"PetscFOpen:Opening file %s\n",fname));CHKERRQ(ierr); 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 PetscFunctionReturn(0); 69 } 70 71 #undef __FUNCT__ 72 #define __FUNCT__ "PetscFClose" 73 /*@ 74 PetscFClose - Has the first processor in the communicator close a 75 file; all others do nothing. 76 77 Collective on MPI_Comm 78 79 Input Parameters: 80 + comm - the communicator 81 - fd - the file, opened with PetscFOpen() 82 83 Level: developer 84 85 Fortran Note: 86 This routine is not supported in Fortran. 87 88 Concepts: files^closing ASCII 89 Concepts: closing file 90 91 .seealso: PetscFOpen() 92 @*/ 93 PetscErrorCode PETSC_DLLEXPORT PetscFClose(MPI_Comm comm,FILE *fd) 94 { 95 PetscErrorCode ierr; 96 PetscMPIInt rank; 97 98 PetscFunctionBegin; 99 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 100 if (!rank && fd != stdout && fd != stderr) fclose(fd); 101 PetscFunctionReturn(0); 102 } 103 104 #if defined(PETSC_HAVE_POPEN) 105 106 #undef __FUNCT__ 107 #define __FUNCT__ "PetscPClose" 108 /*@C 109 PetscPClose - Closes (ends) a program on processor zero run with PetscPOpen() 110 111 Collective on MPI_Comm, but only process 0 runs the command 112 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 116 117 Level: intermediate 118 119 Notes: 120 Does not work under Windows 121 122 .seealso: PetscFOpen(), PetscFClose(), PetscPOpen() 123 124 @*/ 125 PetscErrorCode PETSC_DLLEXPORT PetscPClose(MPI_Comm comm,FILE *fd) 126 { 127 PetscErrorCode ierr; 128 PetscMPIInt rank; 129 130 PetscFunctionBegin; 131 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 132 if (!rank) { 133 char buf[1024]; 134 while (fgets(buf,1024,fd)) {;} /* wait till it prints everything */ 135 pclose(fd); 136 } 137 PetscFunctionReturn(0); 138 } 139 140 141 #undef __FUNCT__ 142 #define __FUNCT__ "PetscPOpen" 143 /*@C 144 PetscPOpen - Runs a program on processor zero and sends either its input or output to 145 a file. 146 147 Collective on MPI_Comm, but only process 0 runs the command 148 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 154 155 Output Parameter: 156 . fp - the file pointer where program input or output may be read or PETSC_NULL if don't care 157 158 Level: intermediate 159 160 Notes: 161 Use PetscPClose() to close the file pointer when you are finished with it 162 Does not work under Windows 163 164 The program string may contain ${DISPLAY}, ${HOMEDIRECTORY} or ${WORKINGDIRECTORY}; these 165 will be replaced with relevent values. 166 167 .seealso: PetscFOpen(), PetscFClose(), PetscPClose() 168 169 @*/ 170 PetscErrorCode PETSC_DLLEXPORT PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp) 171 { 172 PetscErrorCode ierr; 173 PetscMPIInt rank; 174 size_t i,len,cnt; 175 char commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN]; 176 FILE *fd; 177 178 PetscFunctionBegin; 179 180 /* all processors have to do the string manipulation because PetscStrreplace() is a collective operation */ 181 if (machine && machine[0]) { 182 ierr = PetscStrcpy(command,"ssh ");CHKERRQ(ierr); 183 ierr = PetscStrcat(command,machine);CHKERRQ(ierr); 184 ierr = PetscStrcat(command," \" setenv DISPLAY ${DISPLAY}; ");CHKERRQ(ierr); 185 /* 186 Copy program into command but protect the " with a \ in front of it 187 */ 188 ierr = PetscStrlen(command,&cnt);CHKERRQ(ierr); 189 ierr = PetscStrlen(program,&len);CHKERRQ(ierr); 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 ierr = PetscStrcat(command,"\"");CHKERRQ(ierr); 198 } else { 199 ierr = PetscStrcpy(command,program);CHKERRQ(ierr); 200 } 201 202 ierr = PetscStrreplace(comm,command,commandt,1024);CHKERRQ(ierr); 203 204 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 205 if (!rank) { 206 ierr = PetscVerboseInfo((0,"PetscPOpen:Running command :%s\n",commandt));CHKERRQ(ierr); 207 if (!(fd = popen(commandt,mode))) { 208 SETERRQ1(PETSC_ERR_LIB,"Cannot run command %s",commandt); 209 } 210 if (fp) *fp = fd; 211 } 212 PetscFunctionReturn(0); 213 } 214 215 #endif 216