зеркало из https://github.com/mozilla/pjs.git
Bug 456449: Upgraded NSPR to NSPR_HEAD_20090205.
This commit is contained in:
Родитель
2b212f6b17
Коммит
cf84acb225
|
@ -42,3 +42,4 @@
|
|||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
|
|
@ -4242,6 +4242,11 @@ EOF
|
|||
LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
|
||||
|
||||
DLLFLAGS='-OUT:"$@"'
|
||||
if test -n "$MOZ_DEBUG_SYMBOLS"; then
|
||||
OS_LDFLAGS=-DEBUG -DEBUGTYPE:CV
|
||||
OS_DLLFLAGS=-DEBUG -DEBUGTYPE:CV
|
||||
DSO_LDOPTS=-DEBUG -DEBUGTYPE:CV
|
||||
fi
|
||||
_DEBUG_FLAGS=-Zi
|
||||
;;
|
||||
|
||||
|
@ -4541,17 +4546,17 @@ EOF
|
|||
_OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000"
|
||||
ac_safe=`echo "machine/builtins.h" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for machine/builtins.h""... $ac_c" 1>&6
|
||||
echo "configure:4545: checking for machine/builtins.h" >&5
|
||||
echo "configure:4550: checking for machine/builtins.h" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 4550 "configure"
|
||||
#line 4555 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <machine/builtins.h>
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:4555: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:4560: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
rm -rf conftest*
|
||||
|
@ -5081,7 +5086,7 @@ case $target in
|
|||
;;
|
||||
*)
|
||||
echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
|
||||
echo "configure:5085: checking for dlopen in -ldl" >&5
|
||||
echo "configure:5090: checking for dlopen in -ldl" >&5
|
||||
ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
|
||||
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
|
@ -5089,7 +5094,7 @@ else
|
|||
ac_save_LIBS="$LIBS"
|
||||
LIBS="-ldl $LIBS"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 5093 "configure"
|
||||
#line 5098 "configure"
|
||||
#include "confdefs.h"
|
||||
/* Override any gcc2 internal prototype to avoid an error. */
|
||||
/* We use char because int might match the return type of a gcc2
|
||||
|
@ -5100,7 +5105,7 @@ int main() {
|
|||
dlopen()
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:5104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:5109: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_lib_$ac_lib_var=yes"
|
||||
else
|
||||
|
@ -5117,17 +5122,17 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
|
|||
echo "$ac_t""yes" 1>&6
|
||||
ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6
|
||||
echo "configure:5121: checking for dlfcn.h" >&5
|
||||
echo "configure:5126: checking for dlfcn.h" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 5126 "configure"
|
||||
#line 5131 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <dlfcn.h>
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:5131: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:5136: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
rm -rf conftest*
|
||||
|
@ -5160,13 +5165,13 @@ esac
|
|||
|
||||
if test $ac_cv_prog_gcc = yes; then
|
||||
echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
|
||||
echo "configure:5164: checking whether ${CC-cc} needs -traditional" >&5
|
||||
echo "configure:5169: checking whether ${CC-cc} needs -traditional" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
ac_pattern="Autoconf.*'x'"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 5170 "configure"
|
||||
#line 5175 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <sgtty.h>
|
||||
Autoconf TIOCGETP
|
||||
|
@ -5184,7 +5189,7 @@ rm -f conftest*
|
|||
|
||||
if test $ac_cv_prog_gcc_traditional = no; then
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 5188 "configure"
|
||||
#line 5193 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <termio.h>
|
||||
Autoconf TCGETA
|
||||
|
@ -5208,12 +5213,12 @@ fi
|
|||
for ac_func in lchown strerror
|
||||
do
|
||||
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
|
||||
echo "configure:5212: checking for $ac_func" >&5
|
||||
echo "configure:5217: checking for $ac_func" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 5217 "configure"
|
||||
#line 5222 "configure"
|
||||
#include "confdefs.h"
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func(); below. */
|
||||
|
@ -5236,7 +5241,7 @@ $ac_func();
|
|||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:5240: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:5245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func_$ac_func=yes"
|
||||
else
|
||||
|
@ -5277,7 +5282,7 @@ hpux*)
|
|||
if test -z "$GNU_CC"; then
|
||||
|
||||
echo $ac_n "checking for +Olit support""... $ac_c" 1>&6
|
||||
echo "configure:5281: checking for +Olit support" >&5
|
||||
echo "configure:5286: checking for +Olit support" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_hpux_usable_olit_option'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
|
@ -5316,7 +5321,7 @@ darwin*)
|
|||
*)
|
||||
|
||||
echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6
|
||||
echo "configure:5320: checking for pthread_create in -lpthreads" >&5
|
||||
echo "configure:5325: checking for pthread_create in -lpthreads" >&5
|
||||
echo "
|
||||
#include <pthread.h>
|
||||
void *foo(void *v) { return v; }
|
||||
|
@ -5338,7 +5343,7 @@ echo "
|
|||
echo "$ac_t""no" 1>&6
|
||||
|
||||
echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
|
||||
echo "configure:5342: checking for pthread_create in -lpthread" >&5
|
||||
echo "configure:5347: checking for pthread_create in -lpthread" >&5
|
||||
echo "
|
||||
#include <pthread.h>
|
||||
void *foo(void *v) { return v; }
|
||||
|
@ -5360,7 +5365,7 @@ echo "
|
|||
echo "$ac_t""no" 1>&6
|
||||
|
||||
echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6
|
||||
echo "configure:5364: checking for pthread_create in -lc_r" >&5
|
||||
echo "configure:5369: checking for pthread_create in -lc_r" >&5
|
||||
echo "
|
||||
#include <pthread.h>
|
||||
void *foo(void *v) { return v; }
|
||||
|
@ -5382,7 +5387,7 @@ echo "
|
|||
echo "$ac_t""no" 1>&6
|
||||
|
||||
echo $ac_n "checking for pthread_create in -lc""... $ac_c" 1>&6
|
||||
echo "configure:5386: checking for pthread_create in -lc" >&5
|
||||
echo "configure:5391: checking for pthread_create in -lc" >&5
|
||||
echo "
|
||||
#include <pthread.h>
|
||||
void *foo(void *v) { return v; }
|
||||
|
@ -5514,7 +5519,7 @@ if test -n "$USE_PTHREADS"; then
|
|||
rm -f conftest*
|
||||
ac_cv_have_dash_pthread=no
|
||||
echo $ac_n "checking whether ${CC-cc} accepts -pthread""... $ac_c" 1>&6
|
||||
echo "configure:5518: checking whether ${CC-cc} accepts -pthread" >&5
|
||||
echo "configure:5523: checking whether ${CC-cc} accepts -pthread" >&5
|
||||
echo 'int main() { return 0; }' | cat > conftest.c
|
||||
${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1
|
||||
if test $? -eq 0; then
|
||||
|
@ -5537,7 +5542,7 @@ echo "configure:5518: checking whether ${CC-cc} accepts -pthread" >&5
|
|||
ac_cv_have_dash_pthreads=no
|
||||
if test "$ac_cv_have_dash_pthread" = "no"; then
|
||||
echo $ac_n "checking whether ${CC-cc} accepts -pthreads""... $ac_c" 1>&6
|
||||
echo "configure:5541: checking whether ${CC-cc} accepts -pthreads" >&5
|
||||
echo "configure:5546: checking whether ${CC-cc} accepts -pthreads" >&5
|
||||
echo 'int main() { return 0; }' | cat > conftest.c
|
||||
${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1
|
||||
if test $? -eq 0; then
|
||||
|
|
|
@ -1707,6 +1707,11 @@ tools are selected during the Xcode/Developer Tools installation.])
|
|||
LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
|
||||
|
||||
DLLFLAGS='-OUT:"$@"'
|
||||
if test -n "$MOZ_DEBUG_SYMBOLS"; then
|
||||
OS_LDFLAGS=-DEBUG -DEBUGTYPE:CV
|
||||
OS_DLLFLAGS=-DEBUG -DEBUGTYPE:CV
|
||||
DSO_LDOPTS=-DEBUG -DEBUGTYPE:CV
|
||||
fi
|
||||
_DEBUG_FLAGS=-Zi
|
||||
;;
|
||||
|
||||
|
|
|
@ -1,725 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef prmacos_h___
|
||||
#define prmacos_h___
|
||||
|
||||
//
|
||||
// This file contains all changes and additions which need to be made to the NSPR runtime
|
||||
// for the Macintosh platform (specifically the Metrowerks environment). This file should
|
||||
// only be incluced in Macintosh builds.
|
||||
//
|
||||
|
||||
#define PR_DLL_SUFFIX ""
|
||||
#define _PR_LOCAL_THREADS_ONLY
|
||||
#define _PR_NO_PREEMPT 1
|
||||
#define _PR_HAVE_ATOMIC_OPS 1
|
||||
|
||||
#include "prinit.h"
|
||||
#include "prio.h"
|
||||
#include "prlong.h"
|
||||
#include "prlock.h"
|
||||
#include "prcvar.h"
|
||||
#include "prsem.h"
|
||||
#include "prthread.h"
|
||||
#include "prtime.h"
|
||||
#include "prproces.h"
|
||||
|
||||
#if !defined(MAC_NSPR_STANDALONE)
|
||||
#include "macstdlibextras.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <Errors.h>
|
||||
#include <OpenTransport.h>
|
||||
#include <DriverServices.h>
|
||||
|
||||
#define _PR_HAVE_PEEK_BUFFER
|
||||
#define _PR_PEEK_BUFFER_MAX (16 * 1024)
|
||||
#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) 1
|
||||
|
||||
struct _MDProcess {
|
||||
PRInt8 notused;
|
||||
};
|
||||
|
||||
struct _MDThread {
|
||||
jmp_buf jb;
|
||||
int osErrCode;
|
||||
PRLock * asyncIOLock;
|
||||
PRCondVar * asyncIOCVar;
|
||||
PRBool missedIONotify;
|
||||
PRBool missedAsyncNotify;
|
||||
PRBool asyncNotifyPending;
|
||||
};
|
||||
|
||||
struct _MDThreadStack {
|
||||
PRInt8 notused;
|
||||
};
|
||||
|
||||
struct _MDLock {
|
||||
PRInt8 notused;
|
||||
};
|
||||
|
||||
struct _MDCVar {
|
||||
PRInt8 notused;
|
||||
};
|
||||
|
||||
struct _MDSemaphore {
|
||||
PRInt8 notused;
|
||||
};
|
||||
|
||||
struct _MDSegment {
|
||||
PRInt8 notused;
|
||||
};
|
||||
|
||||
struct _MDCPU {
|
||||
AbsoluteTime lastThreadSwitch;
|
||||
AbsoluteTime lastWakeUpProcess;
|
||||
PRBool trackScheduling;
|
||||
};
|
||||
|
||||
typedef struct _MDSocketCallerInfo {
|
||||
PRThread * thread;
|
||||
void * cookie;
|
||||
} _MDSocketCallerInfo;
|
||||
|
||||
struct _MDFileDesc {
|
||||
PRInt32 osfd;
|
||||
PRPackedBool orderlyDisconnect;
|
||||
PRPackedBool readReady;
|
||||
PRPackedBool writeReady;
|
||||
PRPackedBool exceptReady;
|
||||
PRLock * miscLock;
|
||||
|
||||
/* Server sockets: listen bit tells the notifier func what to do */
|
||||
PRBool doListen;
|
||||
|
||||
/* stored error for non-blocking connects, as a Unix-style error code */
|
||||
OTReason disconnectError;
|
||||
|
||||
_MDSocketCallerInfo misc;
|
||||
_MDSocketCallerInfo read;
|
||||
_MDSocketCallerInfo write;
|
||||
};
|
||||
|
||||
/*
|
||||
** Iinitialization Related definitions
|
||||
*/
|
||||
|
||||
#define _MD_EARLY_INIT _MD_EarlyInit
|
||||
#define _MD_FINAL_INIT _MD_FinalInit
|
||||
|
||||
/*
|
||||
** Interrupts Related definitions
|
||||
*/
|
||||
|
||||
#define _MD_GET_INTSOFF() (_pr_intsOff)
|
||||
|
||||
#define _MD_INTSOFF(_is) \
|
||||
PR_BEGIN_MACRO \
|
||||
ENTER_CRITICAL_REGION(); \
|
||||
(_is) = _PR_MD_GET_INTSOFF(); \
|
||||
_PR_MD_SET_INTSOFF(1); \
|
||||
LEAVE_CRITICAL_REGION(); \
|
||||
PR_END_MACRO
|
||||
|
||||
#if TARGET_CARBON
|
||||
extern void _MD_SetIntsOff(PRInt32 ints);
|
||||
#define _MD_SET_INTSOFF(_val) _MD_SetIntsOff(_val)
|
||||
#else /* not TARGET_CARBON */
|
||||
#define _MD_SET_INTSOFF(_val) (_pr_intsOff = _val)
|
||||
#endif /* TARGET_CARBON */
|
||||
|
||||
#define _MD_START_INTERRUPTS _MD_StartInterrupts
|
||||
#define _MD_STOP_INTERRUPTS _MD_StopInterrupts
|
||||
#define _MD_BLOCK_CLOCK_INTERRUPTS()
|
||||
#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
|
||||
#define _MD_DISABLE_CLOCK_INTERRUPTS()
|
||||
#define _MD_ENABLE_CLOCK_INTERRUPTS()
|
||||
|
||||
/*
|
||||
** CPU Related definitions
|
||||
*/
|
||||
|
||||
#define _MD_PAUSE_CPU _MD_PauseCPU
|
||||
#define _MD_CLEANUP_BEFORE_EXIT()
|
||||
#define _MD_EXIT(status) exit(status)
|
||||
#define _MD_INIT_CPUS()
|
||||
#define _MD_INIT_RUNNING_CPU(cpu) _MD_InitRunningCPU(cpu)
|
||||
|
||||
/*
|
||||
** Process Related definitions
|
||||
*/
|
||||
|
||||
extern struct PRProcess * _MD_CreateProcess(
|
||||
const char *path,
|
||||
char *const *argv,
|
||||
char *const *envp,
|
||||
const PRProcessAttr *attr);
|
||||
#define _MD_CREATE_PROCESS _MD_CreateProcess
|
||||
|
||||
extern PRStatus _MD_DetachProcess(PRProcess *process);
|
||||
#define _MD_DETACH_PROCESS _MD_DetachProcess
|
||||
|
||||
extern PRStatus _MD_WaitProcess(PRProcess *process, PRInt32 *exitCode);
|
||||
#define _MD_WAIT_PROCESS _MD_WaitProcess
|
||||
|
||||
extern PRStatus _MD_KillProcess(PRProcess *process);
|
||||
#define _MD_KILL_PROCESS _MD_KillProcess
|
||||
|
||||
/*
|
||||
** Memory Segments Related definitions
|
||||
*/
|
||||
|
||||
#define _MD_INIT_SEGS()
|
||||
|
||||
/*
|
||||
** Thread Stacks Debugging Related definitions
|
||||
*/
|
||||
|
||||
#define _MD_INIT_STACK _MD_InitStack
|
||||
#define _MD_CLEAR_STACK _MD_ClearStack
|
||||
|
||||
/*
|
||||
** Locks Related definitions
|
||||
*/
|
||||
|
||||
#define _MD_INIT_LOCKS()
|
||||
#define _MD_NEW_LOCK(lock) (PR_SUCCESS)
|
||||
#define _MD_FREE_LOCK(lock)
|
||||
#define _MD_LOCK(lock)
|
||||
#define _MD_UNLOCK(lock)
|
||||
|
||||
/*
|
||||
** Thread Related definitions
|
||||
*/
|
||||
|
||||
NSPR_API(PRThread *) PR_GetPrimaryThread();
|
||||
|
||||
#if defined(powerc) || defined(__powerc)
|
||||
#define _MD_GET_PC(_t) (*((PRUint32 *)((_t)->md.jb)))
|
||||
#define _MD_GET_SP(_t) (*((PRUint32 *)((_t)->md.jb) + 2))
|
||||
#define _MD_GET_TOC(_t) (*((PRUint32 *)((_t)->md.jb) + 3))
|
||||
#define INIT_STACKPTR(stackTop) ((unsigned char*)stackTop - 128)
|
||||
#define PR_NUM_GCREGS 70
|
||||
#else
|
||||
#define _MD_GET_PC(_t) (*((PRUint32 *)((_t)->md.jb) + 6))
|
||||
#define _MD_GET_SP(_t) (*((PRUint32 *)((_t)->md.jb) + 12))
|
||||
#define INIT_STACKPTR(stackTop) ((unsigned char*)stackTop - 4)
|
||||
#define PR_NUM_GCREGS 13
|
||||
#endif
|
||||
|
||||
#define _MD_DEFAULT_STACK_SIZE (58 * 1024)
|
||||
#define _MD_MINIMUM_STACK_SIZE (58 * 1024)
|
||||
|
||||
/*
|
||||
** Initialize the thread machine dependent data structure
|
||||
*/
|
||||
extern PRStatus _MD_InitThread(PRThread *thread);
|
||||
#define _MD_INIT_THREAD _MD_InitThread
|
||||
|
||||
/*
|
||||
** Clean-up the thread machine dependent data structure
|
||||
*/
|
||||
#define _MD_CLEAN_THREAD(_thread) \
|
||||
PR_BEGIN_MACRO \
|
||||
PR_DestroyCondVar(_thread->md.asyncIOCVar); \
|
||||
PR_DestroyLock(_thread->md.asyncIOLock); \
|
||||
PR_END_MACRO
|
||||
|
||||
|
||||
/*
|
||||
** Initialize the thread context preparing it to execute _main.
|
||||
** *sp = 0 zeros out the sp for the first stack frame so that
|
||||
** stack walking code can find the top of the stack.
|
||||
*/
|
||||
#if defined(powerc) || defined(__powerc)
|
||||
#define _MD_INIT_CONTEXT(_thread, _sp, _main, _status) \
|
||||
PR_BEGIN_MACRO \
|
||||
unsigned char *sp; \
|
||||
unsigned long *tvect; \
|
||||
long **jb = (_thread)->md.jb; \
|
||||
*((PRBool *)_status) = PR_TRUE; \
|
||||
(void) setjmp(jb); \
|
||||
sp = INIT_STACKPTR(_sp); \
|
||||
*sp = 0; \
|
||||
(_MD_GET_SP(_thread)) = (long) sp; \
|
||||
tvect = (unsigned long *)_main; \
|
||||
(_MD_GET_PC(_thread)) = (int) *tvect; \
|
||||
(_MD_GET_TOC(_thread)) = (int) *(tvect+1); \
|
||||
_thread->no_sched = 0; \
|
||||
PR_END_MACRO
|
||||
#else
|
||||
#define _MD_INIT_CONTEXT(_thread, _sp, _main, _status) \
|
||||
PR_BEGIN_MACRO \
|
||||
unsigned char *sp; \
|
||||
long **jb = (_thread)->md.jb; \
|
||||
*((PRBool *)_status) = PR_TRUE; \
|
||||
(void) setjmp(jb); \
|
||||
sp = INIT_STACKPTR(_sp); \
|
||||
(_MD_GET_SP(_thread)) = (long) sp; \
|
||||
(_MD_GET_PC(_thread)) = (int) _main; \
|
||||
_thread->no_sched = 0; \
|
||||
PR_END_MACRO
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Switch away from the current thread context by saving its state and
|
||||
** calling the thread scheduler. Reload cpu when we come back from the
|
||||
** context switch because it might have changed.
|
||||
*/
|
||||
/* ResetTimer(); before _PR_Schedule() */
|
||||
|
||||
|
||||
#define _MD_SWITCH_CONTEXT(_thread) \
|
||||
PR_BEGIN_MACRO \
|
||||
PR_ASSERT(_thread->no_sched); \
|
||||
if (!setjmp(_thread->md.jb)) { \
|
||||
_MD_SET_LAST_THREAD(_thread); \
|
||||
if (_PR_MD_CURRENT_CPU()->md.trackScheduling) \
|
||||
_PR_MD_CURRENT_CPU()->md.lastThreadSwitch = UpTime(); \
|
||||
_PR_Schedule(); \
|
||||
} else { \
|
||||
PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \
|
||||
_MD_LAST_THREAD()->no_sched = 0; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
/*
|
||||
** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
|
||||
** initialized by _MD_INIT_CONTEXT.
|
||||
*/
|
||||
#define _MD_RESTORE_CONTEXT(_newThread) \
|
||||
PR_BEGIN_MACRO \
|
||||
long **jb = (_newThread)->md.jb; \
|
||||
_MD_SET_CURRENT_THREAD(_newThread); \
|
||||
_newThread->no_sched = 1; \
|
||||
longjmp(jb, 1); \
|
||||
PR_END_MACRO
|
||||
|
||||
|
||||
#define _MD_ERRNO() _MD_CURRENT_THREAD()->md.osErrCode
|
||||
|
||||
extern PRStatus _MD_wait(PRThread *thread, PRIntervalTime timeout);
|
||||
#define _MD_WAIT _MD_wait
|
||||
|
||||
/*
|
||||
** Combined thread model related definitions
|
||||
*/
|
||||
|
||||
#define _MD_CREATE_THREAD(a,b,c,d,e,f) (PR_SUCCESS)
|
||||
#define _MD_WAKEUP_WAITER(a)
|
||||
#define _MD_SET_PRIORITY(a,b)
|
||||
|
||||
/*
|
||||
** File I/O Related definitions
|
||||
*/
|
||||
|
||||
extern PRInt32 _PR_MD_WRITE_SYNC(PRFileDesc *fd, void *buf, PRInt32 amount);
|
||||
#define _PR_MD_WRITE_SYNC _MD_WRITE_SYNC
|
||||
|
||||
struct _MDDir {
|
||||
short ioVRefNum;
|
||||
long ioDirID;
|
||||
short ioFDirIndex;
|
||||
char *currentEntryName;
|
||||
};
|
||||
|
||||
#define PR_DIRECTORY_SEPARATOR '/'
|
||||
#define PR_DIRECTORY_SEPARATOR_STR "/"
|
||||
#define PR_PATH_SEPARATOR ':'
|
||||
#define PR_PATH_SEPARATOR_STR ":"
|
||||
|
||||
typedef enum IOOperation {
|
||||
READ_ASYNC,
|
||||
WRITE_ASYNC
|
||||
} IOOperation;
|
||||
|
||||
|
||||
#define _MD_INIT_IO()
|
||||
|
||||
#define _MD_OPEN _MD_Open
|
||||
#define _MD_OPEN_FILE _MD_Open
|
||||
#define _MD_CLOSE_FILE FSClose
|
||||
#define _MD_READ(fd,buf,amount) ReadWriteProc(fd,buf,amount,READ_ASYNC)
|
||||
#define _MD_WRITE(fd,buf,amount) ReadWriteProc(fd,buf,amount,WRITE_ASYNC)
|
||||
#define _MD_WRITE_SYNC(fd,buf,amount) WriteSyncProc(fd,buf,amount)
|
||||
#define _MD_GET_FILE_ERROR() _PR_MD_CURRENT_THREAD()->md.osErrCode
|
||||
#define _MD_LSEEK _MD_LSeek
|
||||
#define _MD_FSYNC _MD_FSync
|
||||
|
||||
/* to be implemented */
|
||||
#define _MD_LSEEK64(a,b,c) LL_ZERO
|
||||
#define _MD_GETOPENFILEINFO64(fd,info) -1
|
||||
#define _MD_GETFILEINFO64(fd,info) -1
|
||||
|
||||
#define _MD_IOQ_LOCK()
|
||||
#define _MD_IOQ_UNLOCK()
|
||||
|
||||
/*
|
||||
** File Manipulation definitions
|
||||
*/
|
||||
|
||||
#define _MD_RENAME _MD_Rename
|
||||
#define _MD_ACCESS _MD_Access
|
||||
|
||||
#define _MD_GETFILEINFO _MD_GetFileInfo
|
||||
#define _MD_GETOPENFILEINFO _MD_GetOpenFileInfo
|
||||
|
||||
#define _MD_STAT _MD_Stat
|
||||
|
||||
#define _MD_DELETE _MD_Delete
|
||||
|
||||
extern PRStatus _MD_LockFile(PRInt32 osfd);
|
||||
#define _MD_LOCKFILE _MD_LockFile
|
||||
extern PRStatus _MD_TLockFile(PRInt32 osfd);
|
||||
#define _MD_TLOCKFILE _MD_TLockFile
|
||||
extern PRStatus _MD_UnlockFile(PRInt32 osfd);
|
||||
#define _MD_UNLOCKFILE _MD_UnlockFile
|
||||
|
||||
/*
|
||||
** Directory enumeration related definitions
|
||||
*/
|
||||
|
||||
extern PRStatus _MD_OpenDir(struct _MDDir *md,const char *name);
|
||||
#define _MD_OPEN_DIR _MD_OpenDir
|
||||
|
||||
extern char* _MD_ReadDir(struct _MDDir *md,PRIntn flags);
|
||||
#define _MD_READ_DIR _MD_ReadDir
|
||||
|
||||
#define _MD_CLOSE_DIR _MD_CloseDir
|
||||
|
||||
#define _MD_MKDIR _MD_MkDir
|
||||
#define _MD_MAKE_DIR _MD_MkDir
|
||||
#define _MD_RMDIR _MD_Delete
|
||||
|
||||
/*
|
||||
** Pipe I/O Related definitions (not implemented)
|
||||
*/
|
||||
|
||||
#define _MD_PIPEAVAILABLE(fd) -1
|
||||
|
||||
/*
|
||||
** Socket I/O Related definitions
|
||||
*/
|
||||
|
||||
#if UNIVERSAL_INTERFACES_VERSION >= 0x0330
|
||||
/* In Universal Interfaces 3.3 and later, these are enums. */
|
||||
#define IP_TTL IP_TTL
|
||||
#define IP_TOS IP_TOS
|
||||
#define IP_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP
|
||||
#define IP_DROP_MEMBERSHIP IP_DROP_MEMBERSHIP
|
||||
#define IP_MULTICAST_IF IP_MULTICAST_IF
|
||||
#define IP_MULTICAST_TTL IP_MULTICAST_TTL
|
||||
#define IP_MULTICAST_LOOP IP_MULTICAST_LOOP
|
||||
#define TCP_NODELAY TCP_NODELAY
|
||||
#define TCP_MAXSEG TCP_MAXSEG
|
||||
#endif
|
||||
|
||||
#define _MD_SOCKET _MD_socket
|
||||
#define _MD_BIND _MD_bind
|
||||
#define _MD_LISTEN _MD_listen
|
||||
#define _MD_GETSOCKNAME _MD_getsockname
|
||||
|
||||
extern PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
|
||||
#define _MD_GETSOCKOPT _MD_getsockopt
|
||||
|
||||
extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen);
|
||||
#define _MD_SETSOCKOPT _MD_setsockopt
|
||||
|
||||
#define _MD_SOCKETAVAILABLE _MD_socketavailable
|
||||
#define _MD_ACCEPT _MD_accept
|
||||
#define _MD_CONNECT _MD_connect
|
||||
#define _MD_SEND _MD_send
|
||||
#define _MD_RECV _MD_recv
|
||||
#define _MD_CLOSE_SOCKET _MD_closesocket
|
||||
#define _MD_SENDTO _MD_sendto
|
||||
#define _MD_RECVFROM _MD_recvfrom
|
||||
#define _MD_PR_POLL _MD_poll
|
||||
#define _MD_INIT_FILEDESC _MD_initfiledesc
|
||||
#define _MD_FREE_FILEDESC _MD_freefiledesc
|
||||
#define _MD_MAKE_NONBLOCK _MD_makenonblock
|
||||
#define _MD_INIT_FD_INHERITABLE _MD_initfdinheritable
|
||||
#define _MD_QUERY_FD_INHERITABLE _MD_queryfdinheritable
|
||||
|
||||
#define _MD_GET_SOCKET_ERROR() _PR_MD_CURRENT_THREAD()->md.osErrCode
|
||||
|
||||
#define _PR_MD_MAP_SELECT_ERROR(x) (x)
|
||||
/*
|
||||
** Netdb Related definitions
|
||||
*/
|
||||
extern PRStatus _MD_gethostname(char *name, int namelen);
|
||||
#define _MD_GETHOSTNAME _MD_gethostname
|
||||
#define _PR_GET_HOST_ADDR_AS_NAME
|
||||
|
||||
/*
|
||||
XXX _MD_WRITEV, _MD_SHUTDOWN & _MD_GETPEERNAME not done yet!!!
|
||||
*/
|
||||
#define _MD_WRITEV _MD_writev
|
||||
#define _MD_SHUTDOWN _MD_shutdown
|
||||
#define _MD_GETPEERNAME _MD_getpeername
|
||||
|
||||
|
||||
#ifdef OLD_MACSOCK_LIBRARY
|
||||
#define _MD_SOCKET macsock_socket
|
||||
#define _MD_LISTEN macsock_listen
|
||||
#define _MD_SEND(fd,buf,amount,flags,timeout) macsock_send(fd->secret->md.osfd,buf,amount,flags)
|
||||
#define _MD_SENDTO(fd,buf,amount,flags,addr,addrlen,timeout) macsock_sendto(fd->secret->md.osfd,buf,amount,flags,(struct sockaddr *)addr,addrlen)
|
||||
#define _MD_RECV(fd,buf,amount,flags,timeout) macsock_recv(fd->secret->md.osfd,buf,amount,flags)
|
||||
#define _MD_RECVFROM(fd,buf,amount,flags,addr,addrlen,timeout) macsock_recvfrom(fd->secret->md.osfd,buf,amount,flags,(struct sockaddr *)addr,addrlen)
|
||||
#define _MD_CLOSE_SOCKET macsock_close
|
||||
#define _MD_SHUTDOWN(a,b) (0)
|
||||
|
||||
#define _MD_ACCEPT(fd,addr,addrlen,timeout) macsock_accept(fd->secret->md.osfd,(struct sockaddr *)addr,addrlen)
|
||||
#define _MD_CONNECT(fd,name,namelen,timeout) macsock_connect(fd->secret->md.osfd,(struct sockaddr *)name,namelen)
|
||||
#define _MD_BIND(fd,name,namelen) macsock_bind(fd->secret->md.osfd,(struct sockaddr *)name,namelen)
|
||||
#define _MD_GETSOCKNAME(fd,name,namelen) macsock_getsockname(fd->secret->md.osfd,(struct sockaddr *)name,namelen)
|
||||
#define _MD_GETPEERNAME(fd,name,namelen) macsock_getpeername(fd->secret->md.osfd,(struct sockaddr *)name,namelen)
|
||||
#define _MD_GETSOCKOPT(fd,level,optname,optval,optlen) macsock_getsockopt(fd->secret->md.osfd,level,optname,optval,optlen)
|
||||
#define _MD_SETSOCKOPT(fd,level,optname,optval,optlen) macsock_setsockopt(fd->secret->md.osfd,level,optname,optval,optlen)
|
||||
#define _MD_SOCKETAVAILABLE(fd,bytes) macsock_socketavailable(fd->secret->md.osfd,bytes)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Memory Segements Related definitions
|
||||
*/
|
||||
|
||||
#define _MD_INIT_SEGS()
|
||||
#define _MD_ALLOC_SEGMENT _MD_AllocSegment
|
||||
#define _MD_FREE_SEGMENT _MD_FreeSegment
|
||||
|
||||
/*
|
||||
** Time Related definitions
|
||||
*/
|
||||
|
||||
#define _MD_GET_INTERVAL _MD_GetInterval
|
||||
#define _MD_INTERVAL_PER_SEC() PR_MSEC_PER_SEC
|
||||
#define _MD_INTERVAL_INIT()
|
||||
|
||||
/*
|
||||
** Environemnt Related definitions
|
||||
*/
|
||||
|
||||
extern char *_MD_GetEnv(const char *name);
|
||||
#define _MD_GET_ENV _MD_GetEnv
|
||||
|
||||
extern int _MD_PutEnv(const char *variableCopy);
|
||||
#define _MD_PUT_ENV _MD_PutEnv
|
||||
|
||||
/*
|
||||
** Following is old stuff to be looked at.
|
||||
*/
|
||||
|
||||
#define GCPTR
|
||||
#define CALLBACK
|
||||
typedef int (*FARPROC)();
|
||||
|
||||
|
||||
#define MAX_NON_PRIMARY_TIME_SLICES 6
|
||||
|
||||
extern long gTimeSlicesOnNonPrimaryThread;
|
||||
extern struct PRThread *gPrimaryThread;
|
||||
|
||||
// Errors not found in the Mac StdCLib
|
||||
#define EACCES 13 // Permission denied
|
||||
#define ENOENT -43 // No such file or directory
|
||||
#define _OS_INVALID_FD_VALUE -1
|
||||
|
||||
#define STDERR_FILENO 2
|
||||
|
||||
#if !defined(MAC_NSPR_STANDALONE)
|
||||
#define PATH_SEPARATOR ':'
|
||||
#define PATH_SEPARATOR_STR ":"
|
||||
#define DIRECTORY_SEPARATOR '/'
|
||||
#define DIRECTORY_SEPARATOR_STR "/"
|
||||
#endif
|
||||
|
||||
#define UNIX_THIS_DIRECTORY_STR "./"
|
||||
#define UNIX_PARENT_DIRECTORY_STR "../"
|
||||
|
||||
|
||||
// Alias a few names
|
||||
#define getenv PR_GetEnv
|
||||
#define putenv _MD_PutEnv
|
||||
|
||||
#if defined(MAC_NSPR_STANDALONE)
|
||||
typedef unsigned char (*MemoryCacheFlusherProc)(size_t size);
|
||||
typedef void (*PreAllocationHookProc)(void);
|
||||
|
||||
extern char *strdup(const char *source);
|
||||
|
||||
extern void InstallPreAllocationHook(PreAllocationHookProc newHook);
|
||||
extern void InstallMemoryCacheFlusher(MemoryCacheFlusherProc newFlusher);
|
||||
#endif
|
||||
|
||||
extern char *PR_GetDLLSearchPath(void);
|
||||
|
||||
#if defined(MAC_NSPR_STANDALONE)
|
||||
extern int strcmp(const char *str1, const char *str2);
|
||||
extern int strcasecmp(const char *str1, const char *str2);
|
||||
#endif
|
||||
|
||||
extern void MapFullToPartialMacFile(char *);
|
||||
extern char *MapPartialToFullMacFile(const char *);
|
||||
|
||||
extern void ResetTimer(void);
|
||||
extern void PR_PeriodicIdle(void);
|
||||
extern void ActivateTimer(void);
|
||||
extern void DeactivateTimer(void);
|
||||
extern void PR_InitMemory(void);
|
||||
|
||||
extern struct hostent *gethostbyaddr(const void *addr, int addrlen, int type);
|
||||
|
||||
extern short GetVolumeRefNumFromName(const char *);
|
||||
|
||||
#include <stdio.h> // Needed to get FILE typedef
|
||||
extern FILE *_OS_FOPEN(const char *filename, const char *mode);
|
||||
//
|
||||
// Macintosh only private parts.
|
||||
//
|
||||
|
||||
#define dprintTrace ";dprintf;doTrace"
|
||||
#define dprintNoTrace ";dprintf"
|
||||
extern void dprintf(const char *format, ...);
|
||||
|
||||
|
||||
// Entry into the memory system's cache flushing
|
||||
#if defined(MAC_NSPR_STANDALONE)
|
||||
extern PRUint8 CallCacheFlushers(size_t blockSize);
|
||||
#endif
|
||||
|
||||
#if defined(MAC_NSPR_STANDALONE)
|
||||
extern void* reallocSmaller(void* block, size_t newSize);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** PR_GetSystemInfo related definitions
|
||||
*/
|
||||
#define _PR_SI_SYSNAME "MacOS"
|
||||
#define _PR_SI_ARCHITECTURE "PowerPC"
|
||||
|
||||
/*
|
||||
* Memory-mapped files
|
||||
*/
|
||||
|
||||
struct _MDFileMap {
|
||||
PRInt8 unused;
|
||||
};
|
||||
|
||||
extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
|
||||
#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
|
||||
|
||||
extern PRInt32 _MD_GetMemMapAlignment(void);
|
||||
#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
|
||||
|
||||
extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
|
||||
PRUint32 len);
|
||||
#define _MD_MEM_MAP _MD_MemMap
|
||||
|
||||
extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
|
||||
#define _MD_MEM_UNMAP _MD_MemUnmap
|
||||
|
||||
extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
|
||||
#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
|
||||
|
||||
extern void SetLogFileTypeCreator(const char *logFile);
|
||||
extern int _MD_mac_get_nonblocking_connect_error(PRFileDesc* fd);
|
||||
|
||||
|
||||
/*
|
||||
* Critical section support
|
||||
*/
|
||||
|
||||
#define MAC_CRITICAL_REGIONS TARGET_CARBON
|
||||
|
||||
#if MAC_CRITICAL_REGIONS
|
||||
|
||||
extern void InitCriticalRegion();
|
||||
extern void TermCriticalRegion();
|
||||
|
||||
extern void EnterCritialRegion();
|
||||
extern void LeaveCritialRegion();
|
||||
|
||||
#define INIT_CRITICAL_REGION() InitCriticalRegion()
|
||||
#define TERM_CRITICAL_REGION() TermCriticalRegion()
|
||||
|
||||
#define ENTER_CRITICAL_REGION() EnterCritialRegion()
|
||||
#define LEAVE_CRITICAL_REGION() LeaveCritialRegion()
|
||||
|
||||
#else
|
||||
|
||||
#define INIT_CRITICAL_REGION()
|
||||
#define TERM_CRITICAL_REGION()
|
||||
|
||||
#define ENTER_CRITICAL_REGION()
|
||||
#define LEAVE_CRITICAL_REGION()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* CPU Idle support
|
||||
*/
|
||||
|
||||
extern void InitIdleSemaphore();
|
||||
extern void TermIdleSemaphore();
|
||||
|
||||
extern void WaitOnIdleSemaphore();
|
||||
extern void SignalIdleSemaphore();
|
||||
|
||||
|
||||
/*
|
||||
* Atomic operations
|
||||
*/
|
||||
#ifdef _PR_HAVE_ATOMIC_OPS
|
||||
|
||||
extern PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval);
|
||||
|
||||
#define _MD_INIT_ATOMIC()
|
||||
#define _MD_ATOMIC_INCREMENT(val) OTAtomicAdd32(1, (SInt32 *)val)
|
||||
#define _MD_ATOMIC_ADD(ptr, val) OTAtomicAdd32(val, (SInt32 *)ptr)
|
||||
#define _MD_ATOMIC_DECREMENT(val) OTAtomicAdd32(-1, (SInt32 *)val)
|
||||
#define _MD_ATOMIC_SET(val, newval) _MD_AtomicSet(val, newval)
|
||||
|
||||
#endif /* _PR_HAVE_ATOMIC_OPS */
|
||||
|
||||
|
||||
#endif /* prmacos_h___ */
|
|
@ -526,7 +526,7 @@ extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
|
|||
* not emulating anything. Just mapping.
|
||||
*/
|
||||
#define FreeLibrary(x) DosFreeModule((HMODULE)x)
|
||||
#define OutputDebugString(x)
|
||||
#define OutputDebugStringA(x)
|
||||
|
||||
extern int _MD_os2_get_nonblocking_connect_error(int osfd);
|
||||
|
||||
|
|
|
@ -63,10 +63,6 @@ PR_BEGIN_EXTERN_C
|
|||
#error unknown Windows platform
|
||||
#endif
|
||||
|
||||
#elif defined XP_MAC
|
||||
|
||||
#include "_macos.h"
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
|
||||
#if defined(AIX)
|
||||
|
|
|
@ -122,10 +122,6 @@ struct sockaddr_dl;
|
|||
|
||||
#include <winsock.h>
|
||||
|
||||
#elif defined(XP_MAC)
|
||||
|
||||
#include "macsocket.h"
|
||||
|
||||
#else
|
||||
|
||||
#error Unknown platform
|
||||
|
|
|
@ -50,6 +50,10 @@ PRCondVar *_pr_flock_cv;
|
|||
* There are no stdin, stdout, stderr in Windows CE. INVALID_HANDLE_VALUE
|
||||
* should cause all I/O functions on the handle to fail.
|
||||
*/
|
||||
#define STD_INPUT_HANDLE ((DWORD)-10)
|
||||
#define STD_OUTPUT_HANDLE ((DWORD)-11)
|
||||
#define STD_ERROR_HANDLE ((DWORD)-12)
|
||||
|
||||
static HANDLE GetStdHandle(DWORD nStdHandle)
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
|
|
@ -394,8 +394,10 @@ PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file)
|
|||
if (!newLogFile)
|
||||
return PR_FALSE;
|
||||
|
||||
#ifndef WINCE /* _IONBF does not exist in the Windows Mobile 6 SDK. */
|
||||
/* We do buffering ourselves. */
|
||||
setvbuf(newLogFile, NULL, _IONBF, 0);
|
||||
#endif
|
||||
}
|
||||
if (logFile
|
||||
&& logFile != stdout
|
||||
|
|
|
@ -135,193 +135,6 @@ PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
|
|||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#elif defined (XP_MAC)
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
/*
|
||||
* On Mac, local sockets cannot be used, because the networking stack
|
||||
* closes them when the machine goes to sleep. Instead, we'll use a simple
|
||||
* flag.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* PRFilePrivate structure for the NSPR pollable events layer
|
||||
*/
|
||||
typedef struct PRPollableDesc {
|
||||
PRBool gotEvent;
|
||||
PRThread *pollingThread;
|
||||
} PRPollableDesc;
|
||||
|
||||
static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd);
|
||||
|
||||
static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
|
||||
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
|
||||
|
||||
static PRIOMethods _pr_mac_polevt_methods = {
|
||||
PR_DESC_LAYERED,
|
||||
_pr_MacPolEvtClose,
|
||||
(PRReadFN)_PR_InvalidInt,
|
||||
(PRWriteFN)_PR_InvalidInt,
|
||||
(PRAvailableFN)_PR_InvalidInt,
|
||||
(PRAvailable64FN)_PR_InvalidInt64,
|
||||
(PRFsyncFN)_PR_InvalidStatus,
|
||||
(PRSeekFN)_PR_InvalidInt,
|
||||
(PRSeek64FN)_PR_InvalidInt64,
|
||||
(PRFileInfoFN)_PR_InvalidStatus,
|
||||
(PRFileInfo64FN)_PR_InvalidStatus,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
_pr_MacPolEvtPoll,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRGetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRConnectcontinueFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt
|
||||
};
|
||||
|
||||
static PRDescIdentity _pr_mac_polevt_id;
|
||||
static PRCallOnceType _pr_mac_polevt_once_control;
|
||||
static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void);
|
||||
|
||||
static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
|
||||
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
|
||||
{
|
||||
PRPollableDesc *pollDesc = (PRPollableDesc *)fd->secret;
|
||||
PR_ASSERT(pollDesc);
|
||||
|
||||
// set the current thread so that we can wake up the poll thread
|
||||
pollDesc->pollingThread = PR_GetCurrentThread();
|
||||
|
||||
if ((in_flags & PR_POLL_READ) && pollDesc->gotEvent)
|
||||
*out_flags = PR_POLL_READ;
|
||||
else
|
||||
*out_flags = 0;
|
||||
return pollDesc->gotEvent ? 1 : 0;
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void)
|
||||
{
|
||||
_pr_mac_polevt_id = PR_GetUniqueIdentity("NSPR pollable events");
|
||||
if (PR_INVALID_IO_LAYER == _pr_mac_polevt_id) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd)
|
||||
{
|
||||
PRPollableDesc *pollDesc = (PRPollableDesc *)fd->secret;
|
||||
PR_ASSERT(NULL == fd->higher && NULL == fd->lower);
|
||||
PR_ASSERT(pollDesc);
|
||||
PR_DELETE(pollDesc);
|
||||
fd->dtor(fd);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
|
||||
{
|
||||
PRFileDesc *event;
|
||||
PRPollableDesc *pollDesc;
|
||||
|
||||
if (PR_CallOnce(&_pr_mac_polevt_once_control, _pr_MacPolEvtInit) == PR_FAILURE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
event = PR_CreateIOLayerStub(_pr_mac_polevt_id, &_pr_mac_polevt_methods);
|
||||
if (NULL == event) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate an event flag and clear it.
|
||||
*/
|
||||
pollDesc = PR_NEW(PRPollableDesc);
|
||||
if (!pollDesc) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
goto errorExit;
|
||||
}
|
||||
|
||||
pollDesc->gotEvent = PR_FALSE;
|
||||
pollDesc->pollingThread = NULL;
|
||||
|
||||
event->secret = (PRFilePrivate*)pollDesc;
|
||||
return event;
|
||||
|
||||
errorExit:
|
||||
|
||||
if (event) {
|
||||
PR_DELETE(event->secret);
|
||||
event->dtor(event);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
|
||||
{
|
||||
return PR_Close(event);
|
||||
}
|
||||
|
||||
/* from macsockotpt.c. I wish there was a cleaner way */
|
||||
extern void WakeUpNotifiedThread(PRThread *thread, OTResult result);
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
|
||||
{
|
||||
PRPollableDesc *pollDesc = (PRPollableDesc *)event->secret;
|
||||
PR_ASSERT(pollDesc);
|
||||
PR_ASSERT(pollDesc->pollingThread->state != _PR_DEAD_STATE);
|
||||
|
||||
if (pollDesc->pollingThread->state == _PR_DEAD_STATE)
|
||||
return PR_FAILURE;
|
||||
|
||||
pollDesc->gotEvent = PR_TRUE;
|
||||
|
||||
if (pollDesc->pollingThread)
|
||||
WakeUpNotifiedThread(pollDesc->pollingThread, noErr);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
|
||||
{
|
||||
PRPollableDesc *pollDesc = (PRPollableDesc *)event->secret;
|
||||
PRStatus status;
|
||||
PR_ASSERT(pollDesc);
|
||||
|
||||
/*
|
||||
FIXME: Danger Will Robinson!
|
||||
|
||||
The current implementation of PR_WaitForPollableEvent is somewhat
|
||||
bogus; it makes the assumption that, in Mozilla, this will only
|
||||
ever be called when PR_Poll has returned, telling us that an
|
||||
event has been set.
|
||||
*/
|
||||
|
||||
PR_ASSERT(pollDesc->gotEvent);
|
||||
|
||||
status = (pollDesc->gotEvent) ? PR_SUCCESS : PR_FAILURE;
|
||||
pollDesc->gotEvent = PR_FALSE;
|
||||
return status;
|
||||
}
|
||||
|
||||
#else /* VMS */
|
||||
|
||||
/*
|
||||
|
|
|
@ -459,11 +459,6 @@ PRIntervalTime timeout)
|
|||
* of the listening socket. As an optimization, these
|
||||
* platforms can skip the following _PR_MD_MAKE_NONBLOCK
|
||||
* call.
|
||||
*
|
||||
* On Mac, we MUST make this call, because _PR_MD_MAKE_NONBLOCK
|
||||
* (which maps to _MD_makenonblock, see macsockotpt.c)
|
||||
* installs the async notifier routine needed to make blocking
|
||||
* I/O work properly.
|
||||
*/
|
||||
#if !defined(SOLARIS) && !defined(IRIX) && !defined(WINNT)
|
||||
_PR_MD_MAKE_NONBLOCK(fd2);
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#
|
||||
# This is a list of local files which get copied to the mozilla:dist directory
|
||||
#
|
||||
|
||||
MacErrorHandling.h
|
||||
macsocket.h
|
||||
prcpucfg.h
|
|
@ -1,668 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
FILENAME
|
||||
Exceptions.h
|
||||
|
||||
DESCRIPTION
|
||||
A collection of routines and macros to handle assertions and
|
||||
exceptions.
|
||||
|
||||
COPYRIGHT
|
||||
Copyright © Apple Computer, Inc. 1989-1991
|
||||
All rights reserved.
|
||||
|
||||
ROUTINES
|
||||
EXTERNALS
|
||||
dprintf
|
||||
check_dprintf
|
||||
checkpos_dprintf
|
||||
|
||||
MACROS
|
||||
EXTERNALS
|
||||
check
|
||||
ncheck
|
||||
check_action
|
||||
ncheck_action
|
||||
require
|
||||
nrequire
|
||||
require_action
|
||||
nrequire_action
|
||||
resume
|
||||
|
||||
MODIFICATION HISTORY
|
||||
Nov 12 95 BKJ Moved to MetroWerks environment & the NSPR
|
||||
|
||||
NOTE
|
||||
To keep code size down, use these routines and macros with the C
|
||||
compiler option -b2 or -b3. This will eliminate duplicate strings
|
||||
within a procedure.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __MACERRORHANDLING__
|
||||
#define __MACERRORHANDLING__
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
INCLUDES
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include <Types.h>
|
||||
|
||||
/*<FF>*/
|
||||
/*********************************************************************
|
||||
|
||||
CONSTANTS AND CONTROL
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
/*
|
||||
These defines are used to control the amount of information
|
||||
displayed when an assertion fails. DEBUGOFF and WARN will run
|
||||
silently. MIN will simply break into the debugger. ON will break
|
||||
and display the assertion that failed and the exception (for
|
||||
require statements). FULL will also display the source file name
|
||||
and line number. SYM does a SysBreak and is usefull when using a
|
||||
symbolic debugger like SourceBug or SADE. They should be set into
|
||||
DEBUGLEVEL. The default LEVEL is OFF.
|
||||
*/
|
||||
|
||||
#define DEBUGOFF 0
|
||||
#define DEBUGWARN 1
|
||||
#define DEBUGMIN 2
|
||||
#define DEBUGON 3
|
||||
#define DEBUGFULL 4
|
||||
#define DEBUGSYM 6
|
||||
|
||||
#ifndef DEBUGLEVEL
|
||||
#define DEBUGLEVEL DEBUGOFF
|
||||
#endif DEBUGLEVEL
|
||||
|
||||
/*
|
||||
resumeLabel is used to control the insertion of labels for use with
|
||||
the resume macro. If you do not use the resume macro and you wish
|
||||
to have multible exceptions per label then you can add the
|
||||
following define to you source code.
|
||||
|
||||
*/
|
||||
#define resumeLabel(exception) // Multiple exceptions per label
|
||||
// #define resumeLabel(exception) resume_ ## exception: // Single exception per label
|
||||
|
||||
|
||||
/*
|
||||
traceon and debugon are used to test for options
|
||||
*/
|
||||
|
||||
#define traceon ((DEBUGLEVEL > DEBUGWARN) && defined(TRACEON))
|
||||
#define debugon (DEBUGLEVEL > DEBUGWARN)
|
||||
|
||||
/*
|
||||
Add some macros for DEBUGMIN and DEBUGSYM to keep the size down.
|
||||
*/
|
||||
|
||||
#define __DEBUGSMALL ((DEBUGLEVEL == DEBUGMIN) || \
|
||||
(DEBUGLEVEL == DEBUGSYM))
|
||||
|
||||
#if DEBUGLEVEL == DEBUGMIN
|
||||
#define __DebuggerBreak Debugger()
|
||||
#elif DEBUGLEVEL == DEBUGSYM
|
||||
#define __DebuggerBreak SysBreak()
|
||||
#endif
|
||||
|
||||
|
||||
/*<FF>*/
|
||||
/*********************************************************************
|
||||
|
||||
MACRO
|
||||
check(assertion)
|
||||
|
||||
DESCRIPTION
|
||||
If debugging is on then check will test assertion and if it fails
|
||||
break into the debugger. Otherwise check does nothing.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#if __DEBUGSMALL
|
||||
|
||||
#define check(assertion) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else __DebuggerBreak; \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGON
|
||||
|
||||
#define check(assertion) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
dprintf(notrace, "Assertion \"%s\" Failed", #assertion); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGFULL
|
||||
|
||||
#define check(assertion) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
dprintf(notrace, "Assertion \"%s\" Failed\n" \
|
||||
"File: %s\n" \
|
||||
"Line: %d", \
|
||||
#assertion, __FILE__, __LINE__); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define check(assertion)
|
||||
|
||||
#endif
|
||||
|
||||
/*<FF>*/
|
||||
/*********************************************************************
|
||||
|
||||
MACRO
|
||||
ncheck(assertion)
|
||||
|
||||
DESCRIPTION
|
||||
If debugging is on then ncheck will test !assertion and if it fails
|
||||
break into the debugger. Otherwise ncheck does nothing.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#if __DEBUGSMALL
|
||||
|
||||
#define ncheck(assertion) \
|
||||
do { \
|
||||
if (assertion) __DebuggerBreak; \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGON
|
||||
|
||||
#define ncheck(assertion) \
|
||||
do { \
|
||||
void* __privateAssertion = (void*)(assertion); \
|
||||
\
|
||||
if (__privateAssertion) { \
|
||||
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed", \
|
||||
#assertion, __privateAssertion); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGFULL
|
||||
|
||||
#define ncheck(assertion) \
|
||||
do { \
|
||||
void* __privateAssertion = (void*)(assertion); \
|
||||
\
|
||||
if (__privateAssertion) { \
|
||||
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
|
||||
"File: %s\n" \
|
||||
"Line: %d", \
|
||||
#assertion, __privateAssertion, __FILE__, __LINE__); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define ncheck(assertion)
|
||||
|
||||
#endif
|
||||
|
||||
/*<FF>*/
|
||||
/*********************************************************************
|
||||
|
||||
MACRO
|
||||
check_action(assertion, action)
|
||||
|
||||
DESCRIPTION
|
||||
If debugging is on then check_action will test assertion and if it
|
||||
fails break into the debugger then execute action. Otherwise
|
||||
check_action does nothing.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#if __DEBUGSMALL
|
||||
|
||||
#define check_action(assertion, action) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
__DebuggerBreak; \
|
||||
{ action } \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGON
|
||||
|
||||
#define check_action(assertion, action) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
dprintf(notrace, "Assertion \"%s\" Failed", #assertion); \
|
||||
{ action } \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGFULL
|
||||
|
||||
#define check_action(assertion, action) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
dprintf(notrace, "Assertion \"%s\" Failed\n" \
|
||||
"File: %s\n" \
|
||||
"Line: %d", \
|
||||
#assertion, __FILE__, __LINE__); \
|
||||
{ action } \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define check_action(assertion, action)
|
||||
|
||||
#endif
|
||||
|
||||
/*<FF>*/
|
||||
/**************************************************************************************
|
||||
|
||||
MACRO
|
||||
ncheck_action(assertion, action)
|
||||
|
||||
DESCRIPTION
|
||||
If debugging is on then ncheck_action will test !assertion and if
|
||||
it fails break into the debugger then execute action. Otherwise
|
||||
ncheck_action does nothing.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#if __DEBUGSMALL
|
||||
|
||||
#define ncheck_action(assertion, action) \
|
||||
do { \
|
||||
if (assertion) { \
|
||||
__DebuggerBreak; \
|
||||
{ action } \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGON
|
||||
|
||||
#define ncheck_action(assertion, action) \
|
||||
do { \
|
||||
void* __privateAssertion = (void*)(assertion); \
|
||||
\
|
||||
if (__privateAssertion) { \
|
||||
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed", \
|
||||
#assertion, __privateAssertion); \
|
||||
{ action } \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGFULL
|
||||
|
||||
#define ncheck_action(assertion, action) \
|
||||
do { \
|
||||
void* __privateAssertion = (void*)(assertion); \
|
||||
\
|
||||
if (__privateAssertion) { \
|
||||
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
|
||||
"File: %s\n" \
|
||||
"Line: %d", \
|
||||
#assertion, __privateAssertion, __FILE__, __LINE__); \
|
||||
{ action } \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define ncheck_action(assertion, action)
|
||||
|
||||
#endif
|
||||
|
||||
/*<FF>*/
|
||||
/*********************************************************************
|
||||
|
||||
MACRO
|
||||
require(assertion, exception)
|
||||
|
||||
DESCRIPTION
|
||||
require will test assertion and if it fails:
|
||||
break into the debugger if debugging is on.
|
||||
goto exception.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#if __DEBUGSMALL
|
||||
|
||||
#define require(assertion, exception) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
__DebuggerBreak; \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGON
|
||||
|
||||
#define require(assertion, exception) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
dprintf(notrace, "Assertion \"%s\" Failed\n" \
|
||||
"Exception \"%s\" Raised", \
|
||||
#assertion, #exception); \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGFULL
|
||||
|
||||
#define require(assertion, exception) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
dprintf(notrace, "Assertion \"%s\" Failed\n" \
|
||||
"Exception \"%s\" Raised\n" \
|
||||
"File: %s\n" \
|
||||
"Line: %d", \
|
||||
#assertion, #exception, __FILE__, __LINE__); \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define require(assertion, exception) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#endif
|
||||
|
||||
/*<FF>*/
|
||||
/*********************************************************************
|
||||
|
||||
MACRO
|
||||
nrequire(assertion, exception)
|
||||
|
||||
DESCRIPTION
|
||||
nrequire will test !assertion and if it fails:
|
||||
break into the debugger if debugging is on.
|
||||
goto exception.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#if __DEBUGSMALL
|
||||
|
||||
#define nrequire(assertion, exception) \
|
||||
do { \
|
||||
if (assertion) { \
|
||||
DebugStr(); \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGON
|
||||
|
||||
#define nrequire(assertion, exception) \
|
||||
do { \
|
||||
void* __privateAssertion = (void*)(assertion); \
|
||||
\
|
||||
if (__privateAssertion) { \
|
||||
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
|
||||
"Exception \"%s\" Raised", \
|
||||
#assertion, __privateAssertion, #exception); \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGFULL
|
||||
|
||||
#define nrequire(assertion, exception) \
|
||||
do { \
|
||||
void* __privateAssertion = (void*)(assertion); \
|
||||
\
|
||||
if (__privateAssertion) { \
|
||||
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
|
||||
"Exception \"%s\" Raised\n" \
|
||||
"File: %s\n" \
|
||||
"Line: %d", \
|
||||
#assertion, __privateAssertion, #exception, __FILE__, \
|
||||
__LINE__); \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define nrequire(assertion, exception) \
|
||||
do { \
|
||||
if (assertion) { \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#endif
|
||||
|
||||
/*<FF>*/
|
||||
/*********************************************************************
|
||||
|
||||
MACRO
|
||||
require_action(assertion, exception, action)
|
||||
|
||||
DESCRIPTION
|
||||
require_action will test assertion and if it fails:
|
||||
break into the debugger if debugging is on.
|
||||
execute action.
|
||||
goto exception.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#if __DEBUGSMALL
|
||||
|
||||
#define require_action(assertion, exception, action) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
__DebuggerBreak; \
|
||||
{ action } \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGON
|
||||
|
||||
#define require_action(assertion, exception, action) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
dprintf(notrace, "Assertion \"%s\" Failed\n" \
|
||||
"Exception \"%s\" Raised", \
|
||||
#assertion, #exception); \
|
||||
{ action } \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGFULL
|
||||
|
||||
#define require_action(assertion, exception, action) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
dprintf(notrace, "Assertion \"%s\" Failed\n" \
|
||||
"Exception \"%s\" Raised\n" \
|
||||
"File: %s\n" \
|
||||
"Line: %d", \
|
||||
#assertion, #exception, __FILE__, __LINE__); \
|
||||
{ action } \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define require_action(assertion, exception, action) \
|
||||
do { \
|
||||
if (assertion) ; \
|
||||
else { \
|
||||
{ action } \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#endif
|
||||
|
||||
/*<FF>*/
|
||||
/*********************************************************************
|
||||
|
||||
MACRO
|
||||
nrequire_action(assertion, exception, action)
|
||||
|
||||
DESCRIPTION
|
||||
nrequire_action will test !assertion and if it fails:
|
||||
break into the debugger if debugging is on.
|
||||
execute action.
|
||||
goto exception.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#if __DEBUGSMALL
|
||||
|
||||
#define nrequire_action(assertion, exception, action) \
|
||||
do { \
|
||||
if (assertion) { \
|
||||
__DebuggerBreak; \
|
||||
{ action } \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGON
|
||||
|
||||
#define nrequire_action(assertion, exception, action) \
|
||||
do { \
|
||||
void* __privateAssertion = (void*)(assertion); \
|
||||
\
|
||||
if (__privateAssertion) { \
|
||||
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
|
||||
"Exception \"%s\" Raised", \
|
||||
#assertion, __privateAssertion, #exception); \
|
||||
{ action } \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#elif DEBUGLEVEL == DEBUGFULL
|
||||
|
||||
#define nrequire_action(assertion, exception, action) \
|
||||
do { \
|
||||
void* __privateAssertion = (void*)(assertion); \
|
||||
\
|
||||
if (__privateAssertion) { \
|
||||
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
|
||||
"Exception \"%s\" Raised\n" \
|
||||
"File: %s\n" \
|
||||
"Line: %d", \
|
||||
#assertion, __privateAssertion, #exception, __FILE__, \
|
||||
__LINE__); \
|
||||
{ action } \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define nrequire_action(assertion, exception, action) \
|
||||
do { \
|
||||
if (assertion) { \
|
||||
{ action } \
|
||||
goto exception; \
|
||||
resumeLabel(exception); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#endif
|
||||
|
||||
/*<FF>*/
|
||||
/*********************************************************************
|
||||
|
||||
MACRO
|
||||
resume(exception)
|
||||
|
||||
DESCRIPTION
|
||||
resume will resume execution after the n/require/_action statement
|
||||
specified by exception. Resume lables must be on (the default) in
|
||||
order to use resume. If an action form of require was used then the
|
||||
action will not be re-executed.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
#define resume(exception) \
|
||||
do { \
|
||||
goto resume_ ## exception; \
|
||||
} while (false)
|
||||
|
||||
|
||||
/*<FF>*/
|
||||
/********************************************************************/
|
||||
#endif
|
|
@ -1,587 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <Files.h>
|
||||
#include <Errors.h>
|
||||
#include <Folders.h>
|
||||
#include <CodeFragments.h>
|
||||
#include <Aliases.h>
|
||||
#include <Resources.h>
|
||||
|
||||
#include "IterateDirectory.h" /* MoreFiles */
|
||||
|
||||
#include "MacErrorHandling.h"
|
||||
#include "macdll.h"
|
||||
#include "mdmac.h"
|
||||
#include "macio.h"
|
||||
|
||||
#include "primpl.h"
|
||||
#include "plstr.h"
|
||||
|
||||
/*
|
||||
turds used to iterate through the directories looking
|
||||
for the desired library.
|
||||
*/
|
||||
|
||||
struct GetSharedLibraryFilterProcData
|
||||
{
|
||||
Boolean inRecursive;
|
||||
StringPtr inName;
|
||||
|
||||
Boolean outFound;
|
||||
CFragConnectionID outID;
|
||||
Ptr outAddress;
|
||||
OSErr outError;
|
||||
};
|
||||
typedef struct GetSharedLibraryFilterProcData GetSharedLibraryFilterProcData;
|
||||
|
||||
static pascal void
|
||||
GetSharedLibraryFilterProc(const CInfoPBRec* const inCpb, Boolean* inWantQuit, void *inFilterData);
|
||||
|
||||
|
||||
/*
|
||||
NSGetSharedLibrary
|
||||
|
||||
Unfortunately CFM doesn't support user specified loader paths,
|
||||
so we emulate the behavior. Effectively this is a GetSharedLibrary
|
||||
where the loader path is user defined.
|
||||
*/
|
||||
|
||||
OSErr
|
||||
NSGetSharedLibrary(Str255 inLibName, CFragConnectionID* outID, Ptr* outMainAddr)
|
||||
{
|
||||
char* curLibPath;
|
||||
char* freeCurLibPath;
|
||||
OSErr tempErr;
|
||||
Boolean recursive;
|
||||
FSSpec curFolder;
|
||||
GetSharedLibraryFilterProcData filterData;
|
||||
char *endCurLibPath;
|
||||
Boolean done;
|
||||
|
||||
filterData.outFound = false;
|
||||
filterData.outID = (CFragConnectionID)(-1);
|
||||
filterData.outAddress = NULL;
|
||||
filterData.inName = inLibName;
|
||||
|
||||
freeCurLibPath = curLibPath = PR_GetLibraryPath();
|
||||
|
||||
if (curLibPath == NULL)
|
||||
return (cfragNoLibraryErr);
|
||||
|
||||
tempErr = cfragNoLibraryErr;
|
||||
|
||||
do
|
||||
{
|
||||
endCurLibPath = PL_strchr(curLibPath, PR_PATH_SEPARATOR);
|
||||
done = (endCurLibPath == NULL);
|
||||
|
||||
#if 0
|
||||
// we overload the first character of a path if it's :
|
||||
// then we want to recursively search that path
|
||||
// see if path should be recursive
|
||||
if (*curLibPath == ':')
|
||||
{
|
||||
// ':' is an illegal character in the name of a file
|
||||
// if we start any path with this, we want to allow
|
||||
// search recursively
|
||||
curLibPath++;
|
||||
recursive = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
recursive = false;
|
||||
}
|
||||
|
||||
if (!done)
|
||||
*endCurLibPath = '\0'; // NULL terminate the string
|
||||
|
||||
// convert to FSSpec
|
||||
tempErr = ConvertUnixPathToFSSpec(curLibPath, &curFolder);
|
||||
|
||||
// now look in this directory
|
||||
if (noErr == tempErr)
|
||||
{
|
||||
filterData.inRecursive = recursive;
|
||||
FSpIterateDirectory(&curFolder, recursive ? 0 : 1, &GetSharedLibraryFilterProc, &filterData);
|
||||
|
||||
if (filterData.outFound)
|
||||
{
|
||||
*outID = filterData.outID;
|
||||
*outMainAddr = filterData.outAddress;
|
||||
tempErr = noErr;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempErr = cfragNoLibraryErr;
|
||||
}
|
||||
}
|
||||
|
||||
curLibPath = endCurLibPath + 1; // skip to next path (past the '\0');
|
||||
} while (!done);
|
||||
|
||||
free(freeCurLibPath);
|
||||
return (tempErr);
|
||||
}
|
||||
|
||||
|
||||
static Boolean
|
||||
LibInPefContainer(const FSSpec* inSpec, StringPtr inName, UInt32* outCodeOffset, UInt32* outCodeLength);
|
||||
|
||||
|
||||
/*
|
||||
GetSharedLibraryFilterProc
|
||||
|
||||
Callback to FSpIterateDirectory, finds a library with the name matching the
|
||||
data in inFilterData (of type GetSharedLibraryFilterProcData). Forces a quit
|
||||
when a match is found.
|
||||
*/
|
||||
|
||||
static pascal void
|
||||
GetSharedLibraryFilterProc(const CInfoPBRec* const inCpb, Boolean* inWantQuit, void *inFilterData)
|
||||
{
|
||||
GetSharedLibraryFilterProcData* pFilterData = (GetSharedLibraryFilterProcData*) inFilterData;
|
||||
|
||||
if ((inCpb->hFileInfo.ioFlAttrib & (1 << ioDirFlg)) == 0)
|
||||
{
|
||||
FSSpec fragSpec;
|
||||
OSErr tempErr;
|
||||
Str255 errName;
|
||||
Boolean crap;
|
||||
UInt32 codeOffset;
|
||||
UInt32 codeLength;
|
||||
|
||||
// it's a file
|
||||
|
||||
// ¥ fix-me do we really want to allow all 'APPL's' for in which to find this library?
|
||||
switch (inCpb->hFileInfo.ioFlFndrInfo.fdType)
|
||||
{
|
||||
case kCFragLibraryFileType:
|
||||
case 'APPL':
|
||||
tempErr = FSMakeFSSpec(inCpb->hFileInfo.ioVRefNum, inCpb->hFileInfo.ioFlParID, inCpb->hFileInfo.ioNamePtr, &fragSpec);
|
||||
|
||||
// this shouldn't fail
|
||||
if (noErr != tempErr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// resolve an alias if this was one
|
||||
tempErr = ResolveAliasFile(&fragSpec, true, &crap, &crap);
|
||||
|
||||
// if got here we have a shlb (or app-like shlb)
|
||||
if (noErr != tempErr)
|
||||
{
|
||||
// probably couldn't resolve an alias
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// see if this symbol is in this fragment
|
||||
if (LibInPefContainer(&fragSpec, pFilterData->inName, &codeOffset, &codeLength))
|
||||
tempErr = GetDiskFragment(&fragSpec, codeOffset, codeLength, fragSpec.name, kLoadCFrag, &pFilterData->outID, &pFilterData->outAddress, errName);
|
||||
else
|
||||
return;
|
||||
|
||||
// stop if we found a library by that name
|
||||
if (noErr == tempErr)
|
||||
{
|
||||
*inWantQuit = true;
|
||||
pFilterData->outFound = true;
|
||||
pFilterData->outError = tempErr;
|
||||
}
|
||||
}
|
||||
// FSpIterateDirectory will automagically call us for subsequent sub-dirs if necessary
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
LibInPefContainer
|
||||
|
||||
Tell whether library inName is contained it the file pointed to by inSpec.
|
||||
Return the codeOffset and codeLength information, for a subsequent
|
||||
call to GetDiskFragment.
|
||||
*/
|
||||
|
||||
static Boolean
|
||||
LibInPefContainer(const FSSpec* inSpec, StringPtr inName, UInt32* outCodeOffset, UInt32* outCodeLength)
|
||||
{
|
||||
short refNum;
|
||||
CFragResourceHandle hCfrg;
|
||||
CFragResourceMember* pCurItem;
|
||||
UInt32 curLibIndex;
|
||||
Boolean found;
|
||||
|
||||
// asume we didn't find it
|
||||
found = false;
|
||||
|
||||
// open the resource fork, if we can't bail
|
||||
refNum = FSpOpenResFile(inSpec, fsRdPerm);
|
||||
require(-1 != refNum, Exit);
|
||||
|
||||
// grab out the alias record, if it's not there bail
|
||||
hCfrg = (CFragResourceHandle) Get1Resource(kCFragResourceType, kCFragResourceID);
|
||||
require(NULL != hCfrg, CloseResourceAndExit);
|
||||
|
||||
HLock((Handle)hCfrg);
|
||||
|
||||
// get ptr to first item
|
||||
pCurItem = &(*hCfrg)->firstMember;
|
||||
for (curLibIndex = 0; curLibIndex < (*hCfrg)->memberCount; curLibIndex++)
|
||||
{
|
||||
// is this our library?
|
||||
if ((pCurItem->name[0] == inName[0]) &&
|
||||
(strncmp((char*) inName + 1, (char*) pCurItem->name + 1, PR_MIN(pCurItem->name[0], inName[0])) == 0))
|
||||
{
|
||||
*outCodeOffset = pCurItem->offset;
|
||||
*outCodeLength = pCurItem->length;
|
||||
found = true;
|
||||
}
|
||||
|
||||
// skip to next one
|
||||
pCurItem = (CFragResourceMember*) ((char*) pCurItem + pCurItem->memberSize);
|
||||
}
|
||||
|
||||
HUnlock((Handle)hCfrg);
|
||||
|
||||
CloseResourceAndExit:
|
||||
CloseResFile(refNum);
|
||||
Exit:
|
||||
return (found);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
NSFindSymbol
|
||||
|
||||
Workaround bug in CFM FindSymbol (in at least 7.5.5) where symbols with lengths
|
||||
greater than 63 chars cause a "paramErr". We iterate through all symbols
|
||||
in the library to find the desired symbol.
|
||||
*/
|
||||
|
||||
OSErr
|
||||
NSFindSymbol(CFragConnectionID inID, Str255 inSymName, Ptr* outMainAddr, CFragSymbolClass *outSymClass)
|
||||
{
|
||||
OSErr err;
|
||||
|
||||
if (inSymName[0] > 63)
|
||||
{
|
||||
/*
|
||||
if there are greater than 63 characters in the
|
||||
name, CFM FindSymbol fails, so let's iterate through all
|
||||
of the symbols in the fragment and grab it
|
||||
that way.
|
||||
*/
|
||||
long symbolCount;
|
||||
Str255 curSymName;
|
||||
long curIndex;
|
||||
Boolean found;
|
||||
|
||||
found = false;
|
||||
err = CountSymbols(inID, &symbolCount);
|
||||
if (noErr == err)
|
||||
{
|
||||
/* now iterate through all the symbols in the library */
|
||||
/* per DTS the indices apparently go 0 to n-1 */
|
||||
for (curIndex = 0; (curIndex <= symbolCount - 1 && !found); curIndex++)
|
||||
{
|
||||
err = GetIndSymbol(inID, curIndex, curSymName, outMainAddr, outSymClass);
|
||||
if (noErr == err && curSymName[0] == inSymName[0] && !strncmp((char*)curSymName + 1, (char*)inSymName + 1, curSymName[0]))
|
||||
{
|
||||
/* found our symbol */
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we didn't find it set the error code so below it won't take this symbol */
|
||||
if (!found)
|
||||
err = cfragNoSymbolErr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = FindSymbol(inID, inSymName, outMainAddr, outSymClass);
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
|
||||
GetNamedFragmentOffsets
|
||||
|
||||
Get the offsets into the data fork of the named fragment,
|
||||
by reading the 'cfrg' resoruce.
|
||||
|
||||
-----------------------------------------------------------------*/
|
||||
OSErr GetNamedFragmentOffsets(const FSSpec *fileSpec, const char* fragmentName,
|
||||
UInt32 *outOffset, UInt32 *outLength)
|
||||
{
|
||||
CFragResourceHandle cFragHandle;
|
||||
short fileRefNum;
|
||||
OSErr err = noErr;
|
||||
|
||||
fileRefNum = FSpOpenResFile(fileSpec, fsRdPerm);
|
||||
err = ResError();
|
||||
if (err != noErr) return err;
|
||||
|
||||
cFragHandle = (CFragResourceHandle)Get1Resource(kCFragResourceType, kCFragResourceID);
|
||||
if (!cFragHandle)
|
||||
{
|
||||
err = resNotFound;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* nothing here moves memory, so no need to lock the handle */
|
||||
|
||||
err = cfragNoLibraryErr; /* in case of failure */
|
||||
*outOffset = 0;
|
||||
*outLength = 0;
|
||||
|
||||
/* Now look for the named fragment */
|
||||
if ((**cFragHandle).memberCount > 0)
|
||||
{
|
||||
CFragResourceMemberPtr memberPtr;
|
||||
UInt16 i;
|
||||
|
||||
for ( i = 0, memberPtr = &(**cFragHandle).firstMember;
|
||||
i < (**cFragHandle).memberCount;
|
||||
i ++, memberPtr = (CFragResourceMemberPtr)((char *)memberPtr + memberPtr->memberSize))
|
||||
{
|
||||
char memberName[256];
|
||||
UInt16 nameLen = PR_MIN(memberPtr->name[0], 255);
|
||||
|
||||
// avoid malloc here for speed
|
||||
strncpy(memberName, (char *)&memberPtr->name[1], nameLen);
|
||||
memberName[nameLen] = '\0';
|
||||
|
||||
// fragment names are case insensitive, so act like the system
|
||||
if (PL_strcasecmp(memberName, fragmentName) == 0)
|
||||
{
|
||||
*outOffset = memberPtr->offset;
|
||||
*outLength = memberPtr->length;
|
||||
err = noErr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Resource handle will go away when the res fork is closed */
|
||||
|
||||
done:
|
||||
CloseResFile(fileRefNum);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
|
||||
GetIndexedFragmentOffsets
|
||||
|
||||
Get the offsets into the data fork of the indexed fragment,
|
||||
by reading the 'cfrg' resoruce.
|
||||
|
||||
-----------------------------------------------------------------*/
|
||||
OSErr GetIndexedFragmentOffsets(const FSSpec *fileSpec, UInt32 fragmentIndex,
|
||||
UInt32 *outOffset, UInt32 *outLength, char **outFragmentName)
|
||||
{
|
||||
CFragResourceHandle cFragHandle;
|
||||
short fileRefNum;
|
||||
OSErr err = noErr;
|
||||
|
||||
fileRefNum = FSpOpenResFile(fileSpec, fsRdPerm);
|
||||
err = ResError();
|
||||
if (err != noErr) return err;
|
||||
|
||||
cFragHandle = (CFragResourceHandle)Get1Resource(kCFragResourceType, kCFragResourceID);
|
||||
if (!cFragHandle)
|
||||
{
|
||||
err = resNotFound;
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = cfragNoLibraryErr; /* in case of failure */
|
||||
*outOffset = 0;
|
||||
*outLength = 0;
|
||||
*outFragmentName = NULL;
|
||||
|
||||
/* the CStrFromPStr mallocs, so might move memory */
|
||||
HLock((Handle)cFragHandle);
|
||||
|
||||
/* Now look for the named fragment */
|
||||
if ((**cFragHandle).memberCount > 0)
|
||||
{
|
||||
CFragResourceMemberPtr memberPtr;
|
||||
UInt16 i;
|
||||
|
||||
for ( i = 0, memberPtr = &(**cFragHandle).firstMember;
|
||||
i < (**cFragHandle).memberCount;
|
||||
i ++, memberPtr = (CFragResourceMemberPtr)((char *)memberPtr + memberPtr->memberSize))
|
||||
{
|
||||
|
||||
if (i == fragmentIndex)
|
||||
{
|
||||
char *fragmentStr;
|
||||
CStrFromPStr(memberPtr->name, &fragmentStr);
|
||||
if (!fragmentStr) /* test for allocation failure */
|
||||
{
|
||||
err = memFullErr;
|
||||
break;
|
||||
}
|
||||
|
||||
*outFragmentName = fragmentStr;
|
||||
*outOffset = memberPtr->offset;
|
||||
*outLength = memberPtr->length;
|
||||
err = noErr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HUnlock((Handle)cFragHandle);
|
||||
|
||||
/* Resource handle will go away when the res fork is closed */
|
||||
|
||||
done:
|
||||
CloseResFile(fileRefNum);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
|
||||
NSLoadNamedFragment
|
||||
|
||||
Load the named fragment from the specified file. Aliases must
|
||||
have been resolved by this point.
|
||||
|
||||
-----------------------------------------------------------------*/
|
||||
|
||||
OSErr NSLoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName, CFragConnectionID *outConnectionID)
|
||||
{
|
||||
UInt32 fragOffset, fragLength;
|
||||
short fragNameLength;
|
||||
Ptr main;
|
||||
Str255 fragName;
|
||||
Str255 errName;
|
||||
OSErr err;
|
||||
|
||||
err = GetNamedFragmentOffsets(fileSpec, fragmentName, &fragOffset, &fragLength);
|
||||
if (err != noErr) return err;
|
||||
|
||||
// convert fragment name to pascal string
|
||||
fragNameLength = strlen(fragmentName);
|
||||
if (fragNameLength > 255)
|
||||
fragNameLength = 255;
|
||||
BlockMoveData(fragmentName, &fragName[1], fragNameLength);
|
||||
fragName[0] = fragNameLength;
|
||||
|
||||
// Note that we pass the fragment name as the 4th param to GetDiskFragment.
|
||||
// This value affects the ability of debuggers, and the Talkback system,
|
||||
// to match code fragments with symbol files
|
||||
err = GetDiskFragment(fileSpec, fragOffset, fragLength, fragName,
|
||||
kLoadCFrag, outConnectionID, &main, errName);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
|
||||
NSLoadIndexedFragment
|
||||
|
||||
Load the indexed fragment from the specified file. Aliases must
|
||||
have been resolved by this point.
|
||||
|
||||
*outFragName is a malloc'd block containing the fragment name,
|
||||
if returning noErr.
|
||||
|
||||
-----------------------------------------------------------------*/
|
||||
|
||||
OSErr NSLoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragmentIndex,
|
||||
char** outFragName, CFragConnectionID *outConnectionID)
|
||||
{
|
||||
UInt32 fragOffset, fragLength;
|
||||
char *fragNameBlock = NULL;
|
||||
Ptr main;
|
||||
Str255 fragName = "\p";
|
||||
Str255 errName;
|
||||
OSErr err;
|
||||
|
||||
*outFragName = NULL;
|
||||
|
||||
err = GetIndexedFragmentOffsets(fileSpec, fragmentIndex, &fragOffset, &fragLength, &fragNameBlock);
|
||||
if (err != noErr) return err;
|
||||
|
||||
if (fragNameBlock)
|
||||
{
|
||||
UInt32 nameLen = strlen(fragNameBlock);
|
||||
if (nameLen > 63)
|
||||
nameLen = 63;
|
||||
BlockMoveData(fragNameBlock, &fragName[1], nameLen);
|
||||
fragName[0] = nameLen;
|
||||
}
|
||||
|
||||
// Note that we pass the fragment name as the 4th param to GetDiskFragment.
|
||||
// This value affects the ability of debuggers, and the Talkback system,
|
||||
// to match code fragments with symbol files
|
||||
err = GetDiskFragment(fileSpec, fragOffset, fragLength, fragName,
|
||||
kLoadCFrag, outConnectionID, &main, errName);
|
||||
if (err != noErr)
|
||||
{
|
||||
free(fragNameBlock);
|
||||
return err;
|
||||
}
|
||||
|
||||
*outFragName = fragNameBlock;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef macdll_h__
|
||||
#define macdll_h__
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
OSErr GetNamedFragmentOffsets(const FSSpec *fileSpec, const char* fragmentName,
|
||||
UInt32 *outOffset, UInt32 *outLength);
|
||||
OSErr GetIndexedFragmentOffsets(const FSSpec *fileSpec, UInt32 fragmentIndex,
|
||||
UInt32 *outOffset, UInt32 *outLength, char **outFragmentName);
|
||||
|
||||
OSErr NSLoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName, CFragConnectionID *outConnectionID);
|
||||
OSErr NSLoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragmentIndex,
|
||||
char** outFragName, CFragConnectionID *outConnectionID);
|
||||
|
||||
|
||||
OSErr NSGetSharedLibrary(Str255 inLibName, CFragConnectionID* outID, Ptr* outMainAddr);
|
||||
OSErr NSFindSymbol(CFragConnectionID inID, Str255 inSymName,
|
||||
Ptr* outMainAddr, CFragSymbolClass *outSymClass);
|
||||
|
||||
#endif /* macdll_h__ */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,51 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef macio_h__
|
||||
#define macio_h__
|
||||
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
OSErr ConvertUnixPathToMacPath(const char *, char **);
|
||||
OSErr ConvertUnixPathToFSSpec(const char *unixPath, FSSpec *fileSpec);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
|
||||
#endif /* macio_h__ */
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
/* XXX are all these headers required for a call to TickCount()? */
|
||||
#include <Events.h>
|
||||
#include <OSUtils.h>
|
||||
#include <QDOffscreen.h>
|
||||
#include <PPCToolbox.h>
|
||||
#include <Processes.h>
|
||||
#include <LowMem.h>
|
||||
#include "primpl.h"
|
||||
|
||||
extern PRSize _PR_MD_GetRandomNoise( buf, size )
|
||||
{
|
||||
uint32 c = TickCount();
|
||||
return _pr_CopyLowBits((void *)buf, size, &c, sizeof(c));
|
||||
}
|
|
@ -1,238 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef macksocket_h___
|
||||
#define macksocket_h___
|
||||
|
||||
// macsock.h
|
||||
// Interface visible to xp code
|
||||
// C socket type definitions and routines
|
||||
// from sys/socket.h
|
||||
#include <Files.h>
|
||||
#include <OpenTptInternet.h> // All the internet typedefs
|
||||
#include <utime.h> // For timeval
|
||||
/*
|
||||
* sleep and delay conflict with the same in unistd.h from Metrowerks. OT
|
||||
* defines them as
|
||||
*
|
||||
* extern pascal void OTDelay(UInt32 seconds);
|
||||
* extern pascal void OTIdle(void);
|
||||
*
|
||||
* #define sleep(x) OTDelay(x)
|
||||
* #define delay(x) OTDelay(x)
|
||||
*/
|
||||
|
||||
#undef sleep
|
||||
#undef delay
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "prio.h"
|
||||
|
||||
struct sockaddr {
|
||||
unsigned char sa_len; /* total length */
|
||||
unsigned char sa_family; /* address family */
|
||||
char sa_data[14]; /* actually longer; address value */
|
||||
};
|
||||
|
||||
// from netinet/in.h
|
||||
struct in_addr {
|
||||
unsigned long s_addr;
|
||||
};
|
||||
|
||||
struct sockaddr_in {
|
||||
unsigned char sin_len;
|
||||
unsigned char sin_family; // AF_INET
|
||||
unsigned short sin_port;
|
||||
struct in_addr sin_addr;
|
||||
char sin_zero[8];
|
||||
};
|
||||
|
||||
struct hostent {
|
||||
char *h_name; /* official name of host */
|
||||
char **h_aliases; /* alias list */
|
||||
int h_addrtype; /* host address type */
|
||||
int h_length; /* length of address */
|
||||
char **h_addr_list; /* list of addresses from name server */
|
||||
#define h_addr h_addr_list[0] /* address, for backward compatiblity */
|
||||
};
|
||||
|
||||
// Necessary network defines, found by grepping unix headers when XP code would not compile
|
||||
#define FIONBIO 1
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
#define IPPROTO_TCP INET_TCP // Default TCP protocol
|
||||
#define IPPROTO_UDP INET_UDP // Default UDP protocol
|
||||
#define INADDR_ANY kOTAnyInetAddress
|
||||
#define SOL_SOCKET XTI_GENERIC // Any type of socket
|
||||
#define SO_REUSEADDR IP_REUSEADDR
|
||||
#define SO_BROADCAST IP_BROADCAST
|
||||
#define MSG_PEEK 0x2 // Just look at a message waiting, donÕt actually read it.
|
||||
|
||||
typedef unsigned long u_long;
|
||||
|
||||
/* ldap.h has its own definition of fd_set */
|
||||
/* select support */
|
||||
#if !defined(FD_SET)
|
||||
#define NBBY 8
|
||||
typedef long fd_mask;
|
||||
#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
|
||||
|
||||
#ifndef howmany
|
||||
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||
#endif
|
||||
#define FD_SETSIZE 64
|
||||
typedef struct fd_set{
|
||||
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
|
||||
} fd_set;
|
||||
|
||||
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
|
||||
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
|
||||
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
|
||||
#define FD_ZERO(p) memset (p, 0, sizeof(*(p)))
|
||||
#endif /* !FD_SET */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern unsigned long inet_addr(const char *cp);
|
||||
extern char *inet_ntoa(struct in_addr in);
|
||||
|
||||
inline unsigned long htonl(unsigned long hostlong) {return hostlong;}
|
||||
inline unsigned long ntohl(unsigned long netlong) {return netlong;}
|
||||
inline unsigned short ntohs(unsigned short netshort) {return netshort;}
|
||||
inline unsigned short htons(unsigned short hostshort) {return hostshort;}
|
||||
|
||||
|
||||
// UNIX look-alike routines
|
||||
// They make sure that the arguments passed in are valid, and then
|
||||
//
|
||||
extern struct hostent *macsock_gethostbyaddr(const void *addr, int addrlen, int type);
|
||||
|
||||
extern int macsock_socket(int domain, int type, int protocol);
|
||||
extern int macsock_ioctl(int sID, unsigned int request, void *value);
|
||||
extern int macsock_connect(int sID, struct sockaddr *name, int namelen);
|
||||
extern int macsock_write(int sID, const void *buffer, unsigned buflen);
|
||||
extern int macsock_read(int sID, void *buf, unsigned nbyte);
|
||||
extern int macsock_close(int sID);
|
||||
|
||||
extern int macsock_accept(int sID, struct sockaddr *addr, int *addrlen);
|
||||
extern int macsock_bind(int sID, const struct sockaddr *name, int namelen);
|
||||
extern int macsock_listen(int sID, int backlog);
|
||||
|
||||
extern int macsock_shutdown(int sID, int how);
|
||||
extern int macsock_getpeername(int sID, struct sockaddr *name, int *namelen);
|
||||
extern int macsock_getsockname(int sID, struct sockaddr *name, int *namelen);
|
||||
extern int macsock_getsockopt(int sID, int level, int optname, void *optval,int *optlen);
|
||||
extern int macsock_setsockopt(int sID, int level, int optname, const void *optval,int optlen);
|
||||
extern int macsock_socketavailable(int sID, size_t *bytesAvailable);
|
||||
extern int macsock_dup(int sID);
|
||||
|
||||
extern int macsock_send(int sID, const void *msg, int len, int flags);
|
||||
extern int macsock_sendto(int sID, const void *msg, int len, int flags, struct sockaddr *toAddr, int toLen);
|
||||
extern int macsock_recvfrom(int sID, void *buf, int len, int flags, struct sockaddr *from, int *fromLen);
|
||||
extern int macsock_recv(int sID, void *buf, int len, int flags);
|
||||
|
||||
extern int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
||||
|
||||
|
||||
#define macsock_gethostbyaddr PR_GetHostByAddr
|
||||
#define macsock_socket PR_Socket
|
||||
#define macsock_connect PR_Connect
|
||||
#define macsock_write PR_Write
|
||||
#define macsock_read PR_Read
|
||||
#define macsock_close PR_Close
|
||||
#define macsock_accept PR_Accept
|
||||
#define macsock_bind PR_Bind
|
||||
#define macsock_listen PR_Listen
|
||||
#define macsock_shutdown PR_Shutdown
|
||||
#define macsock_getpeername PR_GetPeerName
|
||||
#define macsock_getsockname PR_GetSockName
|
||||
#define macsock_socketavailable PR_SocketAvailable
|
||||
#define macsock_send PR_Send
|
||||
#define macsock_sendto PR_SendTo
|
||||
#define macsock_recvfrom PR_RecvFrom
|
||||
#define macsock_recv PR_Recv
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
//extern int errno;
|
||||
|
||||
/*
|
||||
macsock_sendmsg
|
||||
macsock_readv
|
||||
macsock_writev
|
||||
*/
|
||||
|
||||
/* New definitions that are not defined in macsock.h in macsock library */
|
||||
struct protoent {
|
||||
char *p_name; /* official protocol name */
|
||||
char **p_aliases; /* alias list */
|
||||
int p_proto; /* protocol # */
|
||||
};
|
||||
|
||||
extern struct protoent *getprotobyname(const char * name);
|
||||
extern struct protoent *getprotobynumber(int number);
|
||||
|
||||
extern int gethostname (char *name, int namelen);
|
||||
extern struct hostent *gethostbyname(const char * name);
|
||||
extern struct hostent *gethostbyaddr(const void *addr, int addrlen, int type);
|
||||
|
||||
#define INADDR_LOOPBACK 0x7F000001
|
||||
|
||||
#define SO_KEEPALIVE TCP_KEEPALIVE
|
||||
#define SO_RCVBUF XTI_RCVBUF
|
||||
#define SO_SNDBUF XTI_SNDBUF
|
||||
#define SO_LINGER XTI_LINGER /* linger on close if data present */
|
||||
|
||||
#define IPPROTO_IP INET_IP
|
||||
|
||||
/* Get/Set sock opt until fixed in NSPR 2.0 */
|
||||
struct linger {
|
||||
int l_onoff; /* option on/off */
|
||||
int l_linger; /* linger time */
|
||||
};
|
||||
|
||||
struct ip_mreq {
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_interface; /* local IP address of interface */
|
||||
};
|
||||
|
||||
#endif /* macksocket_h___ */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,721 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <MacTypes.h>
|
||||
#include <Timer.h>
|
||||
#include <OSUtils.h>
|
||||
#include <Math64.h>
|
||||
#include <LowMem.h>
|
||||
#include <Multiprocessing.h>
|
||||
#include <Gestalt.h>
|
||||
|
||||
#include "mdcriticalregion.h"
|
||||
|
||||
TimerUPP gTimerCallbackUPP = NULL;
|
||||
PRThread * gPrimaryThread = NULL;
|
||||
|
||||
ProcessSerialNumber gApplicationProcess;
|
||||
|
||||
PR_IMPLEMENT(PRThread *) PR_GetPrimaryThread()
|
||||
{
|
||||
return gPrimaryThread;
|
||||
}
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark CREATING MACINTOSH THREAD STACKS
|
||||
|
||||
#if defined(GC_LEAK_DETECTOR)
|
||||
extern void* GC_malloc_atomic(PRUint32 size);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Allocate a new memory segment. We allocate it from our figment heap. Currently,
|
||||
** it is being used for per thread stack space.
|
||||
**
|
||||
** Return the segment's access rights and size. vaddr is used on Unix platforms to
|
||||
** map an existing address for the segment.
|
||||
*/
|
||||
PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, void *vaddr)
|
||||
{
|
||||
PR_ASSERT(seg != 0);
|
||||
PR_ASSERT(size != 0);
|
||||
PR_ASSERT(vaddr == 0);
|
||||
|
||||
/*
|
||||
** Take the actual memory for the segment out of our Figment heap.
|
||||
*/
|
||||
|
||||
#if defined(GC_LEAK_DETECTOR)
|
||||
seg->vaddr = (char *)GC_malloc_atomic(size);
|
||||
#else
|
||||
seg->vaddr = (char *)malloc(size);
|
||||
#endif
|
||||
|
||||
if (seg->vaddr == NULL) {
|
||||
|
||||
#if DEBUG
|
||||
DebugStr("\p_MD_AllocSegment failed.");
|
||||
#endif
|
||||
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
seg->size = size;
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Free previously allocated memory segment.
|
||||
*/
|
||||
void _MD_FreeSegment(PRSegment *seg)
|
||||
{
|
||||
PR_ASSERT((seg->flags & _PR_SEG_VM) == 0);
|
||||
|
||||
if (seg->vaddr != NULL)
|
||||
free(seg->vaddr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** The thread's stack has been allocated and its fields are already properly filled
|
||||
** in by PR. Perform any debugging related initialization here.
|
||||
**
|
||||
** Put a recognizable pattern so that we can find it from Macsbug.
|
||||
** Put a cookie at the top of the stack so that we can find it from Macsbug.
|
||||
*/
|
||||
void _MD_InitStack(PRThreadStack *ts, int redZoneBytes)
|
||||
{
|
||||
#pragma unused (redZoneBytes)
|
||||
#if DEVELOPER_DEBUG
|
||||
// Put a cookie at the top of the stack so that we can find
|
||||
// it from Macsbug.
|
||||
|
||||
memset(ts->allocBase, 0xDC, ts->stackSize);
|
||||
|
||||
((UInt32 *)ts->stackTop)[-1] = 0xBEEFCAFE;
|
||||
((UInt32 *)ts->stackTop)[-2] = (UInt32)gPrimaryThread;
|
||||
((UInt32 *)ts->stackTop)[-3] = (UInt32)(ts);
|
||||
((UInt32 *)ts->stackBottom)[0] = 0xCAFEBEEF;
|
||||
#else
|
||||
#pragma unused (ts)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void _MD_ClearStack(PRThreadStack *ts)
|
||||
{
|
||||
#if DEVELOPER_DEBUG
|
||||
// Clear out our cookies.
|
||||
|
||||
memset(ts->allocBase, 0xEF, ts->allocSize);
|
||||
((UInt32 *)ts->stackTop)[-1] = 0;
|
||||
((UInt32 *)ts->stackTop)[-2] = 0;
|
||||
((UInt32 *)ts->stackTop)[-3] = 0;
|
||||
((UInt32 *)ts->stackBottom)[0] = 0;
|
||||
#else
|
||||
#pragma unused (ts)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark TIME MANAGER-BASED CLOCK
|
||||
|
||||
// On Mac OS X, it's possible for the application to spend lots of time
|
||||
// in WaitNextEvent, yielding to other applications. Since NSPR threads are
|
||||
// cooperative here, this means that NSPR threads will also get very little
|
||||
// time to run. To kick ourselves out of a WaitNextEvent call when we have
|
||||
// determined that it's time to schedule another thread, the Timer Task
|
||||
// (which fires every 8ms, even when other apps have the CPU) calls WakeUpProcess.
|
||||
// We only want to do this on Mac OS X; the gTimeManagerTaskDoesWUP variable
|
||||
// indicates when we're running on that OS.
|
||||
//
|
||||
// Note that the TimerCallback makes use of gApplicationProcess. We need to
|
||||
// have set this up before the first possible run of the timer task; we do
|
||||
// so in _MD_EarlyInit().
|
||||
static Boolean gTimeManagerTaskDoesWUP;
|
||||
|
||||
static TMTask gTimeManagerTaskElem;
|
||||
|
||||
extern void _MD_IOInterrupt(void);
|
||||
_PRInterruptTable _pr_interruptTable[] = {
|
||||
{ "clock", _PR_MISSED_CLOCK, _PR_ClockInterrupt, },
|
||||
{ "i/o", _PR_MISSED_IO, _MD_IOInterrupt, },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#define kMacTimerInMiliSecs 8L
|
||||
|
||||
pascal void TimerCallback(TMTaskPtr tmTaskPtr)
|
||||
{
|
||||
_PRCPU *cpu = _PR_MD_CURRENT_CPU();
|
||||
PRIntn is;
|
||||
|
||||
if (_PR_MD_GET_INTSOFF()) {
|
||||
cpu->u.missed[cpu->where] |= _PR_MISSED_CLOCK;
|
||||
PrimeTime((QElemPtr)tmTaskPtr, kMacTimerInMiliSecs);
|
||||
return;
|
||||
}
|
||||
|
||||
_PR_INTSOFF(is);
|
||||
|
||||
// And tell nspr that a clock interrupt occured.
|
||||
_PR_ClockInterrupt();
|
||||
|
||||
if ((_PR_RUNQREADYMASK(cpu)) >> ((_PR_MD_CURRENT_THREAD()->priority))) {
|
||||
if (gTimeManagerTaskDoesWUP) {
|
||||
// We only want to call WakeUpProcess if we know that NSPR has managed to switch threads
|
||||
// since the last call, otherwise we end up spewing out WakeUpProcess() calls while the
|
||||
// application is blocking somewhere. This can interfere with events loops other than
|
||||
// our own (see bug 158927).
|
||||
if (UnsignedWideToUInt64(cpu->md.lastThreadSwitch) > UnsignedWideToUInt64(cpu->md.lastWakeUpProcess))
|
||||
{
|
||||
WakeUpProcess(&gApplicationProcess);
|
||||
cpu->md.lastWakeUpProcess = UpTime();
|
||||
}
|
||||
}
|
||||
_PR_SET_RESCHED_FLAG();
|
||||
}
|
||||
|
||||
_PR_FAST_INTSON(is);
|
||||
|
||||
// Reset the clock timer so that we fire again.
|
||||
PrimeTime((QElemPtr)tmTaskPtr, kMacTimerInMiliSecs);
|
||||
}
|
||||
|
||||
|
||||
void _MD_StartInterrupts(void)
|
||||
{
|
||||
gPrimaryThread = _PR_MD_CURRENT_THREAD();
|
||||
|
||||
gTimeManagerTaskDoesWUP = RunningOnOSX();
|
||||
|
||||
if ( !gTimerCallbackUPP )
|
||||
gTimerCallbackUPP = NewTimerUPP(TimerCallback);
|
||||
|
||||
// Fill in the Time Manager queue element
|
||||
|
||||
gTimeManagerTaskElem.tmAddr = (TimerUPP)gTimerCallbackUPP;
|
||||
gTimeManagerTaskElem.tmCount = 0;
|
||||
gTimeManagerTaskElem.tmWakeUp = 0;
|
||||
gTimeManagerTaskElem.tmReserved = 0;
|
||||
|
||||
// Make sure that our time manager task is ready to go.
|
||||
InsTime((QElemPtr)&gTimeManagerTaskElem);
|
||||
|
||||
PrimeTime((QElemPtr)&gTimeManagerTaskElem, kMacTimerInMiliSecs);
|
||||
}
|
||||
|
||||
void _MD_StopInterrupts(void)
|
||||
{
|
||||
if (gTimeManagerTaskElem.tmAddr != NULL) {
|
||||
RmvTime((QElemPtr)&gTimeManagerTaskElem);
|
||||
gTimeManagerTaskElem.tmAddr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define MAX_PAUSE_TIMEOUT_MS 500
|
||||
|
||||
void _MD_PauseCPU(PRIntervalTime timeout)
|
||||
{
|
||||
if (timeout != PR_INTERVAL_NO_WAIT)
|
||||
{
|
||||
// There is a race condition entering the critical section
|
||||
// in AsyncIOCompletion (and probably elsewhere) that can
|
||||
// causes deadlock for the duration of this timeout. To
|
||||
// work around this, use a max 500ms timeout for now.
|
||||
// See bug 99561 for details.
|
||||
if (PR_IntervalToMilliseconds(timeout) > MAX_PAUSE_TIMEOUT_MS)
|
||||
timeout = PR_MillisecondsToInterval(MAX_PAUSE_TIMEOUT_MS);
|
||||
|
||||
WaitOnIdleSemaphore(timeout);
|
||||
(void) _MD_IOInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
void _MD_InitRunningCPU(_PRCPU* cpu)
|
||||
{
|
||||
cpu->md.trackScheduling = RunningOnOSX();
|
||||
if (cpu->md.trackScheduling) {
|
||||
AbsoluteTime zeroTime = {0, 0};
|
||||
cpu->md.lastThreadSwitch = UpTime();
|
||||
cpu->md.lastWakeUpProcess = zeroTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark THREAD SUPPORT FUNCTIONS
|
||||
|
||||
#include <OpenTransport.h> /* for error codes */
|
||||
|
||||
PRStatus _MD_InitThread(PRThread *thread)
|
||||
{
|
||||
thread->md.asyncIOLock = PR_NewLock();
|
||||
PR_ASSERT(thread->md.asyncIOLock != NULL);
|
||||
thread->md.asyncIOCVar = PR_NewCondVar(thread->md.asyncIOLock);
|
||||
PR_ASSERT(thread->md.asyncIOCVar != NULL);
|
||||
|
||||
if (thread->md.asyncIOLock == NULL || thread->md.asyncIOCVar == NULL)
|
||||
return PR_FAILURE;
|
||||
else
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus _MD_wait(PRThread *thread, PRIntervalTime timeout)
|
||||
{
|
||||
#pragma unused (timeout)
|
||||
|
||||
_MD_SWITCH_CONTEXT(thread);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout)
|
||||
{
|
||||
intn is;
|
||||
PRIntervalTime timein = PR_IntervalNow();
|
||||
PRStatus status = PR_SUCCESS;
|
||||
|
||||
// Turn interrupts off to avoid a race over lock ownership with the callback
|
||||
// (which can fire at any time). Interrupts may stay off until we leave
|
||||
// this function, or another NSPR thread turns them back on. They certainly
|
||||
// stay off until PR_WaitCondVar() relinquishes the asyncIOLock lock, which
|
||||
// is what we care about.
|
||||
_PR_INTSOFF(is);
|
||||
PR_Lock(thread->md.asyncIOLock);
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT) {
|
||||
while ((thread->io_pending) && (status == PR_SUCCESS))
|
||||
status = PR_WaitCondVar(thread->md.asyncIOCVar, PR_INTERVAL_NO_TIMEOUT);
|
||||
} else {
|
||||
while ((thread->io_pending) && ((PRIntervalTime)(PR_IntervalNow() - timein) < timeout) && (status == PR_SUCCESS))
|
||||
status = PR_WaitCondVar(thread->md.asyncIOCVar, timeout);
|
||||
}
|
||||
if ((status == PR_FAILURE) && (PR_GetError() == PR_PENDING_INTERRUPT_ERROR)) {
|
||||
thread->md.osErrCode = kEINTRErr;
|
||||
} else if (thread->io_pending) {
|
||||
thread->md.osErrCode = kETIMEDOUTErr;
|
||||
PR_SetError(PR_IO_TIMEOUT_ERROR, kETIMEDOUTErr);
|
||||
}
|
||||
|
||||
thread->io_pending = PR_FALSE;
|
||||
PR_Unlock(thread->md.asyncIOLock);
|
||||
_PR_FAST_INTSON(is);
|
||||
}
|
||||
|
||||
|
||||
void DoneWaitingOnThisThread(PRThread *thread)
|
||||
{
|
||||
intn is;
|
||||
|
||||
PR_ASSERT(thread->md.asyncIOLock->owner == NULL);
|
||||
|
||||
// DoneWaitingOnThisThread() is called from OT notifiers and async file I/O
|
||||
// callbacks that can run at "interrupt" time (Classic Mac OS) or on pthreads
|
||||
// that may run concurrently with the main threads (Mac OS X). They can thus
|
||||
// be called when any NSPR thread is running, or even while NSPR is in a
|
||||
// thread context switch. It is therefore vital that we can guarantee to
|
||||
// be able to get the asyncIOLock without blocking (thus avoiding code
|
||||
// that makes assumptions about the current NSPR thread etc). To achieve
|
||||
// this, we use NSPR interrrupts as a semaphore on the lock; all code
|
||||
// that grabs the lock also disables interrupts for the time the lock
|
||||
// is held. Callers of DoneWaitingOnThisThread() thus have to check whether
|
||||
// interrupts are already off, and, if so, simply set the missed_IO flag on
|
||||
// the CPU rather than calling this function.
|
||||
|
||||
_PR_INTSOFF(is);
|
||||
PR_Lock(thread->md.asyncIOLock);
|
||||
thread->io_pending = PR_FALSE;
|
||||
/* let the waiting thread know that async IO completed */
|
||||
PR_NotifyCondVar(thread->md.asyncIOCVar);
|
||||
PR_Unlock(thread->md.asyncIOLock);
|
||||
_PR_FAST_INTSON(is);
|
||||
}
|
||||
|
||||
|
||||
PR_IMPLEMENT(void) PR_Mac_WaitForAsyncNotify(PRIntervalTime timeout)
|
||||
{
|
||||
intn is;
|
||||
PRIntervalTime timein = PR_IntervalNow();
|
||||
PRStatus status = PR_SUCCESS;
|
||||
PRThread *thread = _PR_MD_CURRENT_THREAD();
|
||||
|
||||
// See commments in WaitOnThisThread()
|
||||
_PR_INTSOFF(is);
|
||||
PR_Lock(thread->md.asyncIOLock);
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT) {
|
||||
while ((!thread->md.asyncNotifyPending) && (status == PR_SUCCESS))
|
||||
status = PR_WaitCondVar(thread->md.asyncIOCVar, PR_INTERVAL_NO_TIMEOUT);
|
||||
} else {
|
||||
while ((!thread->md.asyncNotifyPending) && ((PRIntervalTime)(PR_IntervalNow() - timein) < timeout) && (status == PR_SUCCESS))
|
||||
status = PR_WaitCondVar(thread->md.asyncIOCVar, timeout);
|
||||
}
|
||||
if ((status == PR_FAILURE) && (PR_GetError() == PR_PENDING_INTERRUPT_ERROR)) {
|
||||
thread->md.osErrCode = kEINTRErr;
|
||||
} else if (!thread->md.asyncNotifyPending) {
|
||||
thread->md.osErrCode = kETIMEDOUTErr;
|
||||
PR_SetError(PR_IO_TIMEOUT_ERROR, kETIMEDOUTErr);
|
||||
}
|
||||
thread->md.asyncNotifyPending = PR_FALSE;
|
||||
PR_Unlock(thread->md.asyncIOLock);
|
||||
_PR_FAST_INTSON(is);
|
||||
}
|
||||
|
||||
|
||||
void AsyncNotify(PRThread *thread)
|
||||
{
|
||||
intn is;
|
||||
|
||||
PR_ASSERT(thread->md.asyncIOLock->owner == NULL);
|
||||
|
||||
// See commments in DoneWaitingOnThisThread()
|
||||
_PR_INTSOFF(is);
|
||||
PR_Lock(thread->md.asyncIOLock);
|
||||
thread->md.asyncNotifyPending = PR_TRUE;
|
||||
/* let the waiting thread know that async IO completed */
|
||||
PR_NotifyCondVar(thread->md.asyncIOCVar);
|
||||
PR_Unlock(thread->md.asyncIOLock);
|
||||
_PR_FAST_INTSON(is);
|
||||
}
|
||||
|
||||
|
||||
PR_IMPLEMENT(void) PR_Mac_PostAsyncNotify(PRThread *thread)
|
||||
{
|
||||
_PRCPU * cpu = _PR_MD_CURRENT_CPU();
|
||||
|
||||
if (_PR_MD_GET_INTSOFF()) {
|
||||
thread->md.missedAsyncNotify = PR_TRUE;
|
||||
cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
|
||||
} else {
|
||||
AsyncNotify(thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark PROCESS SUPPORT FUNCTIONS
|
||||
|
||||
PRProcess * _MD_CreateProcess(
|
||||
const char *path,
|
||||
char *const *argv,
|
||||
char *const *envp,
|
||||
const PRProcessAttr *attr)
|
||||
{
|
||||
#pragma unused (path, argv, envp, attr)
|
||||
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRStatus _MD_DetachProcess(PRProcess *process)
|
||||
{
|
||||
#pragma unused (process)
|
||||
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus _MD_WaitProcess(PRProcess *process, PRInt32 *exitCode)
|
||||
{
|
||||
#pragma unused (process, exitCode)
|
||||
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus _MD_KillProcess(PRProcess *process)
|
||||
{
|
||||
#pragma unused (process)
|
||||
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark ATOMIC OPERATIONS
|
||||
|
||||
#ifdef _PR_HAVE_ATOMIC_OPS
|
||||
PRInt32
|
||||
_MD_AtomicSet(PRInt32 *val, PRInt32 newval)
|
||||
{
|
||||
PRInt32 rv;
|
||||
do {
|
||||
rv = *val;
|
||||
} while (!OTCompareAndSwap32(rv, newval, (UInt32*)val));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif // _PR_HAVE_ATOMIC_OPS
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark INTERRUPT SUPPORT
|
||||
|
||||
#if TARGET_CARBON
|
||||
|
||||
/*
|
||||
This critical region support is required for Mac NSPR to work correctly on dual CPU
|
||||
machines on Mac OS X. This note explains why.
|
||||
|
||||
NSPR uses a timer task, and has callbacks for async file I/O and Open Transport
|
||||
whose runtime behaviour differs depending on environment. On "Classic" Mac OS
|
||||
these run at "interrupt" time (OS-level interrupts, that is, not NSPR interrupts),
|
||||
and can thus preempt other code, but they always run to completion.
|
||||
|
||||
On Mac OS X, these are all emulated using MP tasks, which sit atop pthreads. Thus,
|
||||
they can be preempted at any time (and not necessarily run to completion), and can
|
||||
also run *concurrently* with eachother, and with application code, on multiple
|
||||
CPU machines. Note that all NSPR threads are emulated, and all run on the main
|
||||
application MP task.
|
||||
|
||||
We thus have to use MP critical sections to protect data that is shared between
|
||||
the various callbacks and the main MP thread. It so happens that NSPR has this
|
||||
concept of software interrupts, and making interrupt-off times be critical
|
||||
sections works.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Whether to use critical regions. True if running on Mac OS X and later
|
||||
*/
|
||||
|
||||
PRBool gUseCriticalRegions;
|
||||
|
||||
/*
|
||||
Count of the number of times we've entered the critical region.
|
||||
We need this because ENTER_CRITICAL_REGION() will *not* block when
|
||||
called from different NSPR threads (which all run on one MP thread),
|
||||
and we need to ensure that when code turns interrupts back on (by
|
||||
settings _pr_intsOff to 0) we exit the critical section enough times
|
||||
to leave it.
|
||||
*/
|
||||
|
||||
PRInt32 gCriticalRegionEntryCount;
|
||||
|
||||
|
||||
void _MD_SetIntsOff(PRInt32 ints)
|
||||
{
|
||||
ENTER_CRITICAL_REGION();
|
||||
gCriticalRegionEntryCount ++;
|
||||
|
||||
_pr_intsOff = ints;
|
||||
|
||||
if (!ints)
|
||||
{
|
||||
PRInt32 i = gCriticalRegionEntryCount;
|
||||
|
||||
gCriticalRegionEntryCount = 0;
|
||||
for ( ;i > 0; i --) {
|
||||
LEAVE_CRITICAL_REGION();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* TARGET_CARBON */
|
||||
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark CRITICAL REGION SUPPORT
|
||||
|
||||
|
||||
static PRBool RunningOnOSX()
|
||||
{
|
||||
long systemVersion;
|
||||
OSErr err = Gestalt(gestaltSystemVersion, &systemVersion);
|
||||
return (err == noErr) && (systemVersion >= 0x00001000);
|
||||
}
|
||||
|
||||
|
||||
#if MAC_CRITICAL_REGIONS
|
||||
|
||||
MDCriticalRegionID gCriticalRegion;
|
||||
|
||||
void InitCriticalRegion()
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
// we only need to do critical region stuff on Mac OS X
|
||||
gUseCriticalRegions = RunningOnOSX();
|
||||
if (!gUseCriticalRegions) return;
|
||||
|
||||
err = MD_CriticalRegionCreate(&gCriticalRegion);
|
||||
PR_ASSERT(err == noErr);
|
||||
}
|
||||
|
||||
void TermCriticalRegion()
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
if (!gUseCriticalRegions) return;
|
||||
|
||||
err = MD_CriticalRegionDelete(gCriticalRegion);
|
||||
PR_ASSERT(err == noErr);
|
||||
}
|
||||
|
||||
|
||||
void EnterCritialRegion()
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
if (!gUseCriticalRegions) return;
|
||||
|
||||
PR_ASSERT(gCriticalRegion != kInvalidID);
|
||||
|
||||
/* Change to a non-infinite timeout for debugging purposes */
|
||||
err = MD_CriticalRegionEnter(gCriticalRegion, kDurationForever /* 10000 * kDurationMillisecond */ );
|
||||
PR_ASSERT(err == noErr);
|
||||
}
|
||||
|
||||
void LeaveCritialRegion()
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
if (!gUseCriticalRegions) return;
|
||||
|
||||
PR_ASSERT(gCriticalRegion != kInvalidID);
|
||||
|
||||
err = MD_CriticalRegionExit(gCriticalRegion);
|
||||
PR_ASSERT(err == noErr);
|
||||
}
|
||||
|
||||
|
||||
#endif // MAC_CRITICAL_REGIONS
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark IDLE SEMAPHORE SUPPORT
|
||||
|
||||
/*
|
||||
Since the WaitNextEvent() in _MD_PauseCPU() is causing all sorts of
|
||||
headache under Mac OS X we're going to switch to MPWaitOnSemaphore()
|
||||
which should do what we want
|
||||
*/
|
||||
|
||||
#if TARGET_CARBON
|
||||
PRBool gUseIdleSemaphore = PR_FALSE;
|
||||
MPSemaphoreID gIdleSemaphore = NULL;
|
||||
#endif
|
||||
|
||||
void InitIdleSemaphore()
|
||||
{
|
||||
// we only need to do idle semaphore stuff on Mac OS X
|
||||
#if TARGET_CARBON
|
||||
gUseIdleSemaphore = RunningOnOSX();
|
||||
if (gUseIdleSemaphore)
|
||||
{
|
||||
OSStatus err = MPCreateSemaphore(1 /* max value */, 0 /* initial value */, &gIdleSemaphore);
|
||||
PR_ASSERT(err == noErr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void TermIdleSemaphore()
|
||||
{
|
||||
#if TARGET_CARBON
|
||||
if (gUseIdleSemaphore)
|
||||
{
|
||||
OSStatus err = MPDeleteSemaphore(gIdleSemaphore);
|
||||
PR_ASSERT(err == noErr);
|
||||
gUseIdleSemaphore = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void WaitOnIdleSemaphore(PRIntervalTime timeout)
|
||||
{
|
||||
#if TARGET_CARBON
|
||||
if (gUseIdleSemaphore)
|
||||
{
|
||||
OSStatus err = MPWaitOnSemaphore(gIdleSemaphore, kDurationMillisecond * PR_IntervalToMilliseconds(timeout));
|
||||
PR_ASSERT(err == noErr);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
EventRecord theEvent;
|
||||
/*
|
||||
** Calling WaitNextEvent() here is suboptimal. This routine should
|
||||
** pause the process until IO or the timeout occur, yielding time to
|
||||
** other processes on operating systems that require this (Mac OS classic).
|
||||
** WaitNextEvent() may incur too much latency, and has other problems,
|
||||
** such as the potential to drop suspend/resume events.
|
||||
*/
|
||||
(void)WaitNextEvent(nullEvent, &theEvent, 1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SignalIdleSemaphore()
|
||||
{
|
||||
#if TARGET_CARBON
|
||||
if (gUseIdleSemaphore)
|
||||
{
|
||||
// often we won't be waiting on the semaphore here, so ignore any errors
|
||||
(void)MPSignalSemaphore(gIdleSemaphore);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
WakeUpProcess(&gApplicationProcess);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <OSUtils.h>
|
||||
#include <Timer.h>
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
#include "mactime.h"
|
||||
|
||||
unsigned long gJanuaryFirst1970Seconds;
|
||||
|
||||
/*
|
||||
* The geographic location and time zone information of a Mac
|
||||
* are stored in extended parameter RAM. The ReadLocation
|
||||
* produdure uses the geographic location record, MachineLocation,
|
||||
* to read the geographic location and time zone information in
|
||||
* extended parameter RAM.
|
||||
*
|
||||
* Because serial port and SLIP conflict with ReadXPram calls,
|
||||
* we cache the call here.
|
||||
*
|
||||
* Caveat: this caching will give the wrong result if a session
|
||||
* extend across the DST changeover time.
|
||||
*/
|
||||
|
||||
static void MyReadLocation(MachineLocation *loc)
|
||||
{
|
||||
static MachineLocation storedLoc;
|
||||
static Boolean didReadLocation = false;
|
||||
|
||||
if (!didReadLocation) {
|
||||
ReadLocation(&storedLoc);
|
||||
didReadLocation = true;
|
||||
}
|
||||
*loc = storedLoc;
|
||||
}
|
||||
|
||||
static long GMTDelta(void)
|
||||
{
|
||||
MachineLocation loc;
|
||||
long gmtDelta;
|
||||
|
||||
MyReadLocation(&loc);
|
||||
gmtDelta = loc.u.gmtDelta & 0x00ffffff;
|
||||
if (gmtDelta & 0x00800000) { /* test sign extend bit */
|
||||
gmtDelta |= 0xff000000;
|
||||
}
|
||||
return gmtDelta;
|
||||
}
|
||||
|
||||
void MacintoshInitializeTime(void)
|
||||
{
|
||||
/*
|
||||
* The NSPR epoch is midnight, Jan. 1, 1970 GMT.
|
||||
*
|
||||
* At midnight Jan. 1, 1970 GMT, the local time was
|
||||
* midnight Jan. 1, 1970 + GMTDelta().
|
||||
*
|
||||
* Midnight Jan. 1, 1970 is 86400 * (365 * (1970 - 1904) + 17)
|
||||
* = 2082844800 seconds since the Mac epoch.
|
||||
* (There were 17 leap years from 1904 to 1970.)
|
||||
*
|
||||
* So the NSPR epoch is 2082844800 + GMTDelta() seconds since
|
||||
* the Mac epoch. Whew! :-)
|
||||
*/
|
||||
gJanuaryFirst1970Seconds = 2082844800 + GMTDelta();
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------
|
||||
*
|
||||
* PR_Now --
|
||||
*
|
||||
* Returns the current time in microseconds since the epoch.
|
||||
* The epoch is midnight January 1, 1970 GMT.
|
||||
* The implementation is machine dependent. This is the Mac
|
||||
* Implementation.
|
||||
* Cf. time_t time(time_t *tp)
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
PRTime PR_Now(void)
|
||||
{
|
||||
unsigned long currentTime; /* unsigned 32-bit integer, ranging
|
||||
from midnight Jan. 1, 1904 to
|
||||
6:28:15 AM Feb. 6, 2040 */
|
||||
PRTime retVal;
|
||||
int64 usecPerSec;
|
||||
|
||||
/*
|
||||
* Get the current time expressed as the number of seconds
|
||||
* elapsed since the Mac epoch, midnight, Jan. 1, 1904 (local time).
|
||||
* On a Mac, current time accuracy is up to a second.
|
||||
*/
|
||||
GetDateTime(¤tTime);
|
||||
|
||||
/*
|
||||
* Express the current time relative to the NSPR epoch,
|
||||
* midnight, Jan. 1, 1970 GMT.
|
||||
*
|
||||
* At midnight Jan. 1, 1970 GMT, the local time was
|
||||
* midnight Jan. 1, 1970 + GMTDelta().
|
||||
*
|
||||
* Midnight Jan. 1, 1970 is 86400 * (365 * (1970 - 1904) + 17)
|
||||
* = 2082844800 seconds since the Mac epoch.
|
||||
* (There were 17 leap years from 1904 to 1970.)
|
||||
*
|
||||
* So the NSPR epoch is 2082844800 + GMTDelta() seconds since
|
||||
* the Mac epoch. Whew! :-)
|
||||
*/
|
||||
currentTime = currentTime - 2082844800 - GMTDelta();
|
||||
|
||||
/* Convert seconds to microseconds */
|
||||
LL_I2L(usecPerSec, PR_USEC_PER_SEC);
|
||||
LL_I2L(retVal, currentTime);
|
||||
LL_MUL(retVal, retVal, usecPerSec);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* PR_LocalTimeParameters --
|
||||
*
|
||||
* returns the time parameters for the local time zone
|
||||
*
|
||||
* This is the machine-dependent implementation for Mac.
|
||||
*
|
||||
* Caveat: On a Mac, we only know the GMT and DST offsets for
|
||||
* the current time, not for the time in question.
|
||||
* Mac has no support for DST handling.
|
||||
* DST changeover is all manually set by the user.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
PRTimeParameters PR_LocalTimeParameters(const PRExplodedTime *gmt)
|
||||
{
|
||||
#pragma unused (gmt)
|
||||
|
||||
PRTimeParameters retVal;
|
||||
MachineLocation loc;
|
||||
|
||||
MyReadLocation(&loc);
|
||||
|
||||
/*
|
||||
* On a Mac, the GMT value is in seconds east of GMT. For example,
|
||||
* San Francisco is at -28,800 seconds (8 hours * 3600 seconds per hour)
|
||||
* east of GMT. The gmtDelta field is a 3-byte value contained in a
|
||||
* long word, so you must take care to get it properly.
|
||||
*/
|
||||
|
||||
retVal.tp_gmt_offset = loc.u.gmtDelta & 0x00ffffff;
|
||||
if (retVal.tp_gmt_offset & 0x00800000) { /* test sign extend bit */
|
||||
retVal.tp_gmt_offset |= 0xff000000;
|
||||
}
|
||||
|
||||
/*
|
||||
* The daylight saving time value, dlsDelta, is a signed byte
|
||||
* value representing the offset for the hour field -- whether
|
||||
* to add 1 hour, subtract 1 hour, or make no change at all.
|
||||
*/
|
||||
|
||||
if (loc.u.dlsDelta) {
|
||||
retVal.tp_gmt_offset -= 3600;
|
||||
retVal.tp_dst_offset = 3600;
|
||||
} else {
|
||||
retVal.tp_dst_offset = 0;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
PRIntervalTime _MD_GetInterval(void)
|
||||
{
|
||||
PRIntervalTime retVal;
|
||||
PRUint64 upTime, microtomilli;
|
||||
|
||||
/*
|
||||
* Use the Microseconds procedure to obtain the number of
|
||||
* microseconds elapsed since system startup time.
|
||||
*/
|
||||
Microseconds((UnsignedWide *)&upTime);
|
||||
LL_I2L(microtomilli, PR_USEC_PER_MSEC);
|
||||
LL_DIV(upTime, upTime, microtomilli);
|
||||
LL_L2I(retVal, upTime);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
struct tm *Maclocaltime(const time_t * t)
|
||||
{
|
||||
DateTimeRec dtr;
|
||||
MachineLocation loc;
|
||||
time_t macLocal = *t + gJanuaryFirst1970Seconds; /* GMT Mac */
|
||||
static struct tm statictime;
|
||||
static const short monthday[12] =
|
||||
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
||||
|
||||
SecondsToDate(macLocal, &dtr);
|
||||
statictime.tm_sec = dtr.second;
|
||||
statictime.tm_min = dtr.minute;
|
||||
statictime.tm_hour = dtr.hour;
|
||||
statictime.tm_mday = dtr.day;
|
||||
statictime.tm_mon = dtr.month - 1;
|
||||
statictime.tm_year = dtr.year - 1900;
|
||||
statictime.tm_wday = dtr.dayOfWeek - 1;
|
||||
statictime.tm_yday = monthday[statictime.tm_mon]
|
||||
+ statictime.tm_mday - 1;
|
||||
if (2 < statictime.tm_mon && !(statictime.tm_year & 3))
|
||||
++statictime.tm_yday;
|
||||
MyReadLocation(&loc);
|
||||
statictime.tm_isdst = loc.u.dlsDelta;
|
||||
return(&statictime);
|
||||
}
|
||||
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
#ifndef mactime_h__
|
||||
#define mactime_h__
|
||||
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
void MacintoshInitializeTime(void);
|
||||
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
|
||||
#endif /* mactime_h__ */
|
|
@ -1,173 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: NULL; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* George Warner, Apple Computer Inc.
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mdcriticalregion.h"
|
||||
#include <MacErrors.h>
|
||||
|
||||
/*
|
||||
This code is a replacement for MPEnterCriticalRegion/MPLeaveCriticalRegion,
|
||||
which is broken on Mac OS 10.0.x builds, but fixed in 10.1. This code works
|
||||
everywhere.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct MDCriticalRegionData_struct {
|
||||
MPTaskID mMPTaskID; /* Who's in the critical region? */
|
||||
UInt32 mDepthCount; /* How deep? */
|
||||
MPSemaphoreID mMPSemaphoreID; /* ready semaphore */
|
||||
} MDCriticalRegionData, *MDCriticalRegionDataPtr;
|
||||
|
||||
|
||||
OSStatus
|
||||
MD_CriticalRegionCreate(MDCriticalRegionID * outCriticalRegionID)
|
||||
{
|
||||
MDCriticalRegionDataPtr newCriticalRegionPtr;
|
||||
MPSemaphoreID mpSemaphoreID;
|
||||
OSStatus err = noErr;
|
||||
|
||||
if (outCriticalRegionID == NULL)
|
||||
return paramErr;
|
||||
|
||||
*outCriticalRegionID = NULL;
|
||||
|
||||
newCriticalRegionPtr = (MDCriticalRegionDataPtr)MPAllocateAligned(sizeof(MDCriticalRegionData),
|
||||
kMPAllocateDefaultAligned, kMPAllocateClearMask);
|
||||
if (newCriticalRegionPtr == NULL)
|
||||
return memFullErr;
|
||||
|
||||
// Note: this semaphore is pre-fired (ready!)
|
||||
err = MPCreateBinarySemaphore(&mpSemaphoreID);
|
||||
if (err == noErr)
|
||||
{
|
||||
newCriticalRegionPtr->mMPTaskID = kInvalidID;
|
||||
newCriticalRegionPtr->mDepthCount = 0;
|
||||
newCriticalRegionPtr->mMPSemaphoreID = mpSemaphoreID;
|
||||
|
||||
*outCriticalRegionID = (MDCriticalRegionID)newCriticalRegionPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
MPFree((LogicalAddress)newCriticalRegionPtr);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus
|
||||
MD_CriticalRegionDelete(MDCriticalRegionID inCriticalRegionID)
|
||||
{
|
||||
MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
|
||||
OSStatus err = noErr;
|
||||
|
||||
if (criticalRegion == NULL)
|
||||
return paramErr;
|
||||
|
||||
if ((criticalRegion->mMPTaskID != kInvalidID) && (criticalRegion->mDepthCount > 0))
|
||||
return kMPInsufficientResourcesErr;
|
||||
|
||||
if (criticalRegion->mMPSemaphoreID != kInvalidID)
|
||||
err = MPDeleteSemaphore(criticalRegion->mMPSemaphoreID);
|
||||
if (noErr != err) return err;
|
||||
|
||||
criticalRegion->mMPSemaphoreID = kInvalidID;
|
||||
MPFree((LogicalAddress) criticalRegion);
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSStatus
|
||||
MD_CriticalRegionEnter(MDCriticalRegionID inCriticalRegionID, Duration inTimeout)
|
||||
{
|
||||
MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
|
||||
MPTaskID currentTaskID = MPCurrentTaskID();
|
||||
OSStatus err = noErr;
|
||||
|
||||
if (criticalRegion == NULL)
|
||||
return paramErr;
|
||||
|
||||
// if I'm inside the critical region...
|
||||
if (currentTaskID == criticalRegion->mMPTaskID)
|
||||
{
|
||||
// bump my depth
|
||||
criticalRegion->mDepthCount++;
|
||||
// and continue
|
||||
return noErr;
|
||||
}
|
||||
|
||||
// wait for the ready semaphore
|
||||
err = MPWaitOnSemaphore(criticalRegion->mMPSemaphoreID, inTimeout);
|
||||
// we didn't get it. return the error
|
||||
if (noErr != err) return err;
|
||||
|
||||
// we got it!
|
||||
criticalRegion->mMPTaskID = currentTaskID;
|
||||
criticalRegion->mDepthCount = 1;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSStatus
|
||||
MD_CriticalRegionExit(MDCriticalRegionID inCriticalRegionID)
|
||||
{
|
||||
MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
|
||||
MPTaskID currentTaskID = MPCurrentTaskID();
|
||||
OSStatus err = noErr;
|
||||
|
||||
// if we don't own the critical region...
|
||||
if (currentTaskID != criticalRegion->mMPTaskID)
|
||||
return kMPInsufficientResourcesErr;
|
||||
|
||||
// if we aren't at a depth...
|
||||
if (criticalRegion->mDepthCount == 0)
|
||||
return kMPInsufficientResourcesErr;
|
||||
|
||||
// un-bump my depth
|
||||
criticalRegion->mDepthCount--;
|
||||
|
||||
// if we just bottomed out...
|
||||
if (criticalRegion->mDepthCount == 0)
|
||||
{
|
||||
// release ownership of the structure
|
||||
criticalRegion->mMPTaskID = kInvalidID;
|
||||
// and signal the ready semaphore
|
||||
err = MPSignalSemaphore(criticalRegion->mMPSemaphoreID);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* George Warner, Apple Computer Inc.
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef mdcriticalregion_h___
|
||||
#define mdcriticalregion_h___
|
||||
|
||||
|
||||
#ifndef __MULTIPROCESSING__
|
||||
#include <Multiprocessing.h>
|
||||
#endif
|
||||
|
||||
typedef struct OpaqueMDCriticalRegionID* MDCriticalRegionID;
|
||||
|
||||
OSStatus MD_CriticalRegionCreate(MDCriticalRegionID * pMDCriticalRegionID);
|
||||
|
||||
OSStatus MD_CriticalRegionDelete(MDCriticalRegionID pMDCriticalRegionID);
|
||||
|
||||
OSStatus MD_CriticalRegionEnter(MDCriticalRegionID pMDCriticalRegionID, Duration pTimeout);
|
||||
|
||||
OSStatus MD_CriticalRegionExit(MDCriticalRegionID pMDCriticalRegionID);
|
||||
|
||||
#endif /* mdcriticalregion_h___ */
|
||||
|
|
@ -1,776 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <Types.h>
|
||||
#include <Timer.h>
|
||||
#include <Files.h>
|
||||
#include <Errors.h>
|
||||
#include <Folders.h>
|
||||
#include <Gestalt.h>
|
||||
#include <Events.h>
|
||||
#include <Processes.h>
|
||||
#include <TextUtils.h>
|
||||
#include <MixedMode.h>
|
||||
#include <LowMem.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stat.h>
|
||||
#include <stdarg.h>
|
||||
#include <unix.h>
|
||||
|
||||
#include "MacErrorHandling.h"
|
||||
|
||||
#include "primpl.h"
|
||||
#include "prgc.h"
|
||||
|
||||
#include "mactime.h"
|
||||
|
||||
#include "mdmac.h"
|
||||
|
||||
// undefine getenv, so that _MD_GetEnv can call the version in NSStdLib::nsEnvironment.cpp.
|
||||
#undef getenv
|
||||
|
||||
//
|
||||
// Local routines
|
||||
//
|
||||
unsigned char GarbageCollectorCacheFlusher(PRUint32 size);
|
||||
|
||||
extern PRThread *gPrimaryThread;
|
||||
extern ProcessSerialNumber gApplicationProcess; // in macthr.c
|
||||
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark CREATING MACINTOSH THREAD STACKS
|
||||
|
||||
|
||||
enum {
|
||||
uppExitToShellProcInfo = kPascalStackBased,
|
||||
uppStackSpaceProcInfo = kRegisterBased
|
||||
| RESULT_SIZE(SIZE_CODE(sizeof(long)))
|
||||
| REGISTER_RESULT_LOCATION(kRegisterD0)
|
||||
| REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(UInt16)))
|
||||
};
|
||||
|
||||
typedef CALLBACK_API( long , StackSpacePatchPtr )(UInt16 trapNo);
|
||||
typedef REGISTER_UPP_TYPE(StackSpacePatchPtr) StackSpacePatchUPP;
|
||||
|
||||
StackSpacePatchUPP gStackSpacePatchUPP = NULL;
|
||||
UniversalProcPtr gStackSpacePatchCallThru = NULL;
|
||||
long (*gCallOSTrapUniversalProc)(UniversalProcPtr,ProcInfoType,...) = NULL;
|
||||
|
||||
|
||||
pascal long StackSpacePatch(UInt16 trapNo)
|
||||
{
|
||||
char tos;
|
||||
PRThread *thisThread;
|
||||
|
||||
thisThread = PR_GetCurrentThread();
|
||||
|
||||
// If we are the primary thread, then call through to the
|
||||
// good ol' fashion stack space implementation. Otherwise,
|
||||
// compute it by hand.
|
||||
if ((thisThread == gPrimaryThread) ||
|
||||
(&tos < thisThread->stack->stackBottom) ||
|
||||
(&tos > thisThread->stack->stackTop)) {
|
||||
return gCallOSTrapUniversalProc(gStackSpacePatchCallThru, uppStackSpaceProcInfo, trapNo);
|
||||
}
|
||||
else {
|
||||
return &tos - thisThread->stack->stackBottom;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void InstallStackSpacePatch(void)
|
||||
{
|
||||
long systemVersion;
|
||||
OSErr err;
|
||||
CFragConnectionID connID;
|
||||
Str255 errMessage;
|
||||
Ptr interfaceLibAddr;
|
||||
CFragSymbolClass symClass;
|
||||
UniversalProcPtr (*getOSTrapAddressProc)(UInt16);
|
||||
void (*setOSTrapAddressProc)(StackSpacePatchUPP, UInt16);
|
||||
UniversalProcPtr (*newRoutineDescriptorProc)(ProcPtr,ProcInfoType,ISAType);
|
||||
|
||||
|
||||
err = Gestalt(gestaltSystemVersion,&systemVersion);
|
||||
if (systemVersion >= 0x00000A00) // we don't need to patch StackSpace()
|
||||
return;
|
||||
|
||||
// open connection to "InterfaceLib"
|
||||
err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
|
||||
&connID, &interfaceLibAddr, errMessage);
|
||||
PR_ASSERT(err == noErr);
|
||||
if (err != noErr)
|
||||
return;
|
||||
|
||||
// get symbol GetOSTrapAddress
|
||||
err = FindSymbol(connID, "\pGetOSTrapAddress", &(Ptr)getOSTrapAddressProc, &symClass);
|
||||
if (err != noErr)
|
||||
return;
|
||||
|
||||
// get symbol SetOSTrapAddress
|
||||
err = FindSymbol(connID, "\pSetOSTrapAddress", &(Ptr)setOSTrapAddressProc, &symClass);
|
||||
if (err != noErr)
|
||||
return;
|
||||
|
||||
// get symbol NewRoutineDescriptor
|
||||
err = FindSymbol(connID, "\pNewRoutineDescriptor", &(Ptr)newRoutineDescriptorProc, &symClass);
|
||||
if (err != noErr)
|
||||
return;
|
||||
|
||||
// get symbol CallOSTrapUniversalProc
|
||||
err = FindSymbol(connID, "\pCallOSTrapUniversalProc", &(Ptr)gCallOSTrapUniversalProc, &symClass);
|
||||
if (err != noErr)
|
||||
return;
|
||||
|
||||
// get and set trap address for StackSpace (A065)
|
||||
gStackSpacePatchCallThru = getOSTrapAddressProc(0x0065);
|
||||
if (gStackSpacePatchCallThru)
|
||||
{
|
||||
gStackSpacePatchUPP =
|
||||
(StackSpacePatchUPP)newRoutineDescriptorProc((ProcPtr)(StackSpacePatch), uppStackSpaceProcInfo, GetCurrentArchitecture());
|
||||
setOSTrapAddressProc(gStackSpacePatchUPP, 0x0065);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
StackSpace();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark ENVIRONMENT VARIABLES
|
||||
|
||||
|
||||
typedef struct EnvVariable EnvVariable;
|
||||
|
||||
struct EnvVariable {
|
||||
char *variable;
|
||||
char *value;
|
||||
EnvVariable *next;
|
||||
};
|
||||
|
||||
EnvVariable *gEnvironmentVariables = NULL;
|
||||
|
||||
char *_MD_GetEnv(const char *name)
|
||||
{
|
||||
EnvVariable *currentVariable = gEnvironmentVariables;
|
||||
|
||||
while (currentVariable) {
|
||||
if (!strcmp(currentVariable->variable, name))
|
||||
return currentVariable->value;
|
||||
|
||||
currentVariable = currentVariable->next;
|
||||
}
|
||||
|
||||
return getenv(name);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(int)
|
||||
_MD_PutEnv(const char *string)
|
||||
{
|
||||
EnvVariable *currentVariable = gEnvironmentVariables;
|
||||
char *variableCopy,
|
||||
*value,
|
||||
*current;
|
||||
|
||||
variableCopy = strdup(string);
|
||||
PR_ASSERT(variableCopy != NULL);
|
||||
|
||||
current = variableCopy;
|
||||
while (*current != '=')
|
||||
current++;
|
||||
|
||||
*current = 0;
|
||||
current++;
|
||||
|
||||
value = current;
|
||||
|
||||
while (currentVariable) {
|
||||
if (!strcmp(currentVariable->variable, variableCopy))
|
||||
break;
|
||||
|
||||
currentVariable = currentVariable->next;
|
||||
}
|
||||
|
||||
if (currentVariable == NULL) {
|
||||
currentVariable = PR_NEW(EnvVariable);
|
||||
|
||||
if (currentVariable == NULL) {
|
||||
PR_DELETE(variableCopy);
|
||||
return -1;
|
||||
}
|
||||
|
||||
currentVariable->variable = strdup(variableCopy);
|
||||
currentVariable->value = strdup(value);
|
||||
currentVariable->next = gEnvironmentVariables;
|
||||
gEnvironmentVariables = currentVariable;
|
||||
}
|
||||
|
||||
else {
|
||||
PR_DELETE(currentVariable->value);
|
||||
currentVariable->value = strdup(current);
|
||||
|
||||
/* This is a temporary hack. Working on a real fix, remove this when done. */
|
||||
/* OK, there are two ways to access the */
|
||||
/* library path, getenv() and PR_GetLibraryPath(). Take a look at PR_GetLibraryPath(). */
|
||||
/* You'll see that we keep the path in a global which is intialized at startup from */
|
||||
/* a call to getenv(). From then on, they have nothing in common. */
|
||||
/* We need to keep them in synch. */
|
||||
if (strcmp(currentVariable->variable, "LD_LIBRARY_PATH") == 0)
|
||||
PR_SetLibraryPath(currentVariable->value);
|
||||
}
|
||||
|
||||
PR_DELETE(variableCopy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark MISCELLANEOUS
|
||||
|
||||
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
||||
{
|
||||
if (isCurrent) {
|
||||
(void) setjmp(t->md.jb);
|
||||
}
|
||||
*np = sizeof(t->md.jb) / sizeof(PRUint32);
|
||||
return (PRWord*) (t->md.jb);
|
||||
}
|
||||
|
||||
void _MD_GetRegisters(PRUint32 *to)
|
||||
{
|
||||
(void) setjmp((void*) to);
|
||||
}
|
||||
|
||||
void _MD_EarlyInit()
|
||||
{
|
||||
Handle environmentVariables;
|
||||
|
||||
GetCurrentProcess(&gApplicationProcess);
|
||||
|
||||
INIT_CRITICAL_REGION();
|
||||
InitIdleSemaphore();
|
||||
|
||||
#if !defined(MAC_NSPR_STANDALONE)
|
||||
// MacintoshInitializeMemory(); Moved to mdmacmem.c: AllocateRawMemory(Size blockSize)
|
||||
#else
|
||||
MacintoshInitializeMemory();
|
||||
#endif
|
||||
MacintoshInitializeTime();
|
||||
|
||||
// Install resource-controlled environment variables.
|
||||
|
||||
environmentVariables = GetResource('Envi', 128);
|
||||
if (environmentVariables != NULL) {
|
||||
|
||||
Size resourceSize;
|
||||
char *currentPutEnvString = (char *)*environmentVariables,
|
||||
*currentScanChar = currentPutEnvString;
|
||||
|
||||
resourceSize = GetHandleSize(environmentVariables);
|
||||
DetachResource(environmentVariables);
|
||||
HLock(environmentVariables);
|
||||
|
||||
while (resourceSize--) {
|
||||
|
||||
if ((*currentScanChar == '\n') || (*currentScanChar == '\r')) {
|
||||
*currentScanChar = 0;
|
||||
_MD_PutEnv (currentPutEnvString);
|
||||
currentPutEnvString = currentScanChar + 1;
|
||||
}
|
||||
|
||||
currentScanChar++;
|
||||
|
||||
}
|
||||
|
||||
DisposeHandle(environmentVariables);
|
||||
|
||||
}
|
||||
|
||||
#ifdef PR_INTERNAL_LOGGING
|
||||
_MD_PutEnv ("NSPR_LOG_MODULES=clock:6,cmon:6,io:6,mon:6,linker:6,cvar:6,sched:6,thread:6");
|
||||
#endif
|
||||
|
||||
InstallStackSpacePatch();
|
||||
}
|
||||
|
||||
void _MD_FinalInit()
|
||||
{
|
||||
_MD_InitNetAccess();
|
||||
}
|
||||
|
||||
void PR_InitMemory(void) {
|
||||
#ifndef NSPR_AS_SHARED_LIB
|
||||
// Needed for Mac browsers without Java. We don't want them calling PR_INIT, since it
|
||||
// brings in all of the thread support. But we do need to allow them to initialize
|
||||
// the NSPR memory package.
|
||||
// This should go away when all clients of the NSPR want threads AND memory.
|
||||
MacintoshInitializeMemory();
|
||||
#endif
|
||||
}
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark TERMINATION
|
||||
|
||||
|
||||
// THIS IS *** VERY *** IMPORTANT... our CFM Termination proc.
|
||||
// This allows us to deactivate our Time Mananger task even
|
||||
// if we are not totally gracefully exited. If this is not
|
||||
// done then we will randomly crash at later times when the
|
||||
// task is called after the app heap is gone.
|
||||
|
||||
#if TARGET_CARBON
|
||||
extern OTClientContextPtr clientContext;
|
||||
#define CLOSE_OPEN_TRANSPORT() CloseOpenTransportInContext(clientContext)
|
||||
|
||||
#else
|
||||
|
||||
#define CLOSE_OPEN_TRANSPORT() CloseOpenTransport()
|
||||
#endif /* TARGET_CARBON */
|
||||
|
||||
extern pascal void __NSTerminate(void);
|
||||
|
||||
void CleanupTermProc(void)
|
||||
{
|
||||
_MD_StopInterrupts(); // deactive Time Manager task
|
||||
|
||||
CLOSE_OPEN_TRANSPORT();
|
||||
TermIdleSemaphore();
|
||||
TERM_CRITICAL_REGION();
|
||||
|
||||
__NSTerminate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark STRING OPERATIONS
|
||||
|
||||
#if !defined(MAC_NSPR_STANDALONE)
|
||||
|
||||
// PStrFromCStr converts the source C string to a destination
|
||||
// pascal string as it copies. The dest string will
|
||||
// be truncated to fit into an Str255 if necessary.
|
||||
// If the C String pointer is NULL, the pascal string's length is set to zero
|
||||
//
|
||||
void
|
||||
PStrFromCStr(const char* src, Str255 dst)
|
||||
{
|
||||
short length = 0;
|
||||
|
||||
// handle case of overlapping strings
|
||||
if ( (void*)src == (void*)dst )
|
||||
{
|
||||
unsigned char* curdst = &dst[1];
|
||||
unsigned char thisChar;
|
||||
|
||||
thisChar = *(const unsigned char*)src++;
|
||||
while ( thisChar != '\0' )
|
||||
{
|
||||
unsigned char nextChar;
|
||||
|
||||
// use nextChar so we don't overwrite what we are about to read
|
||||
nextChar = *(const unsigned char*)src++;
|
||||
*curdst++ = thisChar;
|
||||
thisChar = nextChar;
|
||||
|
||||
if ( ++length >= 255 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( src != NULL )
|
||||
{
|
||||
unsigned char* curdst = &dst[1];
|
||||
short overflow = 255; // count down so test it loop is faster
|
||||
register char temp;
|
||||
|
||||
// Can't do the K&R C thing of "while (*s++ = *t++)" because it will copy trailing zero
|
||||
// which might overrun pascal buffer. Instead we use a temp variable.
|
||||
while ( (temp = *src++) != 0 )
|
||||
{
|
||||
*(char*)curdst++ = temp;
|
||||
|
||||
if ( --overflow <= 0 )
|
||||
break;
|
||||
}
|
||||
length = 255 - overflow;
|
||||
}
|
||||
dst[0] = length;
|
||||
}
|
||||
|
||||
|
||||
void CStrFromPStr(ConstStr255Param pString, char **cString)
|
||||
{
|
||||
// Allocates a cString and copies a Pascal string into it.
|
||||
unsigned int len;
|
||||
|
||||
len = pString[0];
|
||||
*cString = malloc(len+1);
|
||||
|
||||
if (*cString != NULL) {
|
||||
strncpy(*cString, (char *)&pString[1], len);
|
||||
(*cString)[len] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dprintf(const char *format, ...)
|
||||
{
|
||||
#if DEBUG
|
||||
va_list ap;
|
||||
Str255 buffer;
|
||||
|
||||
va_start(ap, format);
|
||||
buffer[0] = PR_vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
DebugStr(buffer);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void debugstr(const char *debuggerMsg)
|
||||
{
|
||||
Str255 pStr;
|
||||
|
||||
PStrFromCStr(debuggerMsg, pStr);
|
||||
DebugStr(pStr);
|
||||
}
|
||||
|
||||
|
||||
char *strdup(const char *source)
|
||||
{
|
||||
char *newAllocation;
|
||||
size_t stringLength;
|
||||
|
||||
PR_ASSERT(source);
|
||||
|
||||
stringLength = strlen(source) + 1;
|
||||
|
||||
newAllocation = (char *)PR_MALLOC(stringLength);
|
||||
if (newAllocation == NULL)
|
||||
return NULL;
|
||||
BlockMoveData(source, newAllocation, stringLength);
|
||||
return newAllocation;
|
||||
}
|
||||
|
||||
// PStrFromCStr converts the source C string to a destination
|
||||
// pascal string as it copies. The dest string will
|
||||
// be truncated to fit into an Str255 if necessary.
|
||||
// If the C String pointer is NULL, the pascal string's length is set to zero
|
||||
//
|
||||
void PStrFromCStr(const char* src, Str255 dst)
|
||||
{
|
||||
short length = 0;
|
||||
|
||||
// handle case of overlapping strings
|
||||
if ( (void*)src == (void*)dst )
|
||||
{
|
||||
unsigned char* curdst = &dst[1];
|
||||
unsigned char thisChar;
|
||||
|
||||
thisChar = *(const unsigned char*)src++;
|
||||
while ( thisChar != '\0' )
|
||||
{
|
||||
unsigned char nextChar;
|
||||
|
||||
// use nextChar so we don't overwrite what we are about to read
|
||||
nextChar = *(const unsigned char*)src++;
|
||||
*curdst++ = thisChar;
|
||||
thisChar = nextChar;
|
||||
|
||||
if ( ++length >= 255 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( src != NULL )
|
||||
{
|
||||
unsigned char* curdst = &dst[1];
|
||||
short overflow = 255; // count down so test it loop is faster
|
||||
register char temp;
|
||||
|
||||
// Can't do the K&R C thing of "while (*s++ = *t++)" because it will copy trailing zero
|
||||
// which might overrun pascal buffer. Instead we use a temp variable.
|
||||
while ( (temp = *src++) != 0 )
|
||||
{
|
||||
*(char*)curdst++ = temp;
|
||||
|
||||
if ( --overflow <= 0 )
|
||||
break;
|
||||
}
|
||||
length = 255 - overflow;
|
||||
}
|
||||
dst[0] = length;
|
||||
}
|
||||
|
||||
|
||||
void CStrFromPStr(ConstStr255Param pString, char **cString)
|
||||
{
|
||||
// Allocates a cString and copies a Pascal string into it.
|
||||
unsigned int len;
|
||||
|
||||
len = pString[0];
|
||||
*cString = PR_MALLOC(len+1);
|
||||
|
||||
if (*cString != NULL) {
|
||||
strncpy(*cString, (char *)&pString[1], len);
|
||||
(*cString)[len] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t strlen(const char *source)
|
||||
{
|
||||
size_t currentLength = 0;
|
||||
|
||||
if (source == NULL)
|
||||
return currentLength;
|
||||
|
||||
while (*source++ != '\0')
|
||||
currentLength++;
|
||||
|
||||
return currentLength;
|
||||
}
|
||||
|
||||
int strcmpcore(const char *str1, const char *str2, int caseSensitive)
|
||||
{
|
||||
char currentChar1, currentChar2;
|
||||
|
||||
while (1) {
|
||||
|
||||
currentChar1 = *str1;
|
||||
currentChar2 = *str2;
|
||||
|
||||
if (!caseSensitive) {
|
||||
|
||||
if ((currentChar1 >= 'a') && (currentChar1 <= 'z'))
|
||||
currentChar1 += ('A' - 'a');
|
||||
|
||||
if ((currentChar2 >= 'a') && (currentChar2 <= 'z'))
|
||||
currentChar2 += ('A' - 'a');
|
||||
|
||||
}
|
||||
|
||||
if (currentChar1 == '\0')
|
||||
break;
|
||||
|
||||
if (currentChar1 != currentChar2)
|
||||
return currentChar1 - currentChar2;
|
||||
|
||||
str1++;
|
||||
str2++;
|
||||
|
||||
}
|
||||
|
||||
return currentChar1 - currentChar2;
|
||||
}
|
||||
|
||||
int strcmp(const char *str1, const char *str2)
|
||||
{
|
||||
return strcmpcore(str1, str2, true);
|
||||
}
|
||||
|
||||
int strcasecmp(const char *str1, const char *str2)
|
||||
{
|
||||
return strcmpcore(str1, str2, false);
|
||||
}
|
||||
|
||||
|
||||
void *memcpy(void *to, const void *from, size_t size)
|
||||
{
|
||||
if (size != 0) {
|
||||
#if DEBUG
|
||||
if ((UInt32)to < 0x1000)
|
||||
DebugStr("\pmemcpy has illegal to argument");
|
||||
if ((UInt32)from < 0x1000)
|
||||
DebugStr("\pmemcpy has illegal from argument");
|
||||
#endif
|
||||
BlockMoveData(from, to, size);
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
void dprintf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buffer;
|
||||
|
||||
va_start(ap, format);
|
||||
buffer = (char *)PR_vsmprintf(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
debugstr(buffer);
|
||||
PR_DELETE(buffer);
|
||||
}
|
||||
|
||||
void
|
||||
exit(int result)
|
||||
{
|
||||
#pragma unused (result)
|
||||
|
||||
ExitToShell();
|
||||
}
|
||||
|
||||
void abort(void)
|
||||
{
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark FLUSHING THE GARBAGE COLLECTOR
|
||||
|
||||
#if !defined(MAC_NSPR_STANDALONE)
|
||||
|
||||
unsigned char GarbageCollectorCacheFlusher(PRUint32)
|
||||
{
|
||||
|
||||
PRIntn is;
|
||||
|
||||
UInt32 oldPriority;
|
||||
|
||||
// If java wasn't completely initialized, then bail
|
||||
// harmlessly.
|
||||
|
||||
if (PR_GetGCInfo()->lock == NULL)
|
||||
return false;
|
||||
|
||||
#if DEBUG
|
||||
if (_MD_GET_INTSOFF() == 1)
|
||||
DebugStr("\pGarbageCollectorCacheFlusher at interrupt time!");
|
||||
#endif
|
||||
|
||||
// The synchronization here is very tricky. We really
|
||||
// don't want any other threads to run while we are
|
||||
// cleaning up the gc heap... they could call malloc,
|
||||
// and then we would be in trouble in a big way. So,
|
||||
// we jack up our priority and that of the finalizer
|
||||
// so that we won't yield to other threads.
|
||||
// dkc 5/17/96
|
||||
|
||||
oldPriority = PR_GetThreadPriority(PR_GetCurrentThread());
|
||||
_PR_INTSOFF(is);
|
||||
_PR_SetThreadPriority(PR_GetCurrentThread(), (PRThreadPriority)30);
|
||||
_PR_INTSON(is);
|
||||
|
||||
// Garbage collect twice. This will finalize any
|
||||
// dangling AWT resources (images, components), and
|
||||
// then free up their GC space, too.
|
||||
// dkc 2/15/96
|
||||
// interrupts must be on during PR_GC
|
||||
|
||||
PR_GC();
|
||||
|
||||
// By setting the finalizer priority to 31, then we
|
||||
// ensure it will run before us. When it finishes
|
||||
// its list of finalizations, it returns to us
|
||||
// for the second garbage collection.
|
||||
|
||||
PR_Yield();
|
||||
|
||||
PR_GC();
|
||||
|
||||
// Restore our old priorities.
|
||||
|
||||
_PR_INTSOFF(is);
|
||||
_PR_SetThreadPriority(PR_GetCurrentThread(), (PRThreadPriority)oldPriority);
|
||||
_PR_INTSON(is);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//##############################################################################
|
||||
//##############################################################################
|
||||
#pragma mark -
|
||||
#pragma mark MISCELLANEOUS-HACKS
|
||||
|
||||
|
||||
//
|
||||
// ***** HACK FIX THESE ****
|
||||
//
|
||||
extern long _MD_GetOSName(char *buf, long count)
|
||||
{
|
||||
long len;
|
||||
|
||||
len = PR_snprintf(buf, count, "Mac OS");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern long _MD_GetOSVersion(char *buf, long count)
|
||||
{
|
||||
long len;
|
||||
|
||||
len = PR_snprintf(buf, count, "7.5");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern long _MD_GetArchitecture(char *buf, long count)
|
||||
{
|
||||
long len;
|
||||
|
||||
#if defined(TARGET_CPU_PPC) && TARGET_CPU_PPC
|
||||
len = PR_snprintf(buf, count, "PowerPC");
|
||||
#else
|
||||
len = PR_snprintf(buf, count, "Motorola68k");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
#ifndef mdmac_h__
|
||||
#define mdmac_h__
|
||||
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
void PStrFromCStr(const char* src, Str255 dst);
|
||||
void CStrFromPStr(ConstStr255Param pString, char **cString);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
|
||||
#endif /* mdmac_h__ */
|
|
@ -1,136 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime (NSPR).
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nspr_cpucfg___
|
||||
#define nspr_cpucfg___
|
||||
|
||||
#ifndef XP_MAC
|
||||
#define XP_MAC
|
||||
#endif
|
||||
|
||||
#undef IS_LITTLE_ENDIAN
|
||||
#define IS_BIG_ENDIAN 1
|
||||
|
||||
#define HAVE_LONG_LONG
|
||||
|
||||
#define PR_AF_INET6 30 /* same as AF_INET6 */
|
||||
|
||||
#define PR_BYTES_PER_BYTE 1L
|
||||
#define PR_BYTES_PER_SHORT 2L
|
||||
#define PR_BYTES_PER_INT 4L
|
||||
#define PR_BYTES_PER_INT64 8L
|
||||
#define PR_BYTES_PER_LONG 4L
|
||||
#define PR_BYTES_PER_FLOAT 4L
|
||||
#define PR_BYTES_PER_DOUBLE 8L
|
||||
#define PR_BYTES_PER_WORD 4L
|
||||
#define PR_BYTES_PER_DWORD 8L
|
||||
|
||||
#define PR_BITS_PER_BYTE 8L
|
||||
#define PR_BITS_PER_SHORT 16L
|
||||
#define PR_BITS_PER_INT 32L
|
||||
#define PR_BITS_PER_INT64 64L
|
||||
#define PR_BITS_PER_LONG 32L
|
||||
#define PR_BITS_PER_FLOAT 32L
|
||||
#define PR_BITS_PER_DOUBLE 64L
|
||||
#define PR_BITS_PER_WORD 32L
|
||||
|
||||
#define PR_BITS_PER_BYTE_LOG2 3L
|
||||
#define PR_BITS_PER_SHORT_LOG2 4L
|
||||
#define PR_BITS_PER_INT_LOG2 5L
|
||||
#define PR_BITS_PER_INT64_LOG2 6L
|
||||
#define PR_BITS_PER_LONG_LOG2 5L
|
||||
#define PR_BITS_PER_FLOAT_LOG2 5L
|
||||
#define PR_BITS_PER_DOUBLE_LOG2 6L
|
||||
#define PR_BITS_PER_WORD_LOG2 5L
|
||||
|
||||
#define PR_ALIGN_OF_SHORT 2L
|
||||
#define PR_ALIGN_OF_INT 4L
|
||||
#define PR_ALIGN_OF_LONG 4L
|
||||
#define PR_ALIGN_OF_INT64 2L
|
||||
#define PR_ALIGN_OF_FLOAT 4L
|
||||
#define PR_ALIGN_OF_DOUBLE 4L
|
||||
#define PR_ALIGN_OF_POINTER 4L
|
||||
#define PR_ALIGN_OF_WORD 4L
|
||||
|
||||
#define PR_BYTES_PER_WORD_LOG2 2L
|
||||
#define PR_BYTES_PER_DWORD_LOG2 3L
|
||||
#define PR_WORDS_PER_DWORD_LOG2 1L
|
||||
|
||||
#ifndef NO_NSPR_10_SUPPORT
|
||||
#define BYTES_PER_BYTE PR_BYTES_PER_BYTE
|
||||
#define BYTES_PER_SHORT PR_BYTES_PER_SHORT
|
||||
#define BYTES_PER_INT PR_BYTES_PER_INT
|
||||
#define BYTES_PER_INT64 PR_BYTES_PER_INT64
|
||||
#define BYTES_PER_LONG PR_BYTES_PER_LONG
|
||||
#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT
|
||||
#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE
|
||||
#define BYTES_PER_WORD PR_BYTES_PER_WORD
|
||||
#define BYTES_PER_DWORD PR_BYTES_PER_DWORD
|
||||
|
||||
#define BITS_PER_BYTE PR_BITS_PER_BYTE
|
||||
#define BITS_PER_SHORT PR_BITS_PER_SHORT
|
||||
#define BITS_PER_INT PR_BITS_PER_INT
|
||||
#define BITS_PER_INT64 PR_BITS_PER_INT64
|
||||
#define BITS_PER_LONG PR_BITS_PER_LONG
|
||||
#define BITS_PER_FLOAT PR_BITS_PER_FLOAT
|
||||
#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE
|
||||
#define BITS_PER_WORD PR_BITS_PER_WORD
|
||||
|
||||
#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2
|
||||
#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
|
||||
#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2
|
||||
#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
|
||||
#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2
|
||||
#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
|
||||
#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2
|
||||
#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2
|
||||
|
||||
#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT
|
||||
#define ALIGN_OF_INT PR_ALIGN_OF_INT
|
||||
#define ALIGN_OF_LONG PR_ALIGN_OF_LONG
|
||||
#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64
|
||||
#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT
|
||||
#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE
|
||||
#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER
|
||||
#define ALIGN_OF_WORD PR_ALIGN_OF_WORD
|
||||
|
||||
#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2
|
||||
#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2
|
||||
#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2
|
||||
#endif /* NO_NSPR_10_SUPPORT */
|
||||
|
||||
#endif /* nspr_cpucfg___ */
|
|
@ -87,8 +87,10 @@ PR_Now(void)
|
|||
{
|
||||
PRTime prt;
|
||||
FILETIME ft;
|
||||
SYSTEMTIME st;
|
||||
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
_PR_FileTimeToPRTime(&ft, &prt);
|
||||
return prt;
|
||||
}
|
||||
|
@ -236,7 +238,19 @@ static int assembleEnvBlock(char **envp, char **envBlock)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WINCE
|
||||
{
|
||||
PRUnichar *wideCurEnv = mozce_GetEnvString();
|
||||
int len = WideCharToMultiByte(CP_ACP, 0, wideCurEnv, -1,
|
||||
NULL, 0, NULL, NULL);
|
||||
curEnv = (char *) PR_MALLOC(len * sizeof(char));
|
||||
WideCharToMultiByte(CP_ACP, 0, wideCurEnv, -1,
|
||||
curEnv, len, NULL, NULL);
|
||||
free(wideCurEnv);
|
||||
}
|
||||
#else
|
||||
curEnv = GetEnvironmentStrings();
|
||||
#endif
|
||||
|
||||
cwdStart = curEnv;
|
||||
while (*cwdStart) {
|
||||
|
@ -266,7 +280,11 @@ static int assembleEnvBlock(char **envp, char **envBlock)
|
|||
|
||||
p = *envBlock = PR_MALLOC((PRUint32) envBlockSize);
|
||||
if (p == NULL) {
|
||||
#ifdef WINCE
|
||||
PR_Free(curEnv);
|
||||
#else
|
||||
FreeEnvironmentStrings(curEnv);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -274,7 +292,11 @@ static int assembleEnvBlock(char **envp, char **envBlock)
|
|||
while (q < cwdEnd) {
|
||||
*p++ = *q++;
|
||||
}
|
||||
#ifdef WINCE
|
||||
PR_Free(curEnv);
|
||||
#else
|
||||
FreeEnvironmentStrings(curEnv);
|
||||
#endif
|
||||
|
||||
for (env = envp; *env; env++) {
|
||||
q = *env;
|
||||
|
@ -302,7 +324,14 @@ PRProcess * _PR_CreateWindowsProcess(
|
|||
char *const *envp,
|
||||
const PRProcessAttr *attr)
|
||||
{
|
||||
#ifdef WINCE
|
||||
STARTUPINFOW startupInfo;
|
||||
PRUnichar *wideCmdLine;
|
||||
PRUnichar *wideCwd;
|
||||
int len = 0;
|
||||
#else
|
||||
STARTUPINFO startupInfo;
|
||||
#endif
|
||||
PROCESS_INFORMATION procInfo;
|
||||
BOOL retVal;
|
||||
char *cmdLine = NULL;
|
||||
|
@ -323,6 +352,7 @@ PRProcess * _PR_CreateWindowsProcess(
|
|||
goto errorExit;
|
||||
}
|
||||
|
||||
#ifndef WINCE
|
||||
/*
|
||||
* If attr->fdInheritBuffer is not NULL, we need to insert
|
||||
* it into the envp array, so envp cannot be NULL.
|
||||
|
@ -392,7 +422,36 @@ PRProcess * _PR_CreateWindowsProcess(
|
|||
}
|
||||
cwd = attr->currentDirectory;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WINCE
|
||||
len = MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, NULL, 0);
|
||||
wideCmdLine = (PRUnichar *)PR_MALLOC(len * sizeof(PRUnichar));
|
||||
MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, wideCmdLine, len);
|
||||
len = MultiByteToWideChar(CP_ACP, 0, cwd, -1, NULL, 0);
|
||||
wideCwd = PR_MALLOC(len * sizeof(PRUnichar));
|
||||
MultiByteToWideChar(CP_ACP, 0, cwd, -1, wideCwd, len);
|
||||
retVal = CreateProcessW(NULL,
|
||||
wideCmdLine,
|
||||
NULL, /* security attributes for the new
|
||||
* process */
|
||||
NULL, /* security attributes for the primary
|
||||
* thread in the new process */
|
||||
TRUE, /* inherit handles */
|
||||
0, /* creation flags */
|
||||
envBlock, /* an environment block, consisting
|
||||
* of a null-terminated block of
|
||||
* null-terminated strings. Each
|
||||
* string is in the form:
|
||||
* name=value
|
||||
* XXX: usually NULL */
|
||||
wideCwd, /* current drive and directory */
|
||||
&startupInfo,
|
||||
&procInfo
|
||||
);
|
||||
PR_Free(wideCmdLine);
|
||||
PR_Free(wideCwd);
|
||||
#else
|
||||
retVal = CreateProcess(NULL,
|
||||
cmdLine,
|
||||
NULL, /* security attributes for the new
|
||||
|
@ -411,6 +470,8 @@ PRProcess * _PR_CreateWindowsProcess(
|
|||
&startupInfo,
|
||||
&procInfo
|
||||
);
|
||||
#endif
|
||||
|
||||
if (retVal == FALSE) {
|
||||
/* XXX what error code? */
|
||||
PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
|
||||
|
@ -603,8 +664,14 @@ PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size)
|
|||
fmap->md.dwAccess = FILE_MAP_WRITE;
|
||||
} else {
|
||||
PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY);
|
||||
#ifdef WINCE
|
||||
/* WINCE does not have FILE_MAP_COPY. */
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
#else
|
||||
flProtect = PAGE_WRITECOPY;
|
||||
fmap->md.dwAccess = FILE_MAP_COPY;
|
||||
#endif
|
||||
}
|
||||
|
||||
fmap->md.hFileMap = CreateFileMapping(
|
||||
|
|
|
@ -49,6 +49,100 @@
|
|||
#include <wchar.h>
|
||||
#endif /* MOZ_UNICODE */
|
||||
|
||||
#ifdef WINCE
|
||||
|
||||
static long GetDriveType(const char *lpRootPathName)
|
||||
{
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return 0; // The drive type cannot be determined.
|
||||
}
|
||||
|
||||
static DWORD GetFullPathName(const char *lpFileName,
|
||||
DWORD nBufferLength,
|
||||
const char *lpBuffer,
|
||||
const char **lpFilePart)
|
||||
{
|
||||
// needs work dft
|
||||
DWORD len = strlen(lpFileName);
|
||||
if (len > nBufferLength)
|
||||
return len;
|
||||
|
||||
strncpy((char *)lpBuffer, lpFileName, len);
|
||||
((char *)lpBuffer)[len] = '\0';
|
||||
|
||||
if (lpFilePart) {
|
||||
char *sep = strrchr(lpBuffer, '\\');
|
||||
if (sep) {
|
||||
sep++; // pass the seperator
|
||||
*lpFilePart = sep;
|
||||
} else {
|
||||
*lpFilePart = lpBuffer;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static BOOL LockFile(HANDLE hFile,
|
||||
DWORD dwFileOffsetLow,
|
||||
DWORD dwFileOffsetHigh,
|
||||
DWORD nNumberOfBytesToLockLow,
|
||||
DWORD nNumberOfBytesToLockHigh)
|
||||
{
|
||||
OVERLAPPED overlapped = {0};
|
||||
overlapped.Offset = dwFileOffsetLow;
|
||||
overlapped.OffsetHigh = dwFileOffsetHigh;
|
||||
return LockFileEx(hFile,
|
||||
LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
|
||||
0, // reserved
|
||||
nNumberOfBytesToLockLow,
|
||||
nNumberOfBytesToLockHigh, &overlapped);
|
||||
}
|
||||
|
||||
static BOOL UnlockFile(HANDLE hFile,
|
||||
DWORD dwFileOffsetLow,
|
||||
DWORD dwFileOffsetHigh,
|
||||
DWORD nNumberOfBytesToUnlockLow,
|
||||
DWORD nNumberOfBytesToUnlockHigh)
|
||||
{
|
||||
OVERLAPPED overlapped = {0};
|
||||
overlapped.Offset = dwFileOffsetLow;
|
||||
overlapped.OffsetHigh = dwFileOffsetHigh;
|
||||
return UnlockFileEx(hFile,
|
||||
0, // reserved
|
||||
nNumberOfBytesToUnlockLow,
|
||||
nNumberOfBytesToUnlockHigh, &overlapped);
|
||||
}
|
||||
|
||||
static unsigned char *_mbsdec(const unsigned char *string1,
|
||||
const unsigned char *string2)
|
||||
{
|
||||
// needs work dft
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned char *_mbsinc(const unsigned char *inCurrent)
|
||||
{
|
||||
// needs work dft
|
||||
return (unsigned char *)(inCurrent + 1);
|
||||
}
|
||||
|
||||
static unsigned char *_mbspbrk(const unsigned char *inString,
|
||||
const unsigned char *inStrCharSet)
|
||||
{
|
||||
// needs work dft
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const unsigned short *_wcsdec(const unsigned short *s,
|
||||
const unsigned short *p)
|
||||
{
|
||||
// needs work dft
|
||||
|
||||
p = s < p ? (const unsigned short *)(s - 1) : 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct _MDLock _pr_ioq_lock;
|
||||
|
||||
|
@ -90,6 +184,7 @@ static void InitGetFileInfo(void);
|
|||
static void InitUnicodeSupport(void);
|
||||
|
||||
static PRBool IsPrevCharSlash(const char *str, const char *current);
|
||||
static PRBool IsPrevCharSlashW(const PRUnichar *str, const PRUnichar *current);
|
||||
|
||||
void
|
||||
_PR_MD_INIT_IO()
|
||||
|
@ -481,6 +576,16 @@ void FlipSlashes(char *cp, size_t len)
|
|||
}
|
||||
} /* end FlipSlashes() */
|
||||
|
||||
void FlipSlashesW(PRUnichar *cp, size_t len)
|
||||
{
|
||||
while (len-- > 0) {
|
||||
if (cp[0] == L'/') {
|
||||
cp[0] = L'\\';
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
} /* end FlipSlashesW() */
|
||||
|
||||
|
||||
/*
|
||||
**
|
||||
|
@ -644,6 +749,11 @@ _PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm)
|
|||
PRInt32
|
||||
_PR_MD_STAT(const char *fn, struct stat *info)
|
||||
{
|
||||
#ifdef WINCE
|
||||
// needs work. dft
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return -1;
|
||||
#else
|
||||
PRInt32 rv;
|
||||
|
||||
rv = _stat(fn, (struct _stat *)info);
|
||||
|
@ -675,6 +785,7 @@ _PR_MD_STAT(const char *fn, struct stat *info)
|
|||
_PR_MD_MAP_STAT_ERROR(errno);
|
||||
}
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\')
|
||||
|
@ -690,6 +801,17 @@ IsPrevCharSlash(const char *str, const char *current)
|
|||
return (prev == current - 1) && _PR_IS_SLASH(*prev);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsPrevCharSlashW(const PRUnichar *str, const PRUnichar *current)
|
||||
{
|
||||
const PRUnichar *prev;
|
||||
|
||||
if (str >= current)
|
||||
return PR_FALSE;
|
||||
prev = _wcsdec(str, current);
|
||||
return (prev == current - 1) && _PR_IS_SLASH(*prev);
|
||||
}
|
||||
|
||||
/*
|
||||
* IsRootDirectory --
|
||||
*
|
||||
|
@ -789,7 +911,7 @@ IsRootDirectory(char *fn, size_t buflen)
|
|||
static void InitGetFileInfo(void)
|
||||
{
|
||||
HMODULE module;
|
||||
module = GetModuleHandle("Kernel32.dll");
|
||||
module = GetModuleHandleW(L"Kernel32.dll");
|
||||
if (!module) {
|
||||
PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
|
||||
("InitGetFileInfo: GetModuleHandle() failed: %d",
|
||||
|
@ -801,6 +923,7 @@ static void InitGetFileInfo(void)
|
|||
GetProcAddress(module, "GetFileAttributesExA");
|
||||
}
|
||||
|
||||
#ifndef WINCE
|
||||
/*
|
||||
* If GetFileAttributeEx doesn't exist, we call FindFirstFile as a
|
||||
* fallback.
|
||||
|
@ -878,6 +1001,7 @@ GetFileAttributesExFB(const char *fn, WIN32_FIND_DATA *findFileData)
|
|||
FindClose(hFindFile);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32
|
||||
_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
|
||||
|
@ -983,6 +1107,10 @@ _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
|
|||
PRStatus
|
||||
_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
|
||||
{
|
||||
#ifdef WINCE
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
#else
|
||||
BOOL rv;
|
||||
|
||||
/*
|
||||
|
@ -998,6 +1126,7 @@ _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
|
|||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1013,6 +1142,9 @@ _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
|
|||
void
|
||||
_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
|
||||
{
|
||||
#ifdef WINCE
|
||||
fd->secret->inheritable = _PR_TRI_FALSE;
|
||||
#else
|
||||
DWORD flags;
|
||||
|
||||
PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
|
||||
|
@ -1023,6 +1155,7 @@ _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
|
|||
fd->secret->inheritable = _PR_TRI_FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PRInt32
|
||||
|
@ -1040,6 +1173,10 @@ _PR_MD_RENAME(const char *from, const char *to)
|
|||
PRInt32
|
||||
_PR_MD_ACCESS(const char *name, PRAccessHow how)
|
||||
{
|
||||
#ifdef WINCE
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return -1;
|
||||
#else
|
||||
PRInt32 rv;
|
||||
switch (how) {
|
||||
case PR_ACCESS_WRITE_OK:
|
||||
|
@ -1058,6 +1195,7 @@ PRInt32 rv;
|
|||
if (rv < 0)
|
||||
_PR_MD_MAP_ACCESS_ERROR(errno);
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
PRInt32
|
||||
|
@ -1187,6 +1325,10 @@ PRBool _pr_useUnicode = PR_FALSE;
|
|||
|
||||
static void InitUnicodeSupport(void)
|
||||
{
|
||||
#ifdef WINCE
|
||||
/* The A functions don't even exist in Windows Mobile. */
|
||||
_pr_useUnicode = PR_TRUE;
|
||||
#else
|
||||
/*
|
||||
* The W functions exist on Win9x as stubs that fail with the
|
||||
* ERROR_CALL_NOT_IMPLEMENTED error. We plan to emulate the
|
||||
|
@ -1210,20 +1352,12 @@ static void InitUnicodeSupport(void)
|
|||
if (getenv("WINAPI_USE_ANSI"))
|
||||
_pr_useUnicode = PR_FALSE;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
|
||||
/* ================ UTF16 Interfaces ================================ */
|
||||
void FlipSlashesW(PRUnichar *cp, size_t len)
|
||||
{
|
||||
while (len-- > 0) {
|
||||
if (cp[0] == L'/') {
|
||||
cp[0] = L'\\';
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
} /* end FlipSlashesW() */
|
||||
|
||||
PROsfd
|
||||
_PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, int mode)
|
||||
|
|
Загрузка…
Ссылка в новой задаче