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(), PetscSynchronizedFGets(), PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 41 PetscFPrintf() 42 @*/ 43 PetscErrorCode PETSC_DLLEXPORT PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp) 44 { 45 PetscErrorCode ierr; 46 PetscMPIInt rank; 47 FILE *fd; 48 char fname[PETSC_MAX_PATH_LEN],tname[PETSC_MAX_PATH_LEN]; 49 50 PetscFunctionBegin; 51 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 52 if (!rank) { 53 PetscTruth isstdout,isstderr; 54 ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr); 55 ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr); 56 if (isstdout || !name) { 57 fd = PETSC_STDOUT; 58 } else if (isstderr) { 59 fd = PETSC_STDERR; 60 } else { 61 ierr = PetscStrreplace(PETSC_COMM_SELF,name,tname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 62 ierr = PetscFixFilename(tname,fname);CHKERRQ(ierr); 63 ierr = PetscInfo1(0,"Opening file %s\n",fname);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 70 } 71 72 #undef __FUNCT__ 73 #define __FUNCT__ "PetscFClose" 74 /*@ 75 PetscFClose - Has the first processor in the communicator close a 76 file; all others do nothing. 77 78 Collective on MPI_Comm 79 80 Input Parameters: 81 + comm - the communicator 82 - fd - the file, opened with PetscFOpen() 83 84 Level: developer 85 86 Fortran Note: 87 This routine is not supported in Fortran. 88 89 Concepts: files^closing ASCII 90 Concepts: closing file 91 92 .seealso: PetscFOpen() 93 @*/ 94 PetscErrorCode PETSC_DLLEXPORT PetscFClose(MPI_Comm comm,FILE *fd) 95 { 96 PetscErrorCode ierr; 97 PetscMPIInt rank; 98 int err; 99 100 PetscFunctionBegin; 101 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 107 } 108 109 #if defined(PETSC_HAVE_POPEN) 110 111 #undef __FUNCT__ 112 #define __FUNCT__ "PetscPClose" 113 /*@C 114 PetscPClose - Closes (ends) a program on processor zero run with PetscPOpen() 115 116 Collective on MPI_Comm, but only process 0 runs the command 117 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 121 122 Level: intermediate 123 124 Notes: 125 Does not work under Windows 126 127 .seealso: PetscFOpen(), PetscFClose(), PetscPOpen() 128 129 @*/ 130 PetscErrorCode PETSC_DLLEXPORT PetscPClose(MPI_Comm comm,FILE *fd) 131 { 132 PetscErrorCode ierr; 133 PetscMPIInt rank; 134 int err; 135 136 PetscFunctionBegin; 137 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 145 } 146 147 148 #undef __FUNCT__ 149 #define __FUNCT__ "PetscPOpen" 150 /*@C 151 PetscPOpen - Runs a program on processor zero and sends either its input or output to 152 a file. 153 154 Collective on MPI_Comm, but only process 0 runs the command 155 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 161 162 Output Parameter: 163 . fp - the file pointer where program input or output may be read or PETSC_NULL if don't care 164 165 Level: intermediate 166 167 Notes: 168 Use PetscPClose() to close the file pointer when you are finished with it 169 Does not work under Windows 170 171 The program string may contain ${DISPLAY}, ${HOMEDIRECTORY} or ${WORKINGDIRECTORY}; these 172 will be replaced with relevent values. 173 174 .seealso: PetscFOpen(), PetscFClose(), PetscPClose() 175 176 @*/ 177 PetscErrorCode PETSC_DLLEXPORT PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp) 178 { 179 PetscErrorCode ierr; 180 PetscMPIInt rank; 181 size_t i,len,cnt; 182 char commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN]; 183 FILE *fd; 184 185 PetscFunctionBegin; 186 187 /* all processors have to do the string manipulation because PetscStrreplace() is a collective operation */ 188 if (machine && machine[0]) { 189 ierr = PetscStrcpy(command,"ssh ");CHKERRQ(ierr); 190 ierr = PetscStrcat(command,machine);CHKERRQ(ierr); 191 ierr = PetscStrcat(command," \" setenv DISPLAY ${DISPLAY}; ");CHKERRQ(ierr); 192 /* 193 Copy program into command but protect the " with a \ in front of it 194 */ 195 ierr = PetscStrlen(command,&cnt);CHKERRQ(ierr); 196 ierr = PetscStrlen(program,&len);CHKERRQ(ierr); 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 ierr = PetscStrcat(command,"\"");CHKERRQ(ierr); 205 } else { 206 ierr = PetscStrcpy(command,program);CHKERRQ(ierr); 207 } 208 209 ierr = PetscStrreplace(comm,command,commandt,1024);CHKERRQ(ierr); 210 211 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 212 if (!rank) { 213 ierr = PetscInfo1(0,"Running command :%s\n",commandt);CHKERRQ(ierr); 214 if (!(fd = popen(commandt,mode))) { 215 SETERRQ1(PETSC_ERR_LIB,"Cannot run command %s",commandt); 216 } 217 if (fp) *fp = fd; 218 } 219 PetscFunctionReturn(0); 220 } 221 222 #endif 223