summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>2003-02-25 15:47:29 +0000
committerwtc%netscape.com <devnull@localhost>2003-02-25 15:47:29 +0000
commit0e99f4ced473a52104da38da724ceb062b83f3d4 (patch)
tree5603872685750d82de2fbdfe6309e77bd95b846a
parenta8d6ec6761ff28903a6bc5aae1d827c519a1a115 (diff)
downloadnspr-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.c154
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;