xref: /petsc/src/sys/fileio/fretrieve.c (revision 7d0a6c19129e7069c8a40e210b34ed62989173db)
1*7d0a6c19SBarry Smith 
2e5c89e4eSSatish Balay /*
3e5c89e4eSSatish Balay       Code for opening and closing files.
4e5c89e4eSSatish Balay */
5d382aafbSBarry Smith #include "petscsys.h"
6e5c89e4eSSatish Balay #if defined(PETSC_HAVE_PWD_H)
7e5c89e4eSSatish Balay #include <pwd.h>
8e5c89e4eSSatish Balay #endif
9e5c89e4eSSatish Balay #include <ctype.h>
10e5c89e4eSSatish Balay #include <sys/types.h>
11e5c89e4eSSatish Balay #include <sys/stat.h>
12e5c89e4eSSatish Balay #if defined(PETSC_HAVE_UNISTD_H)
13e5c89e4eSSatish Balay #include <unistd.h>
14e5c89e4eSSatish Balay #endif
15e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STDLIB_H)
16e5c89e4eSSatish Balay #include <stdlib.h>
17e5c89e4eSSatish Balay #endif
18e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_UTSNAME_H)
19e5c89e4eSSatish Balay #include <sys/utsname.h>
20e5c89e4eSSatish Balay #endif
21e5c89e4eSSatish Balay #include <fcntl.h>
22e5c89e4eSSatish Balay #include <time.h>
23e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H)
24e5c89e4eSSatish Balay #include <sys/systeminfo.h>
25e5c89e4eSSatish Balay #endif
26e5c89e4eSSatish Balay 
27e5c89e4eSSatish Balay EXTERN_C_BEGIN
28480cf27aSJed Brown #undef __FUNCT__
29480cf27aSJed Brown #define __FUNCT__ "Petsc_DelTmpShared"
30480cf27aSJed Brown /*
31480cf27aSJed Brown    Private routine to delete tmp/shared storage
32480cf27aSJed Brown 
33480cf27aSJed Brown    This is called by MPI, not by users.
34480cf27aSJed Brown 
35480cf27aSJed Brown    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
36480cf27aSJed Brown 
37480cf27aSJed Brown */
387087cfbeSBarry Smith PetscMPIInt  MPIAPI Petsc_DelTmpShared(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
39480cf27aSJed Brown {
40480cf27aSJed Brown   PetscErrorCode ierr;
41480cf27aSJed Brown 
42480cf27aSJed Brown   PetscFunctionBegin;
43480cf27aSJed Brown   ierr = PetscInfo1(0,"Deleting tmp/shared data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
44480cf27aSJed Brown   ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
45480cf27aSJed Brown   PetscFunctionReturn(MPI_SUCCESS);
46480cf27aSJed Brown }
47e5c89e4eSSatish Balay EXTERN_C_END
48e5c89e4eSSatish Balay 
49e5c89e4eSSatish Balay #undef __FUNCT__
50e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetTmp"
51e5c89e4eSSatish Balay /*@C
52e5c89e4eSSatish Balay    PetscGetTmp - Gets the name of the tmp directory
53e5c89e4eSSatish Balay 
54e5c89e4eSSatish Balay    Collective on MPI_Comm
55e5c89e4eSSatish Balay 
56e5c89e4eSSatish Balay    Input Parameters:
57e5c89e4eSSatish Balay +  comm - MPI_Communicator that may share /tmp
58e5c89e4eSSatish Balay -  len - length of string to hold name
59e5c89e4eSSatish Balay 
60e5c89e4eSSatish Balay    Output Parameters:
61e5c89e4eSSatish Balay .  dir - directory name
62e5c89e4eSSatish Balay 
63e5c89e4eSSatish Balay    Options Database Keys:
64e5c89e4eSSatish Balay +    -shared_tmp
65e5c89e4eSSatish Balay .    -not_shared_tmp
66e5c89e4eSSatish Balay -    -tmp tmpdir
67e5c89e4eSSatish Balay 
68e5c89e4eSSatish Balay    Environmental Variables:
69e5c89e4eSSatish Balay +     PETSC_SHARED_TMP
70e5c89e4eSSatish Balay .     PETSC_NOT_SHARED_TMP
71e5c89e4eSSatish Balay -     PETSC_TMP
72e5c89e4eSSatish Balay 
73e5c89e4eSSatish Balay    Level: developer
74e5c89e4eSSatish Balay 
75e5c89e4eSSatish Balay 
76e5c89e4eSSatish Balay    If the environmental variable PETSC_TMP is set it will use this directory
77e5c89e4eSSatish Balay   as the "/tmp" directory.
78e5c89e4eSSatish Balay 
79e5c89e4eSSatish Balay @*/
807087cfbeSBarry Smith PetscErrorCode  PetscGetTmp(MPI_Comm comm,char dir[],size_t len)
81e5c89e4eSSatish Balay {
82e5c89e4eSSatish Balay   PetscErrorCode ierr;
83ace3abfcSBarry Smith   PetscBool      flg;
84e5c89e4eSSatish Balay 
85e5c89e4eSSatish Balay   PetscFunctionBegin;
86e5c89e4eSSatish Balay   ierr = PetscOptionsGetenv(comm,"PETSC_TMP",dir,len,&flg);CHKERRQ(ierr);
87e5c89e4eSSatish Balay   if (!flg) {
88e5c89e4eSSatish Balay     ierr = PetscStrncpy(dir,"/tmp",len);CHKERRQ(ierr);
89e5c89e4eSSatish Balay   }
90e5c89e4eSSatish Balay   PetscFunctionReturn(0);
91e5c89e4eSSatish Balay }
92e5c89e4eSSatish Balay 
93e5c89e4eSSatish Balay #undef __FUNCT__
94e5c89e4eSSatish Balay #define __FUNCT__ "PetscSharedTmp"
95e5c89e4eSSatish Balay /*@C
96e5c89e4eSSatish Balay    PetscSharedTmp - Determines if all processors in a communicator share a
97e5c89e4eSSatish Balay          /tmp or have different ones.
98e5c89e4eSSatish Balay 
99e5c89e4eSSatish Balay    Collective on MPI_Comm
100e5c89e4eSSatish Balay 
101e5c89e4eSSatish Balay    Input Parameters:
102e5c89e4eSSatish Balay .  comm - MPI_Communicator that may share /tmp
103e5c89e4eSSatish Balay 
104e5c89e4eSSatish Balay    Output Parameters:
105e5c89e4eSSatish Balay .  shared - PETSC_TRUE or PETSC_FALSE
106e5c89e4eSSatish Balay 
107e5c89e4eSSatish Balay    Options Database Keys:
108e5c89e4eSSatish Balay +    -shared_tmp
109e5c89e4eSSatish Balay .    -not_shared_tmp
110e5c89e4eSSatish Balay -    -tmp tmpdir
111e5c89e4eSSatish Balay 
112e5c89e4eSSatish Balay    Environmental Variables:
113e5c89e4eSSatish Balay +     PETSC_SHARED_TMP
114e5c89e4eSSatish Balay .     PETSC_NOT_SHARED_TMP
115e5c89e4eSSatish Balay -     PETSC_TMP
116e5c89e4eSSatish Balay 
117e5c89e4eSSatish Balay    Level: developer
118e5c89e4eSSatish Balay 
119e5c89e4eSSatish Balay    Notes:
120e5c89e4eSSatish Balay    Stores the status as a MPI attribute so it does not have
121e5c89e4eSSatish Balay     to be redetermined each time.
122e5c89e4eSSatish Balay 
123e5c89e4eSSatish Balay       Assumes that all processors in a communicator either
124e5c89e4eSSatish Balay        1) have a common /tmp or
125a8c7a070SBarry Smith        2) each has a separate /tmp
126e5c89e4eSSatish Balay       eventually we can write a fancier one that determines which processors
127e5c89e4eSSatish Balay       share a common /tmp.
128e5c89e4eSSatish Balay 
129e5c89e4eSSatish Balay    This will be very slow on runs with a large number of processors since
130e5c89e4eSSatish Balay    it requires O(p*p) file opens.
131e5c89e4eSSatish Balay 
132e5c89e4eSSatish Balay    If the environmental variable PETSC_TMP is set it will use this directory
133e5c89e4eSSatish Balay   as the "/tmp" directory.
134e5c89e4eSSatish Balay 
135e5c89e4eSSatish Balay @*/
1367087cfbeSBarry Smith PetscErrorCode  PetscSharedTmp(MPI_Comm comm,PetscBool  *shared)
137e5c89e4eSSatish Balay {
138e5c89e4eSSatish Balay   PetscErrorCode     ierr;
139e5c89e4eSSatish Balay   PetscMPIInt        size,rank,*tagvalp,sum,cnt,i;
140ace3abfcSBarry Smith   PetscBool          flg,iflg;
141e5c89e4eSSatish Balay   FILE               *fd;
142e5c89e4eSSatish Balay   static PetscMPIInt Petsc_Tmp_keyval = MPI_KEYVAL_INVALID;
143ed9cf6e9SBarry Smith   int                err;
144e5c89e4eSSatish Balay 
145e5c89e4eSSatish Balay   PetscFunctionBegin;
146e5c89e4eSSatish Balay   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
147e5c89e4eSSatish Balay   if (size == 1) {
148e5c89e4eSSatish Balay     *shared = PETSC_TRUE;
149e5c89e4eSSatish Balay     PetscFunctionReturn(0);
150e5c89e4eSSatish Balay   }
151e5c89e4eSSatish Balay 
152e5c89e4eSSatish Balay   ierr = PetscOptionsGetenv(comm,"PETSC_SHARED_TMP",PETSC_NULL,0,&flg);CHKERRQ(ierr);
153e5c89e4eSSatish Balay   if (flg) {
154e5c89e4eSSatish Balay     *shared = PETSC_TRUE;
155e5c89e4eSSatish Balay     PetscFunctionReturn(0);
156e5c89e4eSSatish Balay   }
157e5c89e4eSSatish Balay 
158e5c89e4eSSatish Balay   ierr = PetscOptionsGetenv(comm,"PETSC_NOT_SHARED_TMP",PETSC_NULL,0,&flg);CHKERRQ(ierr);
159e5c89e4eSSatish Balay   if (flg) {
160e5c89e4eSSatish Balay     *shared = PETSC_FALSE;
161e5c89e4eSSatish Balay     PetscFunctionReturn(0);
162e5c89e4eSSatish Balay   }
163e5c89e4eSSatish Balay 
164e5c89e4eSSatish Balay   if (Petsc_Tmp_keyval == MPI_KEYVAL_INVALID) {
165480cf27aSJed Brown     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelTmpShared,&Petsc_Tmp_keyval,0);CHKERRQ(ierr);
166e5c89e4eSSatish Balay   }
167e5c89e4eSSatish Balay 
168e5c89e4eSSatish Balay   ierr = MPI_Attr_get(comm,Petsc_Tmp_keyval,(void**)&tagvalp,(int*)&iflg);CHKERRQ(ierr);
169e5c89e4eSSatish Balay   if (!iflg) {
170e5c89e4eSSatish Balay     char       filename[PETSC_MAX_PATH_LEN],tmpname[PETSC_MAX_PATH_LEN];
171e5c89e4eSSatish Balay 
172e5c89e4eSSatish Balay     /* This communicator does not yet have a shared tmp attribute */
173e5c89e4eSSatish Balay     ierr = PetscMalloc(sizeof(PetscMPIInt),&tagvalp);CHKERRQ(ierr);
174e5c89e4eSSatish Balay     ierr = MPI_Attr_put(comm,Petsc_Tmp_keyval,tagvalp);CHKERRQ(ierr);
175e5c89e4eSSatish Balay 
176e5c89e4eSSatish Balay     ierr = PetscOptionsGetenv(comm,"PETSC_TMP",tmpname,238,&iflg);CHKERRQ(ierr);
177e5c89e4eSSatish Balay     if (!iflg) {
178e5c89e4eSSatish Balay       ierr = PetscStrcpy(filename,"/tmp");CHKERRQ(ierr);
179e5c89e4eSSatish Balay     } else {
180e5c89e4eSSatish Balay       ierr = PetscStrcpy(filename,tmpname);CHKERRQ(ierr);
181e5c89e4eSSatish Balay     }
182e5c89e4eSSatish Balay 
183e5c89e4eSSatish Balay     ierr = PetscStrcat(filename,"/petsctestshared");CHKERRQ(ierr);
184e5c89e4eSSatish Balay     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
185e5c89e4eSSatish Balay 
186e5c89e4eSSatish Balay     /* each processor creates a /tmp file and all the later ones check */
187e5c89e4eSSatish Balay     /* this makes sure no subset of processors is shared */
188e5c89e4eSSatish Balay     *shared = PETSC_FALSE;
189e5c89e4eSSatish Balay     for (i=0; i<size-1; i++) {
190e5c89e4eSSatish Balay       if (rank == i) {
191e5c89e4eSSatish Balay         fd = fopen(filename,"w");
192e5c89e4eSSatish Balay         if (!fd) {
193e32f2f54SBarry Smith           SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open test file %s",filename);
194e5c89e4eSSatish Balay         }
195ed9cf6e9SBarry Smith         err = fclose(fd);
196e32f2f54SBarry Smith         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
197e5c89e4eSSatish Balay       }
198e5c89e4eSSatish Balay       ierr = MPI_Barrier(comm);CHKERRQ(ierr);
199e5c89e4eSSatish Balay       if (rank >= i) {
200e5c89e4eSSatish Balay         fd = fopen(filename,"r");
201e5c89e4eSSatish Balay         if (fd) cnt = 1; else cnt = 0;
202e5c89e4eSSatish Balay         if (fd) {
203ed9cf6e9SBarry Smith           err = fclose(fd);
204e32f2f54SBarry Smith           if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
205e5c89e4eSSatish Balay         }
206e5c89e4eSSatish Balay       } else {
207e5c89e4eSSatish Balay         cnt = 0;
208e5c89e4eSSatish Balay       }
209e5c89e4eSSatish Balay       ierr = MPI_Allreduce(&cnt,&sum,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr);
210e5c89e4eSSatish Balay       if (rank == i) {
211e5c89e4eSSatish Balay         unlink(filename);
212e5c89e4eSSatish Balay       }
213e5c89e4eSSatish Balay 
214e5c89e4eSSatish Balay       if (sum == size) {
215e5c89e4eSSatish Balay         *shared = PETSC_TRUE;
216e5c89e4eSSatish Balay         break;
217e5c89e4eSSatish Balay       } else if (sum != 1) {
218e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Subset of processes share /tmp ");
219e5c89e4eSSatish Balay       }
220e5c89e4eSSatish Balay     }
221e5c89e4eSSatish Balay     *tagvalp = (int)*shared;
222ae15b995SBarry Smith     ierr = PetscInfo2(0,"processors %s %s\n",(*shared) ? "share":"do NOT share",(iflg ? tmpname:"/tmp"));CHKERRQ(ierr);
223e5c89e4eSSatish Balay   } else {
224ace3abfcSBarry Smith     *shared = (PetscBool) *tagvalp;
225e5c89e4eSSatish Balay   }
226e5c89e4eSSatish Balay   PetscFunctionReturn(0);
227e5c89e4eSSatish Balay }
228e5c89e4eSSatish Balay 
229e5c89e4eSSatish Balay #undef __FUNCT__
230e5c89e4eSSatish Balay #define __FUNCT__ "PetscSharedWorkingDirectory"
231e5c89e4eSSatish Balay /*@C
232e5c89e4eSSatish Balay    PetscSharedWorkingDirectory - Determines if all processors in a communicator share a
233e5c89e4eSSatish Balay          working directory or have different ones.
234e5c89e4eSSatish Balay 
235e5c89e4eSSatish Balay    Collective on MPI_Comm
236e5c89e4eSSatish Balay 
237e5c89e4eSSatish Balay    Input Parameters:
238e5c89e4eSSatish Balay .  comm - MPI_Communicator that may share working directory
239e5c89e4eSSatish Balay 
240e5c89e4eSSatish Balay    Output Parameters:
241e5c89e4eSSatish Balay .  shared - PETSC_TRUE or PETSC_FALSE
242e5c89e4eSSatish Balay 
243e5c89e4eSSatish Balay    Options Database Keys:
244e5c89e4eSSatish Balay +    -shared_working_directory
245e5c89e4eSSatish Balay .    -not_shared_working_directory
246e5c89e4eSSatish Balay 
247e5c89e4eSSatish Balay    Environmental Variables:
248e5c89e4eSSatish Balay +     PETSC_SHARED_WORKING_DIRECTORY
249e5c89e4eSSatish Balay .     PETSC_NOT_SHARED_WORKING_DIRECTORY
250e5c89e4eSSatish Balay 
251e5c89e4eSSatish Balay    Level: developer
252e5c89e4eSSatish Balay 
253e5c89e4eSSatish Balay    Notes:
254e5c89e4eSSatish Balay    Stores the status as a MPI attribute so it does not have
255e5c89e4eSSatish Balay     to be redetermined each time.
256e5c89e4eSSatish Balay 
257e5c89e4eSSatish Balay       Assumes that all processors in a communicator either
258e5c89e4eSSatish Balay        1) have a common working directory or
259a8c7a070SBarry Smith        2) each has a separate working directory
260e5c89e4eSSatish Balay       eventually we can write a fancier one that determines which processors
261e5c89e4eSSatish Balay       share a common working directory.
262e5c89e4eSSatish Balay 
263e5c89e4eSSatish Balay    This will be very slow on runs with a large number of processors since
264e5c89e4eSSatish Balay    it requires O(p*p) file opens.
265e5c89e4eSSatish Balay 
266e5c89e4eSSatish Balay @*/
2677087cfbeSBarry Smith PetscErrorCode  PetscSharedWorkingDirectory(MPI_Comm comm,PetscBool  *shared)
268e5c89e4eSSatish Balay {
269e5c89e4eSSatish Balay   PetscErrorCode     ierr;
270e5c89e4eSSatish Balay   PetscMPIInt        size,rank,*tagvalp,sum,cnt,i;
271ace3abfcSBarry Smith   PetscBool          flg,iflg;
272e5c89e4eSSatish Balay   FILE               *fd;
273e5c89e4eSSatish Balay   static PetscMPIInt Petsc_WD_keyval = MPI_KEYVAL_INVALID;
274ed9cf6e9SBarry Smith   int                err;
275e5c89e4eSSatish Balay 
276e5c89e4eSSatish Balay   PetscFunctionBegin;
277e5c89e4eSSatish Balay   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
278e5c89e4eSSatish Balay   if (size == 1) {
279e5c89e4eSSatish Balay     *shared = PETSC_TRUE;
280e5c89e4eSSatish Balay     PetscFunctionReturn(0);
281e5c89e4eSSatish Balay   }
282e5c89e4eSSatish Balay 
283e5c89e4eSSatish Balay   ierr = PetscOptionsGetenv(comm,"PETSC_SHARED_WORKING_DIRECTORY",PETSC_NULL,0,&flg);CHKERRQ(ierr);
284e5c89e4eSSatish Balay   if (flg) {
285e5c89e4eSSatish Balay     *shared = PETSC_TRUE;
286e5c89e4eSSatish Balay     PetscFunctionReturn(0);
287e5c89e4eSSatish Balay   }
288e5c89e4eSSatish Balay 
289e5c89e4eSSatish Balay   ierr = PetscOptionsGetenv(comm,"PETSC_NOT_SHARED_WORKING_DIRECTORY",PETSC_NULL,0,&flg);CHKERRQ(ierr);
290e5c89e4eSSatish Balay   if (flg) {
291e5c89e4eSSatish Balay     *shared = PETSC_FALSE;
292e5c89e4eSSatish Balay     PetscFunctionReturn(0);
293e5c89e4eSSatish Balay   }
294e5c89e4eSSatish Balay 
295e5c89e4eSSatish Balay   if (Petsc_WD_keyval == MPI_KEYVAL_INVALID) {
296480cf27aSJed Brown     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelTmpShared,&Petsc_WD_keyval,0);CHKERRQ(ierr);
297e5c89e4eSSatish Balay   }
298e5c89e4eSSatish Balay 
299e5c89e4eSSatish Balay   ierr = MPI_Attr_get(comm,Petsc_WD_keyval,(void**)&tagvalp,(int*)&iflg);CHKERRQ(ierr);
300e5c89e4eSSatish Balay   if (!iflg) {
301e5c89e4eSSatish Balay     char       filename[PETSC_MAX_PATH_LEN];
302e5c89e4eSSatish Balay 
303e5c89e4eSSatish Balay     /* This communicator does not yet have a shared  attribute */
304e5c89e4eSSatish Balay     ierr = PetscMalloc(sizeof(PetscMPIInt),&tagvalp);CHKERRQ(ierr);
305e5c89e4eSSatish Balay     ierr = MPI_Attr_put(comm,Petsc_WD_keyval,tagvalp);CHKERRQ(ierr);
306e5c89e4eSSatish Balay 
307e5c89e4eSSatish Balay     ierr = PetscGetWorkingDirectory(filename,240);CHKERRQ(ierr);
308e5c89e4eSSatish Balay     ierr = PetscStrcat(filename,"/petsctestshared");CHKERRQ(ierr);
309e5c89e4eSSatish Balay     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
310e5c89e4eSSatish Balay 
311e5c89e4eSSatish Balay     /* each processor creates a  file and all the later ones check */
312e5c89e4eSSatish Balay     /* this makes sure no subset of processors is shared */
313e5c89e4eSSatish Balay     *shared = PETSC_FALSE;
314e5c89e4eSSatish Balay     for (i=0; i<size-1; i++) {
315e5c89e4eSSatish Balay       if (rank == i) {
316e5c89e4eSSatish Balay         fd = fopen(filename,"w");
317e32f2f54SBarry Smith         if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open test file %s",filename);
318ed9cf6e9SBarry Smith         err = fclose(fd);
319e32f2f54SBarry Smith         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
320e5c89e4eSSatish Balay       }
321e5c89e4eSSatish Balay       ierr = MPI_Barrier(comm);CHKERRQ(ierr);
322e5c89e4eSSatish Balay       if (rank >= i) {
323e5c89e4eSSatish Balay         fd = fopen(filename,"r");
324e5c89e4eSSatish Balay         if (fd) cnt = 1; else cnt = 0;
325e5c89e4eSSatish Balay         if (fd) {
326ed9cf6e9SBarry Smith           err = fclose(fd);
327e32f2f54SBarry Smith           if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
328e5c89e4eSSatish Balay         }
329e5c89e4eSSatish Balay       } else {
330e5c89e4eSSatish Balay         cnt = 0;
331e5c89e4eSSatish Balay       }
332e5c89e4eSSatish Balay       ierr = MPI_Allreduce(&cnt,&sum,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr);
333e5c89e4eSSatish Balay       if (rank == i) {
334e5c89e4eSSatish Balay         unlink(filename);
335e5c89e4eSSatish Balay       }
336e5c89e4eSSatish Balay 
337e5c89e4eSSatish Balay       if (sum == size) {
338e5c89e4eSSatish Balay         *shared = PETSC_TRUE;
339e5c89e4eSSatish Balay         break;
340e5c89e4eSSatish Balay       } else if (sum != 1) {
341e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Subset of processes share working directory");
342e5c89e4eSSatish Balay       }
343e5c89e4eSSatish Balay     }
344e5c89e4eSSatish Balay     *tagvalp = (int)*shared;
345e5c89e4eSSatish Balay   } else {
346ace3abfcSBarry Smith     *shared = (PetscBool) *tagvalp;
347e5c89e4eSSatish Balay   }
348ae15b995SBarry Smith   ierr = PetscInfo1(0,"processors %s working directory\n",(*shared) ? "shared" : "do NOT share");CHKERRQ(ierr);
349e5c89e4eSSatish Balay   PetscFunctionReturn(0);
350e5c89e4eSSatish Balay }
351e5c89e4eSSatish Balay 
352e5c89e4eSSatish Balay 
353e5c89e4eSSatish Balay #undef __FUNCT__
354e5c89e4eSSatish Balay #define __FUNCT__ "PetscFileRetrieve"
355e5c89e4eSSatish Balay /*@C
356e5c89e4eSSatish Balay     PetscFileRetrieve - Obtains a library from a URL or compressed
357e5c89e4eSSatish Balay         and copies into local disk space as uncompressed.
358e5c89e4eSSatish Balay 
359e5c89e4eSSatish Balay     Collective on MPI_Comm
360e5c89e4eSSatish Balay 
361e5c89e4eSSatish Balay     Input Parameter:
362e5c89e4eSSatish Balay +   comm     - processors accessing the library
363e5c89e4eSSatish Balay .   libname  - name of library, including entire URL (with or without .gz)
364e5c89e4eSSatish Balay -   llen     - length of llibname
365e5c89e4eSSatish Balay 
366e5c89e4eSSatish Balay     Output Parameter:
367e5c89e4eSSatish Balay +   llibname - name of local copy of library
368e5c89e4eSSatish Balay -   found - if found and retrieved the file
369e5c89e4eSSatish Balay 
370e5c89e4eSSatish Balay     Level: developer
371e5c89e4eSSatish Balay 
372e5c89e4eSSatish Balay @*/
3737087cfbeSBarry Smith PetscErrorCode  PetscFileRetrieve(MPI_Comm comm,const char libname[],char llibname[],size_t llen,PetscBool  *found)
374e5c89e4eSSatish Balay {
375e5c89e4eSSatish Balay   char              buf[1024],tmpdir[PETSC_MAX_PATH_LEN],urlget[PETSC_MAX_PATH_LEN],*par;
376e5c89e4eSSatish Balay   const char        *pdir;
377e5c89e4eSSatish Balay   FILE              *fp;
378e5c89e4eSSatish Balay   PetscErrorCode    ierr;
379e5c89e4eSSatish Balay   int               i;
380e5c89e4eSSatish Balay   PetscMPIInt       rank;
381e5c89e4eSSatish Balay   size_t            len = 0;
382ace3abfcSBarry Smith   PetscBool         flg1,flg2,flg3,sharedtmp,exists;
383e5c89e4eSSatish Balay 
384e5c89e4eSSatish Balay   PetscFunctionBegin;
385e5c89e4eSSatish Balay   *found = PETSC_FALSE;
386e5c89e4eSSatish Balay 
387e5c89e4eSSatish Balay   /* if file does not have an ftp:// or http:// or .gz then need not process file */
388e5c89e4eSSatish Balay   ierr = PetscStrstr(libname,".gz",&par);CHKERRQ(ierr);
389e5c89e4eSSatish Balay   if (par) {ierr = PetscStrlen(par,&len);CHKERRQ(ierr);}
390e5c89e4eSSatish Balay 
391e5c89e4eSSatish Balay   ierr = PetscStrncmp(libname,"ftp://",6,&flg1);CHKERRQ(ierr);
392e5c89e4eSSatish Balay   ierr = PetscStrncmp(libname,"http://",7,&flg2);CHKERRQ(ierr);
3933fa76a5bSLisandro Dalcin   ierr = PetscStrncmp(libname,"file://",7,&flg3);CHKERRQ(ierr);
3943fa76a5bSLisandro Dalcin   if (!flg1 && !flg2 && !flg3 && (!par || len != 3)) {
395e5c89e4eSSatish Balay     ierr = PetscStrncpy(llibname,libname,llen);CHKERRQ(ierr);
396e5c89e4eSSatish Balay     ierr = PetscTestFile(libname,'r',found);CHKERRQ(ierr);
397487e5849SBarry Smith     if (*found) {
398487e5849SBarry Smith       ierr = PetscInfo1(PETSC_NULL,"Found file %s\n",libname);
399487e5849SBarry Smith     } else {
400487e5849SBarry Smith       ierr = PetscInfo1(PETSC_NULL,"Did not find file %s\n",libname);
401487e5849SBarry Smith     }
402e5c89e4eSSatish Balay     PetscFunctionReturn(0);
403e5c89e4eSSatish Balay   }
404e5c89e4eSSatish Balay 
405e5c89e4eSSatish Balay   /* Determine if all processors share a common /tmp */
406e5c89e4eSSatish Balay   ierr = PetscSharedTmp(comm,&sharedtmp);CHKERRQ(ierr);
407e5c89e4eSSatish Balay   ierr = PetscOptionsGetenv(comm,"PETSC_TMP",tmpdir,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
408e5c89e4eSSatish Balay 
409e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
410e5c89e4eSSatish Balay   if (!rank || !sharedtmp) {
411e5c89e4eSSatish Balay 
412e5c89e4eSSatish Balay     /* Construct the script to get URL file */
413e5c89e4eSSatish Balay     ierr = PetscGetPetscDir(&pdir);CHKERRQ(ierr);
414e5c89e4eSSatish Balay     ierr = PetscStrcpy(urlget,pdir);CHKERRQ(ierr);
415e5c89e4eSSatish Balay     ierr = PetscStrcat(urlget,"/bin/urlget");CHKERRQ(ierr);
416e5c89e4eSSatish Balay     ierr = PetscTestFile(urlget,'r',&exists);CHKERRQ(ierr);
417e5c89e4eSSatish Balay     if (!exists) {
418e5c89e4eSSatish Balay       ierr = PetscTestFile("urlget",'r',&exists);CHKERRQ(ierr);
419e5c89e4eSSatish Balay       if (!exists) {
420e32f2f54SBarry Smith         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot locate PETSc script urlget in %s or current directory",urlget);
421e5c89e4eSSatish Balay       }
422e5c89e4eSSatish Balay       ierr = PetscStrcpy(urlget,"urlget");CHKERRQ(ierr);
423e5c89e4eSSatish Balay     }
424e5c89e4eSSatish Balay     ierr = PetscStrcat(urlget," ");CHKERRQ(ierr);
425e5c89e4eSSatish Balay 
426e5c89e4eSSatish Balay     /* are we using an alternative /tmp? */
427e5c89e4eSSatish Balay     if (flg1) {
428e5c89e4eSSatish Balay       ierr = PetscStrcat(urlget,"-tmp ");CHKERRQ(ierr);
429e5c89e4eSSatish Balay       ierr = PetscStrcat(urlget,tmpdir);CHKERRQ(ierr);
430e5c89e4eSSatish Balay       ierr = PetscStrcat(urlget," ");CHKERRQ(ierr);
431e5c89e4eSSatish Balay     }
432e5c89e4eSSatish Balay 
433e5c89e4eSSatish Balay     ierr = PetscStrcat(urlget,libname);CHKERRQ(ierr);
434e5c89e4eSSatish Balay     ierr = PetscStrcat(urlget," 2>&1 ");CHKERRQ(ierr);
435e5c89e4eSSatish Balay 
436e5c89e4eSSatish Balay #if defined(PETSC_HAVE_POPEN)
437e5c89e4eSSatish Balay     ierr = PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,urlget,"r",&fp);CHKERRQ(ierr);
438e5c89e4eSSatish Balay #else
439e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
440e5c89e4eSSatish Balay #endif
441e5c89e4eSSatish Balay     if (!fgets(buf,1024,fp)) {
442e32f2f54SBarry Smith       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"No output from ${PETSC_DIR}/bin/urlget in getting file %s",libname);
443e5c89e4eSSatish Balay     }
444ae15b995SBarry Smith     ierr = PetscInfo1(0,"Message back from urlget: %s\n",buf);CHKERRQ(ierr);
445e5c89e4eSSatish Balay 
446e5c89e4eSSatish Balay     ierr = PetscStrncmp(buf,"Error",5,&flg1);CHKERRQ(ierr);
447e5c89e4eSSatish Balay     ierr = PetscStrncmp(buf,"Traceback",9,&flg2);CHKERRQ(ierr);
448e5c89e4eSSatish Balay #if defined(PETSC_HAVE_POPEN)
449e5c89e4eSSatish Balay     ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr);
450e5c89e4eSSatish Balay #endif
451e5c89e4eSSatish Balay     if (flg1 || flg2) {
452e5c89e4eSSatish Balay       *found = PETSC_FALSE;
453e5c89e4eSSatish Balay     } else {
454e5c89e4eSSatish Balay       *found = PETSC_TRUE;
455e5c89e4eSSatish Balay 
456e5c89e4eSSatish Balay       /* Check for \n and make it 0 */
457e5c89e4eSSatish Balay       for (i=0; i<1024; i++) {
458e5c89e4eSSatish Balay         if (buf[i] == '\n') {
459e5c89e4eSSatish Balay           buf[i] = 0;
460e5c89e4eSSatish Balay           break;
461e5c89e4eSSatish Balay         }
462e5c89e4eSSatish Balay       }
463e5c89e4eSSatish Balay       ierr = PetscStrncpy(llibname,buf,llen);CHKERRQ(ierr);
464e5c89e4eSSatish Balay     }
465e5c89e4eSSatish Balay   }
466e5c89e4eSSatish Balay   if (sharedtmp) { /* send library name to all processors */
467e5c89e4eSSatish Balay     ierr = MPI_Bcast(found,1,MPI_INT,0,comm);CHKERRQ(ierr);
468e5c89e4eSSatish Balay     if (*found) {
469e5c89e4eSSatish Balay       ierr = MPI_Bcast(llibname,llen,MPI_CHAR,0,comm);CHKERRQ(ierr);
470e5c89e4eSSatish Balay       ierr = MPI_Bcast(found,1,MPI_INT,0,comm);CHKERRQ(ierr);
471e5c89e4eSSatish Balay     }
472e5c89e4eSSatish Balay   }
473e5c89e4eSSatish Balay 
474e5c89e4eSSatish Balay   PetscFunctionReturn(0);
475e5c89e4eSSatish Balay }
476