Bug 192015: implemented the PR_GetLibraryFilePathname function for OpenVMS.

The patch is contributed by Colin Blakes <colin@theblakes.com>.
This commit is contained in:
wtc%netscape.com 2003-02-25 15:48:58 +00:00
Родитель 8eb4ab55ad
Коммит 2c20c49d49
1 изменённых файлов: 154 добавлений и 0 удалений

Просмотреть файл

@ -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 '_'.
*/
@ -1761,6 +1825,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;