diff options
author | wtc%netscape.com <devnull@localhost> | 2003-02-25 15:47:29 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2003-02-25 15:47:29 +0000 |
commit | 0e99f4ced473a52104da38da724ceb062b83f3d4 (patch) | |
tree | 5603872685750d82de2fbdfe6309e77bd95b846a | |
parent | a8d6ec6761ff28903a6bc5aae1d827c519a1a115 (diff) | |
download | nspr-hg-0e99f4ced473a52104da38da724ceb062b83f3d4.tar.gz |
Bug 192015: implemented the PR_GetLibraryFilePathname function for OpenVMS.
The patch is contributed by Colin Blakes <colin@theblakes.com>.
NSPRPUB_PRE_4_2_CLIENT_BRANCH
-rw-r--r-- | pr/src/linking/prlink.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/pr/src/linking/prlink.c b/pr/src/linking/prlink.c index ec59bc78..cfad25aa 100644 --- a/pr/src/linking/prlink.c +++ b/pr/src/linking/prlink.c @@ -94,6 +94,70 @@ #define _PR_DEFAULT_LD_FLAGS PR_LD_LAZY +#ifdef VMS +/* These are all require for the PR_GetLibraryFilePathname implementation */ +#include <descrip.h> +#include <dvidef.h> +#include <fibdef.h> +#include <iodef.h> +#include <lib$routines.h> +#include <ssdef.h> +#include <starlet.h> +#include <stsdef.h> +#include <unixlib.h> + +#pragma __nostandard +#pragma __member_alignment __save +#pragma __nomember_alignment +#ifdef __INITIAL_POINTER_SIZE +#pragma __required_pointer_size __save +#pragma __required_pointer_size __short +#endif + +typedef struct _imcb { + struct _imcb *imcb$l_flink; + struct _imcb *imcb$l_blink; + unsigned short int imcb$w_size; + unsigned char imcb$b_type; + char imcb$b_resv_1; + unsigned char imcb$b_access_mode; + unsigned char imcb$b_act_code; + unsigned short int imcb$w_chan; + unsigned int imcb$l_flags; + char imcb$t_image_name [40]; + unsigned int imcb$l_symvec_size; + unsigned __int64 imcb$q_ident; + void *imcb$l_starting_address; + void *imcb$l_end_address; +} IMCB; + +#pragma __member_alignment __restore +#ifdef __INITIAL_POINTER_SIZE +#pragma __required_pointer_size __restore +#endif +#pragma __standard + +typedef struct { + short buflen; + short itmcode; + void *buffer; + void *retlen; +} ITMLST; + +typedef struct { + short cond; + short count; + int rest; +} IOSB; + +typedef unsigned long int ulong_t; + +struct _imcb *IAC$GL_IMAGE_LIST = NULL; + +#define MAX_DEVNAM 64 +#define MAX_FILNAM 255 +#endif /* VMS */ + /* * On these platforms, symbols have a leading '_'. */ @@ -1745,6 +1809,96 @@ PR_GetLibraryFilePathname(const char *name, PRFuncPtr addr) } PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); return NULL; +#elif defined(VMS) + /* Contributed by Colin Blake of HP */ + struct _imcb *icb; + ulong_t status; + char device_name[MAX_DEVNAM]; + int device_name_len; + $DESCRIPTOR (device_name_desc, device_name); + struct fibdef fib; + struct dsc$descriptor_s fib_desc = + { sizeof(struct fibdef), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (char *)&fib } ; + IOSB iosb; + ITMLST devlst[2] = { + {MAX_DEVNAM, DVI$_ALLDEVNAM, device_name, &device_name_len}, + {0,0,0,0}}; + short file_name_len; + char file_name[MAX_FILNAM+1]; + char *result = NULL; + struct dsc$descriptor_s file_name_desc = + { MAX_FILNAM, DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *) &file_name[0] } ; + + /* + ** The address for the process image list could change in future versions + ** of the operating system. 7FFD0688 is valid for V7.2 and V7.3 releases, + ** so we use that for the default, but allow an environment variable + ** (logical name) to override. + */ + if (IAC$GL_IMAGE_LIST == NULL) { + char *p = getenv("MOZILLA_IAC_GL_IMAGE_LIST"); + if (p) + IAC$GL_IMAGE_LIST = (struct _imcb *) strtol(p,NULL,0); + else + IAC$GL_IMAGE_LIST = (struct _imcb *) 0x7FFD0688; + } + + for (icb = IAC$GL_IMAGE_LIST->imcb$l_flink; + icb != IAC$GL_IMAGE_LIST; + icb = icb->imcb$l_flink) { + if (((void *)addr >= icb->imcb$l_starting_address) && + ((void *)addr <= icb->imcb$l_end_address)) { + /* + ** This is the correct image. + ** Get the device name. + */ + status = sys$getdviw(0,icb->imcb$w_chan,0,&devlst,0,0,0,0); + if ($VMS_STATUS_SUCCESS(status)) + device_name_desc.dsc$w_length = device_name_len; + + /* + ** Get the FID. + */ + memset(&fib,0,sizeof(struct fibdef)); + status = sys$qiow(0,icb->imcb$w_chan,IO$_ACCESS,&iosb, + 0,0,&fib_desc,0,0,0,0,0); + + /* + ** If we got the FID, now look up its name (if for some reason + ** we didn't get the device name, this call will fail). + */ + if (($VMS_STATUS_SUCCESS(status)) && ($VMS_STATUS_SUCCESS(iosb.cond))) { + status = lib$fid_to_name ( + &device_name_desc, + &fib.fib$w_fid, + &file_name_desc, + &file_name_len, + 0, 0); + + /* + ** If we succeeded then remove the version number and + ** return a copy of the UNIX format version of the file name. + */ + if ($VMS_STATUS_SUCCESS(status)) { + char *p, *result; + file_name[file_name_len] = 0; + p = strrchr(file_name,';'); + if (p) *p = 0; + p = decc$translate_vms(&file_name[0]); + result = PR_Malloc(strlen(p)+1); + if (result != NULL) { + strcpy(result, p); + } + return result; + } + } + } + } + + /* Didn't find it */ + PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); + return NULL; + #elif defined(HPUX) && defined(USE_HPSHL) shl_t handle; struct shl_descriptor desc; |