1 #define PETSC_DLL 2 /* 3 Routines for opening dynamic link libraries (DLLs), keeping a searchable 4 path of DLLs, obtaining remote DLLs via a URL and opening them locally. 5 */ 6 7 #include "petsc.h" 8 #include "petscsys.h" 9 #include "petscfix.h" 10 11 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 12 13 #if defined(PETSC_HAVE_PWD_H) 14 #include <pwd.h> 15 #endif 16 #include <ctype.h> 17 #include <sys/types.h> 18 #include <sys/stat.h> 19 #if defined(PETSC_HAVE_UNISTD_H) 20 #include <unistd.h> 21 #endif 22 #if defined(PETSC_HAVE_STDLIB_H) 23 #include <stdlib.h> 24 #endif 25 #if defined(PETSC_HAVE_SYS_UTSNAME_H) 26 #include <sys/utsname.h> 27 #endif 28 #if defined(PETSC_HAVE_WINDOWS_H) 29 #include <windows.h> 30 #endif 31 #include <fcntl.h> 32 #include <time.h> 33 #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H) 34 #include <sys/systeminfo.h> 35 #endif 36 37 #endif 38 39 #include "petscfix.h" 40 41 42 /* 43 Contains the list of registered CCA components 44 */ 45 PetscFList CCAList = 0; 46 47 48 /* ------------------------------------------------------------------------------*/ 49 /* 50 Code to maintain a list of opened dynamic libraries and load symbols 51 */ 52 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 53 #if defined(PETSC_HAVE_DLFCN_H) 54 #include <dlfcn.h> 55 #endif 56 struct _n_PetscDLLibraryList { 57 PetscDLLibraryList next; 58 void *handle; 59 char libname[PETSC_MAX_PATH_LEN]; 60 }; 61 62 EXTERN_C_BEGIN 63 EXTERN PetscErrorCode Petsc_DelTag(MPI_Comm,int,void*,void*); 64 EXTERN_C_END 65 66 #undef __FUNCT__ 67 #define __FUNCT__ "PetscDLLibraryPrintPath" 68 PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryPrintPath(void) 69 { 70 PetscDLLibraryList libs; 71 72 PetscFunctionBegin; 73 libs = DLLibrariesLoaded; 74 while (libs) { 75 PetscErrorPrintf(" %s\n",libs->libname); 76 libs = libs->next; 77 } 78 PetscFunctionReturn(0); 79 } 80 81 #undef __FUNCT__ 82 #define __FUNCT__ "PetscDLLibraryRetrieve" 83 /*@C 84 PetscDLLibraryRetrieve - Copies a PETSc dynamic library from a remote location 85 (if it is remote), indicates if it exits and its local name. 86 87 Collective on MPI_Comm 88 89 Input Parameters: 90 + comm - processors that are opening the library 91 - libname - name of the library, can be relative or absolute 92 93 Output Parameter: 94 . handle - library handle 95 96 Level: developer 97 98 Notes: 99 [[<http,ftp>://hostname]/directoryname/]filename[.so.1.0] 100 101 ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, or ${any environmental variable} 102 occuring in directoryname and filename will be replaced with appropriate values. 103 @*/ 104 PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryRetrieve(MPI_Comm comm,const char libname[],char *lname,int llen,PetscTruth *found) 105 { 106 char *par2,buff[10],*en,*gz; 107 PetscErrorCode ierr; 108 size_t len1,len2,len; 109 PetscTruth tflg,flg; 110 111 PetscFunctionBegin; 112 /* 113 make copy of library name and replace $PETSC_ARCH and and 114 so we can add to the end of it to look for something like .so.1.0 etc. 115 */ 116 ierr = PetscStrlen(libname,&len);CHKERRQ(ierr); 117 len = PetscMax(4*len,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 118 ierr = PetscMalloc(len*sizeof(char),&par2);CHKERRQ(ierr); 119 ierr = PetscStrreplace(comm,libname,par2,len);CHKERRQ(ierr); 120 121 /* 122 Remove any file: header 123 */ 124 ierr = PetscStrncmp(par2,"file:",5,&tflg);CHKERRQ(ierr); 125 if (tflg) { 126 ierr = PetscStrcpy(par2,par2+5);CHKERRQ(ierr); 127 } 128 129 /* strip out .a from it if user put it in by mistake */ 130 ierr = PetscStrlen(par2,&len);CHKERRQ(ierr); 131 if (par2[len-1] == 'a' && par2[len-2] == '.') par2[len-2] = 0; 132 133 /* remove .gz if it ends library name */ 134 ierr = PetscStrstr(par2,".gz",&gz);CHKERRQ(ierr); 135 if (gz) { 136 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 137 if (len == 3) { 138 *gz = 0; 139 } 140 } 141 142 /* see if library name does already not have suffix attached */ 143 ierr = PetscStrcpy(buff,".");CHKERRQ(ierr); 144 ierr = PetscStrcat(buff,PETSC_SLSUFFIX);CHKERRQ(ierr); 145 ierr = PetscStrstr(par2,buff,&en);CHKERRQ(ierr); 146 if (en) { 147 ierr = PetscStrlen(en,&len1);CHKERRQ(ierr); 148 ierr = PetscStrlen(PETSC_SLSUFFIX,&len2);CHKERRQ(ierr); 149 flg = (PetscTruth) (len1 != 1 + len2); 150 } else { 151 flg = PETSC_TRUE; 152 } 153 if (flg) { 154 ierr = PetscStrcat(par2,".");CHKERRQ(ierr); 155 ierr = PetscStrcat(par2,PETSC_SLSUFFIX);CHKERRQ(ierr); 156 } 157 158 /* put the .gz back on if it was there */ 159 if (gz) { 160 ierr = PetscStrcat(par2,".gz");CHKERRQ(ierr); 161 } 162 163 ierr = PetscFileRetrieve(comm,par2,lname,llen,found);CHKERRQ(ierr); 164 ierr = PetscFree(par2);CHKERRQ(ierr); 165 PetscFunctionReturn(0); 166 } 167 168 169 #undef __FUNCT__ 170 #define __FUNCT__ "PetscDLLibraryOpen" 171 /*@C 172 PetscDLLibraryOpen - Opens a dynamic link library 173 174 Collective on MPI_Comm 175 176 Input Parameters: 177 + comm - processors that are opening the library 178 - libname - name of the library, can be relative or absolute 179 180 Output Parameter: 181 . handle - library handle 182 183 Level: developer 184 185 Notes: 186 [[<http,ftp>://hostname]/directoryname/]filename[.so.1.0] 187 188 ${PETSC_ARCH} occuring in directoryname and filename 189 will be replaced with the appropriate value. 190 @*/ 191 PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryOpen(MPI_Comm comm,const char libname[],void **handle) 192 { 193 PetscErrorCode ierr; 194 char *par2,registername[128],*ptr,*ptrp; 195 PetscTruth foundlibrary; 196 PetscErrorCode (*func)(const char*) = NULL; 197 size_t len; 198 199 PetscFunctionBegin; 200 *handle = NULL; 201 ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&par2);CHKERRQ(ierr); 202 ierr = PetscDLLibraryRetrieve(comm,libname,par2,PETSC_MAX_PATH_LEN,&foundlibrary);CHKERRQ(ierr); 203 if (!foundlibrary) { 204 SETERRQ1(PETSC_ERR_FILE_OPEN,"Unable to locate dynamic library:\n %s\n",libname); 205 } 206 207 /* Eventually config/configure.py should determine if the system needs an executable dynamic library */ 208 #define PETSC_USE_NONEXECUTABLE_SO 209 #if !defined(PETSC_USE_NONEXECUTABLE_SO) 210 ierr = PetscTestFile(par2,'x',&foundlibrary);CHKERRQ(ierr); 211 if (!foundlibrary) { 212 SETERRQ2(PETSC_ERR_FILE_OPEN,"Dynamic library is not executable:\n %s\n %s\n",libname,par2); 213 } 214 #endif 215 216 /* 217 Mode indicates symbols required by symbol loaded with dlsym() 218 are only loaded when required (not all together) also indicates 219 symbols required can be contained in other libraries also opened 220 with dlopen() 221 */ 222 ierr = PetscVerboseInfo((0,"PetscDLLibraryOpen:Opening %s\n",libname));CHKERRQ(ierr); 223 #if defined(PETSC_HAVE_LOADLIBRARY) 224 *handle = LoadLibrary(par2); 225 #else 226 #if defined(PETSC_HAVE_RTLD_GLOBAL) 227 *handle = dlopen(par2,RTLD_LAZY | RTLD_GLOBAL); 228 #else 229 *handle = dlopen(par2,RTLD_LAZY); 230 #endif 231 #endif 232 if (!*handle) { 233 #if defined(PETSC_HAVE_DLERROR) 234 SETERRQ3(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n %s\n Error message from dlopen() %s\n",libname,par2,dlerror()); 235 #elif defined(PETSC_HAVE_GETLASTERROR) 236 { 237 DWORD erc; 238 char *buff; 239 erc = GetLastError(); 240 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 241 NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 242 ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1, 243 "Unable to open dynamic library:\n %s\n %s\n Error message from LoadLibrary() %s\n",libname,par2,buff); 244 LocalFree(buff); 245 return(ierr); 246 } 247 #endif 248 } 249 250 /* build name of symbol to look for based on libname */ 251 ierr = PetscStrcpy(registername,"PetscDLLibraryRegister_");CHKERRQ(ierr); 252 /* look for libXXXXX.YYY and extract out the XXXXXX */ 253 ierr = PetscStrrstr(libname,"lib",&ptr);CHKERRQ(ierr); 254 if (!ptr) SETERRQ1(PETSC_ERR_ARG_WRONG,"Dynamic library name must have lib prefix:%s",libname); 255 ierr = PetscStrchr(ptr+3,'.',&ptrp);CHKERRQ(ierr); 256 if (ptrp) { 257 len = ptrp - ptr - 3; 258 } else { 259 ierr = PetscStrlen(ptr+3,&len);CHKERRQ(ierr); 260 } 261 ierr = PetscStrncat(registername,ptr+3,len);CHKERRQ(ierr); 262 263 #if defined(PETSC_HAVE_GETPROCADDRESS) 264 func = (PetscErrorCode (*)(const char *)) GetProcAddress((HMODULE)*handle,registername); 265 #else 266 func = (PetscErrorCode (*)(const char *)) dlsym(*handle,registername); 267 #endif 268 if (func) { 269 ierr = (*func)(libname);CHKERRQ(ierr); 270 ierr = PetscVerboseInfo((0,"PetscDLLibraryOpen:Loading registered routines from %s\n",libname));CHKERRQ(ierr); 271 } else { 272 SETERRQ2(PETSC_ERR_FILE_UNEXPECTED,"Able to locate dynamic library %s, but cannot load symbol %s\n",libname,registername); 273 } 274 ierr = PetscFree(par2);CHKERRQ(ierr); 275 PetscFunctionReturn(0); 276 } 277 278 #undef __FUNCT__ 279 #define __FUNCT__ "PetscDLLibrarySym" 280 /*@C 281 PetscDLLibrarySym - Load a symbol from the dynamic link libraries. 282 283 Collective on MPI_Comm 284 285 Input Parameter: 286 + path - optional complete library name 287 - insymbol - name of symbol 288 289 Output Parameter: 290 . value 291 292 Level: developer 293 294 Notes: Symbol can be of the form 295 [/path/libname[.so.1.0]:]functionname[()] where items in [] denote optional 296 297 Will attempt to (retrieve and) open the library if it is not yet been opened. 298 299 @*/ 300 PetscErrorCode PETSC_DLLEXPORT PetscDLLibrarySym(MPI_Comm comm,PetscDLLibraryList *inlist,const char path[],const char insymbol[],void **value) 301 { 302 char *par1,*symbol; 303 PetscErrorCode ierr; 304 size_t len; 305 PetscDLLibraryList nlist,prev,list; 306 307 PetscFunctionBegin; 308 if (inlist) list = *inlist; else list = PETSC_NULL; 309 *value = 0; 310 311 /* make copy of symbol so we can edit it in place */ 312 ierr = PetscStrlen(insymbol,&len);CHKERRQ(ierr); 313 ierr = PetscMalloc((len+1)*sizeof(char),&symbol);CHKERRQ(ierr); 314 ierr = PetscStrcpy(symbol,insymbol);CHKERRQ(ierr); 315 316 /* 317 If symbol contains () then replace with a NULL, to support functionname() 318 */ 319 ierr = PetscStrchr(symbol,'(',&par1);CHKERRQ(ierr); 320 if (par1) *par1 = 0; 321 322 323 /* 324 Function name does include library 325 ------------------------------------- 326 */ 327 if (path && path[0] != '\0') { 328 void *handle; 329 330 /* 331 Look if library is already opened and in path 332 */ 333 nlist = list; 334 prev = 0; 335 while (nlist) { 336 PetscTruth match; 337 338 ierr = PetscStrcmp(nlist->libname,path,&match);CHKERRQ(ierr); 339 if (match) { 340 handle = nlist->handle; 341 goto done; 342 } 343 prev = nlist; 344 nlist = nlist->next; 345 } 346 ierr = PetscDLLibraryOpen(comm,path,&handle);CHKERRQ(ierr); 347 348 ierr = PetscNew(struct _n_PetscDLLibraryList,&nlist);CHKERRQ(ierr); 349 nlist->next = 0; 350 nlist->handle = handle; 351 ierr = PetscStrcpy(nlist->libname,path);CHKERRQ(ierr); 352 353 if (prev) { 354 prev->next = nlist; 355 } else { 356 if (inlist) *inlist = nlist; 357 else {ierr = PetscDLLibraryClose(nlist);CHKERRQ(ierr);} 358 } 359 ierr = PetscVerboseInfo((0,"PetscDLLibraryAppend:Appending %s to dynamic library search path\n",path));CHKERRQ(ierr); 360 361 done:; 362 #if defined(PETSC_HAVE_GETPROCADDRESS) 363 *value = GetProcAddress((HMODULE)handle,symbol); 364 #else 365 *value = dlsym(handle,symbol); 366 #endif 367 if (!*value) { 368 SETERRQ2(PETSC_ERR_PLIB,"Unable to locate function %s in dynamic library %s",insymbol,path); 369 } 370 ierr = PetscVerboseInfo((0,"PetscDLLibrarySym:Loading function %s from dynamic library %s\n",insymbol,path));CHKERRQ(ierr); 371 372 /* 373 Function name does not include library so search path 374 ----------------------------------------------------- 375 */ 376 } else { 377 while (list) { 378 #if defined(PETSC_HAVE_GETPROCADDRESS) 379 *value = GetProcAddress((HMODULE)list->handle,symbol); 380 #else 381 *value = dlsym(list->handle,symbol); 382 #endif 383 if (*value) { 384 ierr = PetscVerboseInfo((0,"PetscDLLibrarySym:Loading function %s from dynamic library %s\n",symbol,list->libname));CHKERRQ(ierr); 385 break; 386 } 387 list = list->next; 388 } 389 if (!*value) { 390 #if defined(PETSC_HAVE_GETPROCADDRESS) 391 *value = GetProcAddress(GetCurrentProcess(),symbol); 392 #else 393 *value = dlsym(0,symbol); 394 #endif 395 if (*value) { 396 ierr = PetscVerboseInfo((0,"PetscDLLibrarySym:Loading function %s from object code\n",symbol));CHKERRQ(ierr); 397 } 398 } 399 } 400 401 ierr = PetscFree(symbol);CHKERRQ(ierr); 402 PetscFunctionReturn(0); 403 } 404 405 #undef __FUNCT__ 406 #define __FUNCT__ "PetscDLLibraryAppend" 407 /*@C 408 PetscDLLibraryAppend - Appends another dynamic link library to the seach list, to the end 409 of the search path. 410 411 Collective on MPI_Comm 412 413 Input Parameters: 414 + comm - MPI communicator 415 - libname - name of the library 416 417 Output Parameter: 418 . outlist - list of libraries 419 420 Level: developer 421 422 Notes: if library is already in path will not add it. 423 @*/ 424 PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryAppend(MPI_Comm comm,PetscDLLibraryList *outlist,const char libname[]) 425 { 426 PetscDLLibraryList list,prev; 427 void* handle; 428 PetscErrorCode ierr; 429 size_t len; 430 PetscTruth match,dir; 431 char program[PETSC_MAX_PATH_LEN],buf[8*PETSC_MAX_PATH_LEN],*found,*libname1,suffix[16],*s; 432 PetscToken *token; 433 434 PetscFunctionBegin; 435 436 /* is libname a directory? */ 437 ierr = PetscTestDirectory(libname,'r',&dir);CHKERRQ(ierr); 438 if (dir) { 439 ierr = PetscVerboseInfo((0,"PetscDLLibraryAppend:Checking directory %s for dynamic libraries\n",libname));CHKERRQ(ierr); 440 ierr = PetscStrcpy(program,libname);CHKERRQ(ierr); 441 ierr = PetscStrlen(program,&len);CHKERRQ(ierr); 442 if (program[len-1] == '/') { 443 ierr = PetscStrcat(program,"*.");CHKERRQ(ierr); 444 } else { 445 ierr = PetscStrcat(program,"/*.");CHKERRQ(ierr); 446 } 447 ierr = PetscStrcat(program,PETSC_SLSUFFIX);CHKERRQ(ierr); 448 449 ierr = PetscLs(comm,program,buf,8*PETSC_MAX_PATH_LEN,&dir);CHKERRQ(ierr); 450 if (!dir) PetscFunctionReturn(0); 451 found = buf; 452 } else { 453 found = (char*)libname; 454 } 455 ierr = PetscStrcpy(suffix,".");CHKERRQ(ierr); 456 ierr = PetscStrcat(suffix,PETSC_SLSUFFIX);CHKERRQ(ierr); 457 458 ierr = PetscTokenCreate(found,'\n',&token);CHKERRQ(ierr); 459 ierr = PetscTokenFind(token,&libname1);CHKERRQ(ierr); 460 ierr = PetscStrstr(libname1,suffix,&s);CHKERRQ(ierr); 461 if (s) s[0] = 0; 462 while (libname1) { 463 464 /* see if library was already open then we are done */ 465 list = prev = *outlist; 466 match = PETSC_FALSE; 467 while (list) { 468 469 ierr = PetscStrcmp(list->libname,libname1,&match);CHKERRQ(ierr); 470 if (match) break; 471 prev = list; 472 list = list->next; 473 } 474 if (!match) { 475 476 ierr = PetscDLLibraryOpen(comm,libname1,&handle);CHKERRQ(ierr); 477 478 ierr = PetscNew(struct _n_PetscDLLibraryList,&list);CHKERRQ(ierr); 479 list->next = 0; 480 list->handle = handle; 481 ierr = PetscStrcpy(list->libname,libname1);CHKERRQ(ierr); 482 483 if (!*outlist) { 484 *outlist = list; 485 } else { 486 prev->next = list; 487 } 488 ierr = PetscVerboseInfo((0,"PetscDLLibraryAppend:Appending %s to dynamic library search path\n",libname1));CHKERRQ(ierr); 489 } 490 ierr = PetscTokenFind(token,&libname1);CHKERRQ(ierr); 491 if (libname1) { 492 ierr = PetscStrstr(libname1,suffix,&s);CHKERRQ(ierr); 493 if (s) s[0] = 0; 494 } 495 } 496 ierr = PetscTokenDestroy(token);CHKERRQ(ierr); 497 PetscFunctionReturn(0); 498 } 499 500 #undef __FUNCT__ 501 #define __FUNCT__ "PetscDLLibraryPrepend" 502 /*@C 503 PetscDLLibraryPrepend - Add another dynamic library to search for symbols to the beginning of 504 the search path. 505 506 Collective on MPI_Comm 507 508 Input Parameters: 509 + comm - MPI communicator 510 - libname - name of the library 511 512 Output Parameter: 513 . outlist - list of libraries 514 515 Level: developer 516 517 Notes: If library is already in path will remove old reference. 518 519 @*/ 520 PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryPrepend(MPI_Comm comm,PetscDLLibraryList *outlist,const char libname[]) 521 { 522 PetscDLLibraryList list,prev; 523 void* handle; 524 PetscErrorCode ierr; 525 size_t len; 526 PetscTruth match,dir; 527 char program[PETSC_MAX_PATH_LEN],buf[8*PETSC_MAX_PATH_LEN],*found,*libname1,suffix[16],*s; 528 PetscToken *token; 529 530 PetscFunctionBegin; 531 532 /* is libname a directory? */ 533 ierr = PetscTestDirectory(libname,'r',&dir);CHKERRQ(ierr); 534 if (dir) { 535 ierr = PetscVerboseInfo((0,"PetscDLLibraryPrepend:Checking directory %s for dynamic libraries\n",libname));CHKERRQ(ierr); 536 ierr = PetscStrcpy(program,libname);CHKERRQ(ierr); 537 ierr = PetscStrlen(program,&len);CHKERRQ(ierr); 538 if (program[len-1] == '/') { 539 ierr = PetscStrcat(program,"*.");CHKERRQ(ierr); 540 } else { 541 ierr = PetscStrcat(program,"/*.");CHKERRQ(ierr); 542 } 543 ierr = PetscStrcat(program,PETSC_SLSUFFIX);CHKERRQ(ierr); 544 545 ierr = PetscLs(comm,program,buf,8*PETSC_MAX_PATH_LEN,&dir);CHKERRQ(ierr); 546 if (!dir) PetscFunctionReturn(0); 547 found = buf; 548 } else { 549 found = (char*)libname; 550 } 551 552 ierr = PetscStrcpy(suffix,".");CHKERRQ(ierr); 553 ierr = PetscStrcat(suffix,PETSC_SLSUFFIX);CHKERRQ(ierr); 554 555 ierr = PetscTokenCreate(found,'\n',&token);CHKERRQ(ierr); 556 ierr = PetscTokenFind(token,&libname1);CHKERRQ(ierr); 557 ierr = PetscStrstr(libname1,suffix,&s);CHKERRQ(ierr); 558 if (s) s[0] = 0; 559 while (libname1) { 560 /* see if library was already open and move it to the front */ 561 list = *outlist; 562 prev = 0; 563 match = PETSC_FALSE; 564 while (list) { 565 566 ierr = PetscStrcmp(list->libname,libname1,&match);CHKERRQ(ierr); 567 if (match) { 568 if (prev) prev->next = list->next; 569 list->next = *outlist; 570 *outlist = list; 571 break; 572 } 573 prev = list; 574 list = list->next; 575 } 576 if (!match) { 577 /* open the library and add to front of list */ 578 ierr = PetscDLLibraryOpen(comm,libname1,&handle);CHKERRQ(ierr); 579 580 ierr = PetscVerboseInfo((0,"PetscDLLibraryPrepend:Prepending %s to dynamic library search path\n",libname1));CHKERRQ(ierr); 581 582 ierr = PetscNew(struct _n_PetscDLLibraryList,&list);CHKERRQ(ierr); 583 list->handle = handle; 584 list->next = *outlist; 585 ierr = PetscStrcpy(list->libname,libname1);CHKERRQ(ierr); 586 *outlist = list; 587 } 588 ierr = PetscTokenFind(token,&libname1);CHKERRQ(ierr); 589 if (libname1) { 590 ierr = PetscStrstr(libname1,suffix,&s);CHKERRQ(ierr); 591 if (s) s[0] = 0; 592 } 593 } 594 ierr = PetscTokenDestroy(token);CHKERRQ(ierr); 595 PetscFunctionReturn(0); 596 } 597 598 #undef __FUNCT__ 599 #define __FUNCT__ "PetscDLLibraryClose" 600 /*@C 601 PetscDLLibraryClose - Destroys the search path of dynamic libraries and closes the libraries. 602 603 Collective on PetscDLLibrary 604 605 Input Parameter: 606 . next - library list 607 608 Level: developer 609 610 @*/ 611 PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryClose(PetscDLLibraryList next) 612 { 613 PetscDLLibraryList prev; 614 PetscErrorCode ierr; 615 616 PetscFunctionBegin; 617 618 while (next) { 619 prev = next; 620 next = next->next; 621 /* free the space in the prev data-structure */ 622 ierr = PetscFree(prev);CHKERRQ(ierr); 623 } 624 PetscFunctionReturn(0); 625 } 626 627 #undef __FUNCT__ 628 #define __FUNCT__ "PetscDLLibraryCCAAppend" 629 /*@C 630 PetscDLLibraryCCAAppend - Appends another CCA dynamic link library to the seach list, to the end 631 of the search path. 632 633 Collective on MPI_Comm 634 635 Input Parameters: 636 + comm - MPI communicator 637 - libname - name of directory to check 638 639 Output Parameter: 640 . outlist - list of libraries 641 642 Level: developer 643 644 Notes: if library is already in path will not add it. 645 @*/ 646 PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryCCAAppend(MPI_Comm comm,PetscDLLibraryList *outlist,const char dirname[]) 647 { 648 PetscErrorCode ierr; 649 size_t l; 650 PetscTruth dir; 651 char program[PETSC_MAX_PATH_LEN],buf[8*PETSC_MAX_PATH_LEN],*libname1,fbuf[PETSC_MAX_PATH_LEN],*found,suffix[16],*f2; 652 char *func,*funcname,libname[PETSC_MAX_PATH_LEN],*lib; 653 FILE *fp; 654 PetscToken *token1,*token2; 655 656 PetscFunctionBegin; 657 658 /* is dirname a directory? */ 659 ierr = PetscTestDirectory(dirname,'r',&dir);CHKERRQ(ierr); 660 if (!dir) PetscFunctionReturn(0); 661 662 ierr = PetscVerboseInfo((0,"PetscDLLibraryCCAAppend:Checking directory %s for CCA components\n",dirname));CHKERRQ(ierr); 663 ierr = PetscStrcpy(program,dirname);CHKERRQ(ierr); 664 ierr = PetscStrcat(program,"/*.cca");CHKERRQ(ierr); 665 666 ierr = PetscLs(comm,program,buf,8*PETSC_MAX_PATH_LEN,&dir);CHKERRQ(ierr); 667 if (!dir) PetscFunctionReturn(0); 668 669 ierr = PetscStrcpy(suffix,".");CHKERRQ(ierr); 670 ierr = PetscStrcat(suffix,PETSC_SLSUFFIX);CHKERRQ(ierr); 671 ierr = PetscTokenCreate(buf,'\n',&token1);CHKERRQ(ierr); 672 ierr = PetscTokenFind(token1,&libname1);CHKERRQ(ierr); 673 while (libname1) { 674 fp = fopen(libname1,"r"); if (!fp) continue; 675 while ((found = fgets(fbuf,PETSC_MAX_PATH_LEN,fp))) { 676 if (found[0] == '!') continue; 677 ierr = PetscStrstr(found,suffix,&f2);CHKERRQ(ierr); 678 if (f2) { /* found library name */ 679 if (found[0] == '/') { 680 lib = found; 681 } else { 682 ierr = PetscStrcpy(libname,dirname);CHKERRQ(ierr); 683 ierr = PetscStrlen(libname,&l);CHKERRQ(ierr); 684 if (libname[l-1] != '/') {ierr = PetscStrcat(libname,"/");CHKERRQ(ierr);} 685 ierr = PetscStrcat(libname,found);CHKERRQ(ierr); 686 lib = libname; 687 } 688 ierr = PetscDLLibraryAppend(comm,outlist,lib);CHKERRQ(ierr); 689 } else { 690 ierr = PetscVerboseInfo((0,"PetscDLLibraryCCAAppend:CCA Component function and name: %s from %s\n",found,libname1));CHKERRQ(ierr); 691 ierr = PetscTokenCreate(found,' ',&token2);CHKERRQ(ierr); 692 ierr = PetscTokenFind(token2,&func);CHKERRQ(ierr); 693 ierr = PetscTokenFind(token2,&funcname);CHKERRQ(ierr); 694 ierr = PetscFListAdd(&CCAList,funcname,func,PETSC_NULL);CHKERRQ(ierr); 695 ierr = PetscTokenDestroy(token2);CHKERRQ(ierr); 696 } 697 } 698 fclose(fp); 699 ierr = PetscTokenFind(token1,&libname1);CHKERRQ(ierr); 700 } 701 ierr = PetscTokenDestroy(token1);CHKERRQ(ierr); 702 PetscFunctionReturn(0); 703 } 704 705 706 #endif 707 708 709