diff --git a/nsprpub/config/prdepend.h b/nsprpub/config/prdepend.h index df72c56882d..55444c40b3a 100644 --- a/nsprpub/config/prdepend.h +++ b/nsprpub/config/prdepend.h @@ -42,3 +42,4 @@ */ #error "Do not include this header file." + diff --git a/nsprpub/configure b/nsprpub/configure index 53bdef42974..c2c00743277 100755 --- a/nsprpub/configure +++ b/nsprpub/configure @@ -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 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 <&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 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 < Autoconf TIOCGETP @@ -5184,7 +5189,7 @@ rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat > conftest.$ac_ext < 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 <&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 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 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 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 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 diff --git a/nsprpub/configure.in b/nsprpub/configure.in index c9662f84f96..c0b91e942f4 100644 --- a/nsprpub/configure.in +++ b/nsprpub/configure.in @@ -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 ;; diff --git a/nsprpub/pr/include/md/_macos.h b/nsprpub/pr/include/md/_macos.h deleted file mode 100644 index dbcab4090b7..00000000000 --- a/nsprpub/pr/include/md/_macos.h +++ /dev/null @@ -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 -#include - -#include -#include -#include - -#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 // 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___ */ diff --git a/nsprpub/pr/include/md/_os2.h b/nsprpub/pr/include/md/_os2.h index c47fc0419ab..e5ea9833231 100644 --- a/nsprpub/pr/include/md/_os2.h +++ b/nsprpub/pr/include/md/_os2.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); diff --git a/nsprpub/pr/include/md/prosdep.h b/nsprpub/pr/include/md/prosdep.h index d47c1f000ef..c0e111a45c4 100644 --- a/nsprpub/pr/include/md/prosdep.h +++ b/nsprpub/pr/include/md/prosdep.h @@ -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) diff --git a/nsprpub/pr/include/prinet.h b/nsprpub/pr/include/prinet.h index 9a76ea0ca8d..2975d380085 100644 --- a/nsprpub/pr/include/prinet.h +++ b/nsprpub/pr/include/prinet.h @@ -122,10 +122,6 @@ struct sockaddr_dl; #include -#elif defined(XP_MAC) - -#include "macsocket.h" - #else #error Unknown platform diff --git a/nsprpub/pr/src/io/prio.c b/nsprpub/pr/src/io/prio.c index e4b243c684f..7426b7233f9 100644 --- a/nsprpub/pr/src/io/prio.c +++ b/nsprpub/pr/src/io/prio.c @@ -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); diff --git a/nsprpub/pr/src/io/prlog.c b/nsprpub/pr/src/io/prlog.c index 1f87d9918b5..0d6bfd159b1 100644 --- a/nsprpub/pr/src/io/prlog.c +++ b/nsprpub/pr/src/io/prlog.c @@ -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 diff --git a/nsprpub/pr/src/io/prpolevt.c b/nsprpub/pr/src/io/prpolevt.c index de5f991c56d..733b0fcbd35 100644 --- a/nsprpub/pr/src/io/prpolevt.c +++ b/nsprpub/pr/src/io/prpolevt.c @@ -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 */ /* diff --git a/nsprpub/pr/src/io/prsocket.c b/nsprpub/pr/src/io/prsocket.c index da2d3b00c13..1eae6d66611 100644 --- a/nsprpub/pr/src/io/prsocket.c +++ b/nsprpub/pr/src/io/prsocket.c @@ -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); diff --git a/nsprpub/pr/src/md/mac/MANIFEST b/nsprpub/pr/src/md/mac/MANIFEST deleted file mode 100644 index c51cbd5a020..00000000000 --- a/nsprpub/pr/src/md/mac/MANIFEST +++ /dev/null @@ -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 diff --git a/nsprpub/pr/src/md/mac/MacErrorHandling.h b/nsprpub/pr/src/md/mac/MacErrorHandling.h deleted file mode 100644 index b0e03900052..00000000000 --- a/nsprpub/pr/src/md/mac/MacErrorHandling.h +++ /dev/null @@ -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 - -/**/ -/********************************************************************* - -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 - - -/**/ -/********************************************************************* - -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 - -/**/ -/********************************************************************* - -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 - -/**/ -/********************************************************************* - -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 - -/**/ -/************************************************************************************** - -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 - -/**/ -/********************************************************************* - -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 - -/**/ -/********************************************************************* - -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 - -/**/ -/********************************************************************* - -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 - -/**/ -/********************************************************************* - -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 - -/**/ -/********************************************************************* - -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) - - -/**/ -/********************************************************************/ -#endif diff --git a/nsprpub/pr/src/md/mac/macdll.c b/nsprpub/pr/src/md/mac/macdll.c deleted file mode 100644 index a5ecce78b06..00000000000 --- a/nsprpub/pr/src/md/mac/macdll.c +++ /dev/null @@ -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 - -#include -#include -#include -#include -#include -#include - -#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; -} - - diff --git a/nsprpub/pr/src/md/mac/macdll.h b/nsprpub/pr/src/md/mac/macdll.h deleted file mode 100644 index a34890cd33f..00000000000 --- a/nsprpub/pr/src/md/mac/macdll.h +++ /dev/null @@ -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__ */ diff --git a/nsprpub/pr/src/md/mac/macio.c b/nsprpub/pr/src/md/mac/macio.c deleted file mode 100644 index ae3516de1bf..00000000000 --- a/nsprpub/pr/src/md/mac/macio.c +++ /dev/null @@ -1,1949 +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 - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "FullPath.h" /* MoreFiles */ - -#include "primpl.h" -#include "MacErrorHandling.h" -#include "mdmac.h" - -#include "macio.h" - -/* forward declarations */ -extern unsigned long gJanuaryFirst1970Seconds; - -extern void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout); -extern void DoneWaitingOnThisThread(PRThread *thread); -extern void AsyncNotify(PRThread *thread); - - -/* PB for Read and Write */ -struct ExtendedParamBlock { - /* PB must be first so that the file system can get the right data. */ - ParamBlockRec pb; - PRThread *thread; -}; -typedef struct ExtendedParamBlock ExtendedParamBlock; - - -/* XXX Not done yet for 68K */ -/* I/O completion routne for _MD_READ and _MD_WRITE */ -static void AsyncIOCompletion (ExtendedParamBlock *pbAsyncPtr) -{ - _PRCPU *cpu = _PR_MD_CURRENT_CPU(); - PRThread *thread = pbAsyncPtr->thread; - PRIntn is; - - if (_PR_MD_GET_INTSOFF()) { - thread->md.missedIONotify = PR_TRUE; - cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - } else { - _PR_INTSOFF(is); - - thread->md.osErrCode = noErr; - DoneWaitingOnThisThread(thread); - - _PR_FAST_INTSON(is); - } - - SignalIdleSemaphore(); -} - -void _MD_SetError(OSErr oserror) -{ - PRErrorCode code; - - switch (oserror) { - case memFullErr: - code = PR_OUT_OF_MEMORY_ERROR; - break; - case fnfErr: - code = PR_FILE_NOT_FOUND_ERROR; - break; - case dupFNErr: - code = PR_FILE_EXISTS_ERROR; - break; - case ioErr: - code = PR_IO_ERROR; - break; - case nsvErr: - case wrgVolTypErr: - code = PR_INVALID_DEVICE_STATE_ERROR; - break; - case bdNamErr: - case fsRnErr: - code = PR_NAME_TOO_LONG_ERROR; - break; - case tmfoErr: - code = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case opWrErr: - case wrPermErr: - case permErr: - case afpAccessDenied: - code = PR_NO_ACCESS_RIGHTS_ERROR; - break; - case afpObjectTypeErr: - code = PR_DIRECTORY_LOOKUP_ERROR; - break; - case wPrErr: - case vLckdErr: - code = PR_DEVICE_IS_LOCKED_ERROR; - break; - case fLckdErr: - code = PR_FILE_IS_LOCKED_ERROR; - break; - case dirNFErr: - code = PR_NOT_DIRECTORY_ERROR; - break; - case dirFulErr: - code = PR_MAX_DIRECTORY_ENTRIES_ERROR; - break; - case dskFulErr: - code = PR_NO_DEVICE_SPACE_ERROR; - break; - case rfNumErr: - case fnOpnErr: - code = PR_BAD_DESCRIPTOR_ERROR; - break; - case eofErr: - code = PR_END_OF_FILE_ERROR; - break; - case posErr: - case gfpErr: - code = PR_FILE_SEEK_ERROR; - break; - case fBsyErr: - code = PR_FILE_IS_BUSY_ERROR; - break; - case extFSErr: - code = PR_REMOTE_FILE_ERROR; - break; - case abortErr: - code = PR_PENDING_INTERRUPT_ERROR; - break; - case paramErr: - code = PR_INVALID_ARGUMENT_ERROR; - break; - case unimpErr: - code = PR_NOT_IMPLEMENTED_ERROR; - break; - } - - PR_SetError(code, oserror); -} - -void _MD_IOInterrupt(void) -{ - PRCList *qp; - PRThread *thread, *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT(_PR_MD_GET_INTSOFF() != 0); - - _PR_SLEEPQ_LOCK(me->cpu); - qp = _PR_PAUSEQ(me->cpu).next; - while (qp != &_PR_PAUSEQ(me->cpu)) { - - thread = _PR_THREAD_PTR(qp); - PR_ASSERT(thread->flags & _PR_ON_PAUSEQ); - - qp = qp->next; - - if (thread->md.missedIONotify) { - thread->md.missedIONotify = PR_FALSE; - DoneWaitingOnThisThread(thread); - } - - if (thread->md.missedAsyncNotify) { - thread->md.missedAsyncNotify = PR_FALSE; - AsyncNotify(thread); - } - } - qp = _PR_SLEEPQ(me->cpu).next; - while (qp != &_PR_SLEEPQ(me->cpu)) { - - thread = _PR_THREAD_PTR(qp); - PR_ASSERT(thread->flags & _PR_ON_SLEEPQ); - - qp = qp->next; - - if (thread->md.missedIONotify) { - thread->md.missedIONotify = PR_FALSE; - DoneWaitingOnThisThread(thread); - } - - if (thread->md.missedAsyncNotify) { - thread->md.missedAsyncNotify = PR_FALSE; - AsyncNotify(thread); - } - } - _PR_SLEEPQ_UNLOCK(thread->cpu); -} - -/* -** All PR_read and PR_Write calls are synchronous from caller's perspective. -** They are internally made asynchronous calls. This gives cpu to other -** user threads while the async io is in progress. -*/ -PRInt32 ReadWriteProc(PRFileDesc *fd, void *buf, PRUint32 bytes, IOOperation op) -{ - PRInt32 refNum = fd->secret->md.osfd; - OSErr err; - ExtendedParamBlock pbAsync; - PRThread *me = _PR_MD_CURRENT_THREAD(); - _PRCPU *cpu = _PR_MD_CURRENT_CPU(); - - /* quick hack to allow PR_fprintf, etc to work with stderr, stdin, stdout */ - /* note, if a user chooses "seek" or the like as an operation in another function */ - /* this will not work */ - if (refNum >= 0 && refNum < 3) - { - switch (refNum) - { - case 0: - /* stdin - not on a Mac for now */ - err = paramErr; - goto ErrorExit; - break; - case 1: /* stdout */ - case 2: /* stderr */ - puts(buf); - break; - } - - return (bytes); - } - else - { - static IOCompletionUPP sCompletionUPP = NULL; - - PRBool doingAsync = PR_FALSE; - - /* allocate the callback Universal Procedure Pointer (UPP). This actually allocates - a 32 byte Ptr in the heap, so only do this once - */ - if (!sCompletionUPP) - sCompletionUPP = NewIOCompletionUPP((IOCompletionProcPtr)&AsyncIOCompletion); - - /* grab the thread so we know which one to post to at completion */ - pbAsync.thread = me; - - pbAsync.pb.ioParam.ioCompletion = sCompletionUPP; - pbAsync.pb.ioParam.ioResult = noErr; - pbAsync.pb.ioParam.ioRefNum = refNum; - pbAsync.pb.ioParam.ioBuffer = buf; - pbAsync.pb.ioParam.ioReqCount = bytes; - pbAsync.pb.ioParam.ioPosMode = fsAtMark; - pbAsync.pb.ioParam.ioPosOffset = 0; - - /* - ** Issue the async read call and wait for the io semaphore associated - ** with this thread. - ** Async file system calls *never* return error values, so ignore their - ** results (see ); - ** the completion routine is always called. - */ - me->io_fd = refNum; - me->md.osErrCode = noErr; - if (op == READ_ASYNC) - { - /* - ** Skanky optimization so that reads < 20K are actually done synchronously - ** to optimize performance on small reads (e.g. registry reads on startup) - */ - if ( bytes > 20480L ) - { - doingAsync = PR_TRUE; - me->io_pending = PR_TRUE; - - (void)PBReadAsync(&pbAsync.pb); - } - else - { - pbAsync.pb.ioParam.ioCompletion = NULL; - me->io_pending = PR_FALSE; - - err = PBReadSync(&pbAsync.pb); - if (err != noErr && err != eofErr) - goto ErrorExit; - } - } - else - { - doingAsync = PR_TRUE; - me->io_pending = PR_TRUE; - - /* writes are currently always async */ - (void)PBWriteAsync(&pbAsync.pb); - } - - if (doingAsync) { - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - } - } - - err = me->md.osErrCode; - if (err != noErr) - goto ErrorExit; - - err = pbAsync.pb.ioParam.ioResult; - if (err != noErr && err != eofErr) - goto ErrorExit; - - return pbAsync.pb.ioParam.ioActCount; - -ErrorExit: - me->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -/* -Special WriteSyncProc for logging only. IO occurs synchronously. Otherwise, -logging internal to NSPR causes ReadWriteProc above to recurse on PR_WaitSem logging. -*/ -PRInt32 WriteSyncProc(PRFileDesc *fd, void *buf, PRUint32 bytes) -{ - PRInt32 refNum = fd->secret->md.osfd; - OSErr err; - ParamBlockRec pb; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (refNum >= 0 && refNum < 3) - { - PR_ASSERT(FALSE); /* writing to these is hazardous to a Mac's health (refNum 2 is the system file) */ - err = paramErr; - goto ErrorExit; - } - - pb.ioParam.ioCompletion = NULL; - pb.ioParam.ioResult = noErr; - pb.ioParam.ioRefNum = refNum; - pb.ioParam.ioBuffer = buf; - pb.ioParam.ioReqCount = bytes; - pb.ioParam.ioPosMode = fsAtMark; - pb.ioParam.ioPosOffset = 0; - - err = PBWriteSync(&pb); - - if (err != noErr) - goto ErrorExit; - else - return pb.ioParam.ioActCount; - -ErrorExit: - me->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -/* File I/O functions called by PR I/O routines */ -PRInt32 _MD_Open(const char *path, PRIntn flags, int mode) -{ -// Macintosh doesn't really have mode bits, just drop them -#pragma unused (mode) - - OSErr err; - HParamBlockRec hpb; - ParamBlockRec pb; - char *macFileName = NULL; - Str255 pascalName; - PRInt8 perm; - - err = ConvertUnixPathToMacPath(path, &macFileName); - - if (err != noErr) - goto ErrorExit; - - hpb.ioParam.ioCompletion = NULL; - PStrFromCStr(macFileName, pascalName); - PR_DELETE(macFileName); - hpb.ioParam.ioNamePtr = pascalName; - hpb.ioParam.ioVRefNum = 0; - hpb.ioParam.ioVersNum = 0; - hpb.fileParam.ioDirID = 0; - - if (flags & PR_RDWR) - perm = fsRdWrPerm; - else if (flags & PR_WRONLY) - perm = fsWrPerm; - else - perm = fsRdPerm; - hpb.ioParam.ioPermssn = perm; - - - if (flags & PR_CREATE_FILE) { - err = PBHCreateSync(&hpb); - - /* If opening with the PR_EXCL flag the existence of the file prior to opening is an error */ - if ((flags & PR_EXCL) && (err == dupFNErr)) { - err = PR_FILE_EXISTS_ERROR; - goto ErrorExit; - } - - if ((err != noErr) && (err != dupFNErr)) - goto ErrorExit; - } - - err = PBHOpenDFSync(&hpb); - - if (err != noErr) - goto ErrorExit; - - if (flags & PR_TRUNCATE) { - pb.ioParam.ioCompletion = NULL; - pb.ioParam.ioRefNum = hpb.ioParam.ioRefNum; - pb.ioParam.ioMisc = NULL; - err = PBSetEOFSync(&pb); - if (err != noErr) - goto ErrorExit; - } else if (flags & PR_APPEND) { - pb.ioParam.ioCompletion = NULL; - pb.ioParam.ioRefNum = hpb.ioParam.ioRefNum; - pb.ioParam.ioPosMode = fsFromLEOF; - pb.ioParam.ioPosOffset = 0; - err = PBSetFPosSync(&pb); - if (err != noErr) - goto ErrorExit; - } - return hpb.ioParam.ioRefNum; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -/* _MD_CLOSE_FILE, _MD_READ, _MD_WRITE, _MD_GET_FILE_ERROR are defined in _macos.h */ - -PROffset32 _MD_LSeek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence how) -{ - PRInt32 refNum = fd->secret->md.osfd; - OSErr err = noErr; - long curPos, endPos; - - /* compute new mark */ - switch (how) { - case PR_SEEK_SET: - endPos = offset; - break; - - case PR_SEEK_CUR: - err = GetFPos(refNum, &curPos); - endPos = curPos + offset; - break; - - case PR_SEEK_END: - err = GetEOF(refNum, &curPos); - endPos = curPos + offset; - break; - - default: - err = paramErr; - break; - } - - /* set the new mark and extend the file if seeking beyond current EOF */ - /* making sure to set the mark after any required extend */ - if (err == noErr) { - err = SetFPos(refNum, fsFromStart, endPos); - if (err == eofErr) { - err = SetEOF(refNum, endPos); - if (err == noErr) { - err = SetFPos(refNum, fsFromStart, endPos); - } - } - } - - if (err == noErr) { - return endPos; - } else { - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; - } -} - -PRInt32 _MD_FSync(PRFileDesc *fd) -{ - PRInt32 refNum = fd->secret->md.osfd; - OSErr err; - ParamBlockRec pb; - - pb.ioParam.ioCompletion = NULL; - pb.ioParam.ioRefNum = refNum; - - err = PBFlushFileSync(&pb); - if (err != noErr) - goto ErrorExit; - - return 0; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -#include "plstr.h" - -PRStatus _MD_OpenDir(_MDDir *mdDir,const char *name) -{ - // Emulate the Unix opendir() routine. - - OSErr err; - CInfoPBRec pb; - char *macDirName = NULL; - char *position = NULL; - char volumeName[32]; - Str255 pascalName; - - // Get the Macintosh path - err = ConvertUnixPathToMacPath(name, &macDirName); - if (err != noErr) - goto ErrorExit; - - // Get the vRefNum - position = PL_strchr(macDirName, PR_PATH_SEPARATOR); - if ((position == macDirName) || (position == NULL)) - mdDir->ioVRefNum = 0; // Use application relative searching - else { - memset(volumeName, 0, sizeof(volumeName)); - strncpy(volumeName, macDirName, position-macDirName); - mdDir->ioVRefNum = GetVolumeRefNumFromName(volumeName); - } - - // Get info about the object. - PStrFromCStr(macDirName, pascalName); - PR_DELETE(macDirName); - - pb.dirInfo.ioNamePtr = pascalName; - pb.dirInfo.ioVRefNum = mdDir->ioVRefNum; - pb.dirInfo.ioDrDirID = 0; - pb.dirInfo.ioFDirIndex = 0; - err = PBGetCatInfoSync(&pb); - if (err != noErr) - goto ErrorExit; - - // Are we dealing with a directory? - if ((pb.dirInfo.ioFlAttrib & ioDirMask) == 0) { - err = dirNFErr; - goto ErrorExit; - } - - /* This is a directory, store away the pertinent information. - ** We post increment. I.e. index is always the nth. item we - ** should get on the next call - */ - mdDir->ioDirID = pb.dirInfo.ioDrDirID; - mdDir->currentEntryName = NULL; - mdDir->ioFDirIndex = 1; - return PR_SUCCESS; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return PR_FAILURE; -} - -char *_MD_ReadDir(_MDDir *mdDir, PRIntn flags) -{ - // Emulate the Unix readdir() routine. - - // Mac doesnÕt have the concept of .(PR_SKIP_DOT) & ..(PR_SKIP_DOT_DOT) - - OSErr err; - CInfoPBRec pb; - char *returnedCStr; - Str255 pascalName = "\p"; - PRBool foundEntry; - - PR_ASSERT(mdDir != NULL); - - do { - - // Release the last name read. - PR_DELETE(mdDir->currentEntryName); - mdDir->currentEntryName = NULL; - - // WeÕve got all the info we need, just get info about this guy. - pb.hFileInfo.ioNamePtr = pascalName; - pb.hFileInfo.ioVRefNum = mdDir->ioVRefNum; - pb.hFileInfo.ioFDirIndex = mdDir->ioFDirIndex; - pb.hFileInfo.ioDirID = mdDir->ioDirID; - err = PBGetCatInfoSync(&pb); - if (err != noErr) - goto ErrorExit; - - // Convert the Pascal string to a C string (actual allocation occurs in CStrFromPStr) - CStrFromPStr(pascalName, &returnedCStr); - - mdDir->currentEntryName = returnedCStr; - mdDir->ioFDirIndex++; - - // If it is not a hidden file and the flags did not specify skipping, we are done. - if ((flags & PR_SKIP_HIDDEN) && (pb.hFileInfo.ioFlFndrInfo.fdFlags & fInvisible)) - foundEntry = PR_FALSE; - else - foundEntry = PR_TRUE; - - } while (!foundEntry); - - return (mdDir->currentEntryName); - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return NULL; -} - - -void _MD_CloseDir(_MDDir *mdDir) -{ - // Emulate the Unix closedir() routine - - PR_DELETE(mdDir->currentEntryName); -} - -PRInt32 _MD_MkDir(char *unixPath, PRIntn mode) -{ - HFileParam fpb; - Str255 pascalName = "\p"; - char *cMacPath = NULL; - OSErr err; - - #pragma unused (mode) // Mode is ignored on the Mac - - if (unixPath) { - err = ConvertUnixPathToMacPath(unixPath, &cMacPath); - if (err != noErr) - goto ErrorExit; - - PStrFromCStr(cMacPath, pascalName); - PR_DELETE(cMacPath); - fpb.ioNamePtr = pascalName; - fpb.ioVRefNum = 0; - fpb.ioDirID = 0L; - - err = PBDirCreateSync((HParmBlkPtr)&fpb); - if (err != noErr) - goto ErrorExit; - } - - return 0; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -PRInt32 _MD_Delete(char *unixPath) -{ - HFileParam fpb; - Str255 pascalName = "\p"; - char *cMacPath = NULL; - OSErr err; - - if (unixPath) { - err = ConvertUnixPathToMacPath(unixPath, &cMacPath); - if (err != noErr) - goto ErrorExit; - - PStrFromCStr(cMacPath, pascalName); - PR_DELETE(cMacPath); - fpb.ioNamePtr = pascalName; - fpb.ioVRefNum = 0; - fpb.ioDirID = 0L; - - err = PBHDeleteSync((HParmBlkPtr)&fpb); - if (err != noErr) - goto ErrorExit; - } - - return 0; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -PRInt32 _MD_Rename(char *fromUnixPath, char *toUnixPath) -{ - OSErr err; - FSSpec fromSpec; - FSSpec toSpec; - FSSpec destDirSpec; - FSSpec beforeRenameSpec; - - if (fromUnixPath && toUnixPath) { - err = ConvertUnixPathToFSSpec(fromUnixPath, &fromSpec); - if (err != noErr) - goto ErrorExit; - - err = ConvertUnixPathToFSSpec(toUnixPath, &toSpec); - if (err != noErr && err != fnfErr) - goto ErrorExit; - - /* make an FSSpec for the destination directory */ - err = FSMakeFSSpec(toSpec.vRefNum, toSpec.parID, nil, &destDirSpec); - if (err != noErr) /* parent directory must exist */ - goto ErrorExit; - - // move it to the directory specified - err = FSpCatMove(&fromSpec, &destDirSpec); - if (err != noErr) - goto ErrorExit; - - // make a new FSSpec for the file or directory in its new location - err = FSMakeFSSpec(toSpec.vRefNum, toSpec.parID, fromSpec.name, &beforeRenameSpec); - if (err != noErr) - goto ErrorExit; - - // rename the file or directory - err = FSpRename(&beforeRenameSpec, toSpec.name); - if (err != noErr) - goto ErrorExit; - - } else { - err = paramErr; - goto ErrorExit; - } - - return 0; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -#define kWriteAccessAllowed (0x100) -PRInt32 _MD_Access(char *unixPath, int amode) -{ - // - // Emulate the Unix access routine - // - - OSErr err; - CInfoPBRec pb; - FCBPBRec fcbpb; - char *cMacPath = NULL; - Str255 pascalMacPath; - struct stat info; - - // Convert to a Mac style path - err = ConvertUnixPathToMacPath(unixPath, &cMacPath); - if (err != noErr) - goto ErrorExit; - - err = stat(cMacPath, &info); - if (err != noErr) - goto ErrorExit; - - - // If all weÕre doing is checking for the existence of the file, weÕre out of here. - // On the Mac, if a file exists, you can read from it. - // This doesnÕt handle remote AppleShare volumes. Does it need to? - if ((amode == PR_ACCESS_EXISTS) || (amode == PR_ACCESS_READ_OK)) { - goto success; - } - - PStrFromCStr(cMacPath, pascalMacPath); - - pb.hFileInfo.ioNamePtr = pascalMacPath; - pb.hFileInfo.ioVRefNum = info.st_dev; - pb.hFileInfo.ioDirID = 0; - pb.hFileInfo.ioFDirIndex = 0; - - err = PBGetCatInfoSync(&pb); - if (err != noErr) - goto ErrorExit; - // Check out all the access permissions. - - if (amode == PR_ACCESS_WRITE_OK) { - fcbpb.ioNamePtr = NULL; - fcbpb.ioVRefNum = pb.hFileInfo.ioVRefNum; - fcbpb.ioRefNum = pb.hFileInfo.ioFRefNum; - fcbpb.ioFCBIndx = 0; - - err = PBGetFCBInfoSync(&fcbpb); - if (err != noErr) - goto ErrorExit; - - /* Look at Inside Mac IV-180 */ - if ((fcbpb.ioFCBFlags & kWriteAccessAllowed) == 0) { - err = permErr; - goto ErrorExit; - } - } - -success: - PR_DELETE(cMacPath); - return 0; - -ErrorExit: - if (cMacPath != NULL) - PR_DELETE(cMacPath); - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -PRInt32 _MD_GetFileInfo(char *unixPath, PRFileInfo *info) -{ - CInfoPBRec pb; - OSErr err; - char *cMacPath = NULL; - Str255 pascalMacPath; - PRTime oneMillion, dateInMicroSeconds; - - // Convert to a Mac style path - err = ConvertUnixPathToMacPath(unixPath, &cMacPath); - if (err != noErr) - goto ErrorExit; - - PStrFromCStr(cMacPath, pascalMacPath); - PR_DELETE(cMacPath); - - pb.hFileInfo.ioNamePtr = pascalMacPath; - pb.hFileInfo.ioVRefNum = 0; - pb.hFileInfo.ioDirID = 0; - pb.hFileInfo.ioFDirIndex = 0; - - err = PBGetCatInfoSync(&pb); - if (err != noErr) - goto ErrorExit; - - if (pb.hFileInfo.ioFlAttrib & ioDirMask) { - info->type = PR_FILE_DIRECTORY; - info->size = 0; - } else { - info->type = PR_FILE_FILE; - info->size = pb.hFileInfo.ioFlLgLen + pb.hFileInfo.ioFlRLgLen; - } - - pb.hFileInfo.ioFlCrDat -= gJanuaryFirst1970Seconds; - LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlCrDat); - LL_I2L(oneMillion, PR_USEC_PER_SEC); - LL_MUL(info->creationTime, oneMillion, dateInMicroSeconds); - - pb.hFileInfo.ioFlMdDat -= gJanuaryFirst1970Seconds; - LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlMdDat); - LL_MUL(info->modifyTime, oneMillion, dateInMicroSeconds); - - return 0; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -PRInt32 _MD_GetOpenFileInfo(const PRFileDesc *fd, PRFileInfo *info) -{ - OSErr err; - FCBPBRec fcbpb; - CInfoPBRec pb; - Str255 pascalMacPath; - PRTime oneMillion, dateInMicroSeconds; - - fcbpb.ioNamePtr = pascalMacPath; - fcbpb.ioVRefNum = 0; - fcbpb.ioRefNum = fd->secret->md.osfd; - fcbpb.ioFCBIndx = 0; - - err = PBGetFCBInfoSync(&fcbpb); - if (err != noErr) - goto ErrorExit; - - info->type = PR_FILE_FILE; - info->size = fcbpb.ioFCBEOF; - - pb.hFileInfo.ioNamePtr = pascalMacPath; - pb.hFileInfo.ioVRefNum = fcbpb.ioFCBVRefNum; - pb.hFileInfo.ioDirID = fcbpb.ioFCBParID; - pb.hFileInfo.ioFDirIndex = 0; - - err = PBGetCatInfoSync(&pb); - if (err != noErr) - goto ErrorExit; - - pb.hFileInfo.ioFlCrDat -= gJanuaryFirst1970Seconds; - LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlCrDat); - LL_I2L(oneMillion, PR_USEC_PER_SEC); - LL_MUL(info->creationTime, oneMillion, dateInMicroSeconds); - - pb.hFileInfo.ioFlMdDat -= gJanuaryFirst1970Seconds; - LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlMdDat); - LL_MUL(info->modifyTime, oneMillion, dateInMicroSeconds); - - return 0; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -PRInt32 _MD_Stat(const char *path, struct stat *buf) -{ - OSErr err; - char *macFileName = NULL; - - err = ConvertUnixPathToMacPath(path, &macFileName); - if (err != noErr) - goto ErrorExit; - - err = stat(macFileName, buf); - if (err != noErr) - goto ErrorExit; - - PR_DELETE(macFileName); - - return 0; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return -1; -} - -PRStatus _MD_LockFile(PRInt32 fd) -{ - OSErr err; - FCBPBRec fcbpb; - HFileParam fpb; - Str255 pascalName; - - fcbpb.ioNamePtr = pascalName; - fcbpb.ioVRefNum = 0; - fcbpb.ioRefNum = fd; - fcbpb.ioFCBIndx = 0; - - err = PBGetFCBInfoSync(&fcbpb); - if (err != noErr) - goto ErrorExit; - - fpb.ioCompletion = NULL; - fpb.ioNamePtr = pascalName; - fpb.ioVRefNum = fcbpb.ioFCBVRefNum; - fpb.ioDirID = fcbpb.ioFCBParID; - - err = PBHSetFLockSync((HParmBlkPtr)&fpb); - if (err != noErr) - goto ErrorExit; - - return PR_SUCCESS; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return PR_FAILURE; -} - -PRStatus _MD_TLockFile(PRInt32 fd) -{ - return (_MD_LockFile(fd)); -} - -PRStatus _MD_UnlockFile(PRInt32 fd) -{ - OSErr err; - FCBPBRec fcbpb; - HFileParam fpb; - Str255 pascalName; - - fcbpb.ioNamePtr = pascalName; - fcbpb.ioVRefNum = 0; - fcbpb.ioRefNum = fd; - fcbpb.ioFCBIndx = 0; - - err = PBGetFCBInfoSync(&fcbpb); - if (err != noErr) - goto ErrorExit; - - fpb.ioCompletion = NULL; - fpb.ioNamePtr = pascalName; - fpb.ioVRefNum = fcbpb.ioFCBVRefNum; - fpb.ioDirID = fcbpb.ioFCBParID; - - err = PBHRstFLockSync((HParmBlkPtr)&fpb); - if (err != noErr) - goto ErrorExit; - - return PR_SUCCESS; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return PR_FAILURE; -} - -void SetLogFileTypeCreator(const char *logFile) -{ - HParamBlockRec pb; - OSErr err; - Str31 pName; - - PStrFromCStr(logFile, pName); - pb.fileParam.ioCompletion = nil; - pb.fileParam.ioNamePtr = pName; - pb.fileParam.ioVRefNum = 0; - pb.fileParam.ioFDirIndex = 0; - pb.fileParam.ioDirID = 0; - err = PBHGetFInfoSync(&pb); - PR_ASSERT(err == noErr); - - pb.fileParam.ioDirID = 0; - pb.fileParam.ioFlFndrInfo.fdType = 'TEXT'; - pb.fileParam.ioFlFndrInfo.fdCreator = 'ttxt'; - err = PBHSetFInfoSync(&pb); - PR_ASSERT(err == noErr); -} - -#if DEVELOPER_DEBUG -PR_IMPLEMENT (void) -SetupMacPrintfLog(char *logFile) -{ - /* - * We do _PR_InitLog() twice. The first to force the implicit initialization which - * will set logging to highest levels in _MD_EARLY_INIT. Then, change the env variable - * to disable kernel logging and call _PR_InitLog() again to make it effective. Since - * we are using logging to log test program output, we disable kernel logging to avoid - * all Kernel logging output. - */ -#ifdef PR_INTERNAL_LOGGING - _PR_InitLog(); - _MD_PutEnv("NSPR_LOG_MODULES=clock:0,cmon:0,io:0,mon:0,linker:0,cvar:0,sched:0,thread:0"); - _PR_InitLog(); -#endif - PR_ASSERT(PR_SetLogFile(logFile) == PR_TRUE); - - SetLogFileTypeCreator(logFile); -} -#endif - - -/* -********************** Old name related stuff that is unchanged. ********************** -*/ - -#if !defined(MAC_NSPR_STANDALONE) - -short GetVolumeRefNumFromName(const char *cTgtVolName) -{ - OSErr err; - Str32 pVolName; - char *cVolName = NULL; - HParamBlockRec hPB; - short refNum = 0; - - hPB.volumeParam.ioVolIndex = 0; - hPB.volumeParam.ioNamePtr = pVolName; - do { - hPB.volumeParam.ioVolIndex++; - err = PBHGetVInfoSync(&hPB); - CStrFromPStr(pVolName, &cVolName); - if (strcmp(cTgtVolName, cVolName) == 0) { - refNum = hPB.volumeParam.ioVRefNum; - PR_DELETE(cVolName); - break; - } - PR_DELETE(cVolName); - } while (err == noErr); - - return refNum; -} - -static OSErr CreateMacPathFromUnixPath(const char *unixPath, char **macPath) -{ - // Given a Unix style path with '/' directory separators, this allocates - // a path with Mac style directory separators in the path. - // - // It does not do any special directory translation; use ConvertUnixPathToMacPath - // for that. - - const char *src; - char *tgt; - OSErr err = noErr; - - PR_ASSERT(unixPath != nil); - if (nil == unixPath) { - err = paramErr; - goto exit; - } - - // If unixPath is a zero-length string, we copy ":" into - // macPath, so we need a minimum of two bytes to handle - // the case of ":". - *macPath = malloc(strlen(unixPath) + 2); // Will be enough extra space. - require_action (*macPath != NULL, exit, err = memFullErr;); - - src = unixPath; - tgt = *macPath; - - if (PL_strchr(src, PR_DIRECTORY_SEPARATOR) == src) // If weÕre dealing with an absolute - src++; // path, skip the separator - else - *(tgt++) = PR_PATH_SEPARATOR; - - if (PL_strstr(src, UNIX_THIS_DIRECTORY_STR) == src) // If it starts with / - src += 2; // skip it. - - while (*src) - { // deal with the rest of the path - if (PL_strstr(src, UNIX_PARENT_DIRECTORY_STR) == src) { // Going up? - *(tgt++) = PR_PATH_SEPARATOR; // simply add an extra colon. - src +=3; - } - else if (*src == PR_DIRECTORY_SEPARATOR) { // Change the separator - *(tgt++) = PR_PATH_SEPARATOR; - src++; - } - else - *(tgt++) = *(src++); - } - - *tgt = NULL; // make sure itÕs null terminated. - -exit: - return err; -} - - -static ProcessInfoRec gNavigatorProcInfo; -static FSSpec gGutsFolder; -static FSSpec gNetscapeFolder; - -static OSErr SetupRequiredFSSpecs(void) -{ - OSErr err; - CInfoPBRec pb; - ProcessSerialNumber curPSN = {0, kCurrentProcess}; - - gNavigatorProcInfo.processInfoLength = sizeof(ProcessInfoRec); - gNavigatorProcInfo.processName = NULL; - gNavigatorProcInfo.processAppSpec = &gNetscapeFolder; - - err = GetProcessInformation (&curPSN, &gNavigatorProcInfo); - if (err != noErr) - goto ErrorExit; - - /* guts folder resides at the same place as the app file itself */ - gGutsFolder = gNetscapeFolder; - /* How else do we do this hack??? - * Should NSPR have a string resource for this ? - */ - GetIndString( gGutsFolder.name, 300, 34); - - /* - * vRefNum and parentDirID are now set up correctly for the app file itself. - * parentDirID is the Netscape Folder's ID. Then Find it's parent ID to - * set up the FSSpec and its own name. - */ - - pb.dirInfo.ioCompletion = NULL; - pb.dirInfo.ioNamePtr = gNetscapeFolder.name; - pb.dirInfo.ioVRefNum = gNetscapeFolder.vRefNum; - pb.dirInfo.ioFDirIndex = -1; - pb.dirInfo.ioDrDirID = gNetscapeFolder.parID; - - err = PBGetCatInfoSync(&pb); - if (err != noErr) - goto ErrorExit; - - gNetscapeFolder.parID = pb.dirInfo.ioDrParID; - - return noErr; - -ErrorExit: - return err; -} - -static OSErr FindGutsFolder(FSSpec *foundSpec) -{ - OSErr err; - - if (gNavigatorProcInfo.processInfoLength == 0) { /* Uninitialized? */ - err = SetupRequiredFSSpecs(); - if (err != noErr) - goto ErrorExit; - } - - *foundSpec = gGutsFolder; - - return noErr; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - return err; -} - -static OSErr FindNetscapeFolder(FSSpec *foundSpec) -{ - OSErr err; - - if (gNavigatorProcInfo.processInfoLength == 0) { /* Uninitialized? */ - err = SetupRequiredFSSpecs(); - if (err != noErr) - goto ErrorExit; - } - - *foundSpec = gNetscapeFolder; - - return noErr; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - return err; -} - - -PR_IMPLEMENT (OSErr) -ConvertUnixPathToMacPath(const char *unixPath, char **macPath) -{ - OSErr err = noErr; - - // ******** HACK ALERT ******** - // - // Java really wants long file names (>31 chars). We truncate file names - // greater than 31 characters long. Truncation is from the middle. - // - // Convert UNIX style path names (with . and / separators) into a Macintosh - // style path (with :). - // - // There are also a couple of special paths that need to be dealt with - // by translating them to the appropriate Mac special folders. These include: - // - // /usr/tmp/file => {TempFolder}file - // - // The file conversions we need to do are as follows: - // - // file => file - // dir/file => :dir:file - // ./file => file - // ../file => ::file - // ../dir/file => ::dir:file - // /file => ::BootDrive:file - // /dir/file => ::BootDrive:dir:file - - - if (!strcmp(unixPath, ".")) - { - *macPath = malloc(sizeof(":")); - if (*macPath == NULL) - err = memFullErr; - (*macPath)[0] = ':'; - (*macPath)[1] = '\0'; - } - else - - if (*unixPath != PR_DIRECTORY_SEPARATOR) { // Not root relative, just convert it. - err = CreateMacPathFromUnixPath(unixPath, macPath); - } - - else { - // WeÕre root-relative. This is either a special Unix directory, or a - // full path (which weÕll support on the Mac since they might be generated). - // This is not condoning the use of full-paths on the Macintosh for file - // specification. - - FSSpec foundSpec; - short pathBufferSize; -#if DEBUG - char *temp; -#endif - int tempLen; - - // Are we dealing with the temp folder? - if ((strncmp(unixPath, "/usr/tmp", strlen("/usr/tmp")) == 0) || - ((strncmp(unixPath, "/tmp", strlen("/tmp")) == 0))) { - CInfoPBRec pb; - - unixPath = PL_strchr(unixPath, PR_DIRECTORY_SEPARATOR); - if (strncmp(unixPath, "/tmp", strlen("/tmp")) == 0) // skip past temp spec - unixPath += 5; - else - unixPath += 9; - - err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, // Create if needed - &foundSpec.vRefNum, &foundSpec.parID); - if (err == noErr) { - pb.dirInfo.ioCompletion = NULL; - pb.dirInfo.ioNamePtr = foundSpec.name; - pb.dirInfo.ioVRefNum = foundSpec.vRefNum; - pb.dirInfo.ioFDirIndex = -1; - pb.dirInfo.ioDrDirID = foundSpec.parID; - - err = PBGetCatInfoSync(&pb); - foundSpec.parID = pb.dirInfo.ioDrParID; - } - } - - else if (!strncmp(unixPath, "/usr/local/netscape/", (tempLen = strlen("/usr/local/netscape/")))) { - - unixPath += tempLen; - - if (!strncmp(unixPath, "RequiredGuts/", (tempLen = strlen("RequiredGuts/")))) - { - unixPath += tempLen; - err = FindGutsFolder(&foundSpec); - } - else if (!strncmp(unixPath, "bin/", (tempLen = strlen("bin/")))) - { - unixPath += tempLen; - err = FindNetscapeFolder(&foundSpec); - } - else if (*unixPath == '\0') - { - // it's /usr/local/netscape - err = FindGutsFolder(&foundSpec); - } - - } - - else { - // This is a root relative directory, weÕll just convert the whole thing. - err = CreateMacPathFromUnixPath(unixPath, macPath); - goto Exit_ConvertUnixPathToMacPath; - } - - - - // WeÕre dealing with a special folder - if (err == noErr) - { - Handle hPathStr; - // Get the path to the root-relative directory - err = FSpGetFullPath(&foundSpec, &pathBufferSize, &hPathStr); // NewHandle's hPathStr - - if (noErr == err) - { - // convert handle to c-string - // add one for NULL termination - // pathBufferSize is now one greater than the length of the string - pathBufferSize++; - - *macPath = (char*) malloc(sizeof(char) * pathBufferSize); - (*macPath)[pathBufferSize - 1] = '\0'; - BlockMoveData(*hPathStr, *macPath, pathBufferSize - 1); - - DisposeHandle(hPathStr); - } - } - - if (err == noErr) - { - UInt32 unixPathLeft; - UInt32 macPathLen; - - unixPathLeft = strlen(unixPath); - macPathLen = strlen(*macPath); - - - // copy over the remaining file name, converting - if (pathBufferSize - 1 < macPathLen + unixPathLeft) - { - // need to grow string - *macPath = realloc(*macPath, macPathLen + unixPathLeft + 1); - err = (*macPath == NULL ? memFullErr : noErr); - } - - if (err == noErr) - { - // carefully remove the '/''s out of the unix path. If we see an "escaped" / - // we will leave it in there, otherwise we take it out and replace it with a : - // we have to do this before we convert to a mac-path, so we can tell what is - // really a path separator and what is in the name of a file or directory - // Make sure that all of the /Õs are :Õs in the final pathname - // effectively we do a - // strcat(*macPath, unixPath); while replace all occurrences of / with : in unixPath - char* dp; - const char* sp; - - sp = unixPath; - dp = *macPath + macPathLen; - - for (;*sp != '\0'; sp++, dp++) - { - if (*sp == PR_DIRECTORY_SEPARATOR) - { - // if we can look at the previous character - if (sp > unixPath) - { - // check to see if previous character is an escape - if (sp[-1] == '\\') - { - // leave it in, and cycle - continue; - } - else - { - *dp = PR_PATH_SEPARATOR; - } - } - else - *dp = PR_PATH_SEPARATOR; - } - else - { - // just copy; - *dp = *sp; - } - } - - *dp = '\0'; // NULL terminate *macPath - } -#if DEBUG - // we used to check here, now we check above, we leave this in - // the debug build to make sure we didn't screw up - // Make sure that all of the /Õs are :Õs in the final pathname - for (temp = *macPath + strlen(*macPath) - strlen(unixPath); *temp != '\0'; temp++) { - - if (*temp == PR_DIRECTORY_SEPARATOR) - { - DebugStr("\pFound a slash"); - *temp = PR_PATH_SEPARATOR; - } - } -#endif - } - } - - -Exit_ConvertUnixPathToMacPath: - - return err; -} - -// Hey! Before you delete this "hack" you should look at how it's being -// used by sun-java/netscape/applet/appletStubs.c. -PR_IMPLEMENT (OSErr) -ConvertMacPathToUnixPath(const char *macPath, char **unixPath) -{ - // *** HACK *** - // Get minimal version working - - char *unixPathPtr; - - *unixPath = malloc(strlen(macPath) + 2); // Add one for the front slash, one for null - if (*unixPath == NULL) - return (memFullErr); - - unixPathPtr = *unixPath; - - *unixPathPtr++ = PR_DIRECTORY_SEPARATOR; - - do { - // Translate all colons to slashes - if (*macPath == PR_PATH_SEPARATOR) - *unixPathPtr = PR_DIRECTORY_SEPARATOR; - else - *unixPathPtr = *macPath; - - unixPathPtr++; - macPath++; - } while (*macPath != NULL); - - // Terminate the string - *unixPathPtr = '\0'; - - return (noErr); -} - -OSErr -ConvertUnixPathToFSSpec(const char *unixPath, FSSpec *fileSpec) -{ - char* macPath; - OSErr convertError; - int len; - - convertError = ConvertUnixPathToMacPath(unixPath, &macPath); - if (convertError != noErr) - return convertError; - - len = strlen(macPath); - - if (*macPath == PR_PATH_SEPARATOR) - { - if (len < sizeof(Str255)) - { - short vRefNum; - long dirID; - Str255 pascalMacPath; - - convertError = HGetVol(NULL, &vRefNum, &dirID); - if (convertError == noErr) - { - PStrFromCStr(macPath, pascalMacPath); - convertError = FSMakeFSSpec(vRefNum, dirID, pascalMacPath, fileSpec); - } - } - else - convertError = paramErr; - } - else - { - convertError = FSpLocationFromFullPath(len, macPath, fileSpec); - if (convertError == fnfErr) - { - CInfoPBRec pb; - Str255 pascalMacPath; - OSErr err; - - PStrFromCStr(macPath, pascalMacPath); - /* - FSpLocationFromFullPath does not work for directories unless there is - a ":" at the end. We will make sure of an existence of a directory. - If so, the returned fileSpec is valid from FSpLocationFromFullPath eventhough - it returned an error. - */ - pb.hFileInfo.ioNamePtr = pascalMacPath; - pb.hFileInfo.ioVRefNum = 0; - pb.hFileInfo.ioDirID = 0; - pb.hFileInfo.ioFDirIndex = 0; - - err = PBGetCatInfoSync(&pb); - if (err == noErr) - convertError = noErr; - } - } - - free(macPath); - - return (convertError); -} - - -FILE *_OS_FOPEN(const char *filename, const char *mode) -{ - OSErr err = noErr; - char *macFileName = NULL; - FILE *result; - - err = ConvertUnixPathToMacPath(filename, &macFileName); - if (err != noErr) - goto ErrorExit; - - result = fopen(macFileName, mode); - - PR_DELETE(macFileName); - - return result; - -ErrorExit: - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - _MD_SetError(err); - return NULL; -} - -#else - -short GetVolumeRefNumFromName(const char *cTgtVolName) -{ - OSErr err; - Str32 pVolName; - char *cVolName = NULL; - HParamBlockRec hPB; - short refNum = 0; - - hPB.volumeParam.ioVolIndex = 0; - hPB.volumeParam.ioNamePtr = pVolName; - do { - hPB.volumeParam.ioVolIndex++; - err = PBHGetVInfoSync(&hPB); - CStrFromPStr(pVolName, &cVolName); - if (strcmp(cTgtVolName, cVolName) == 0) { - refNum = hPB.volumeParam.ioVRefNum; - PR_DELETE(cVolName); - break; - } - PR_DELETE(cVolName); - } while (err == noErr); - - return refNum; -} - - - -static OSErr GetFullPath(short vRefNum, long dirID, char **fullPath, int *strSize) -{ - Str255 pascalDirName; - char cDirName[256]; - char *tmpPath = NULL; // needed since sprintf isnÕt safe - CInfoPBRec myPB; - OSErr err = noErr; - - - // get the full path of the temp folder. - *strSize = 256; - *fullPath = NULL; - *fullPath = malloc(*strSize); // How big should this thing be? - require_action (*fullPath != NULL, errorExit, err = memFullErr;); - - tmpPath = malloc(*strSize); - require_action (tmpPath != NULL, errorExit, err = memFullErr;); - - strcpy(*fullPath, ""); // Clear C result - strcpy(tmpPath, ""); - pascalDirName[0] = 0; // Clear Pascal intermediate string - - myPB.dirInfo.ioNamePtr = &pascalDirName[0]; - myPB.dirInfo.ioVRefNum = vRefNum; - myPB.dirInfo.ioDrParID = dirID; - myPB.dirInfo.ioFDirIndex = -1; // Getting info about - - do { - myPB.dirInfo.ioDrDirID = myPB.dirInfo.ioDrParID; - - err = PBGetCatInfoSync(&myPB); - require(err == noErr, errorExit); - - // Move the name into C domain - memcpy(&cDirName, &pascalDirName, 256); - p2cstr((unsigned char *)&cDirName); // Changes in place! - - if ((strlen(cDirName) + strlen(*fullPath)) > *strSize) { - // We need to grow the string, do it in 256 byte chunks - (*strSize) += 256; - *fullPath = PR_REALLOC(*fullPath, *strSize); - require_action (*fullPath != NULL, errorExit, err = memFullErr;); - - tmpPath = PR_REALLOC(tmpPath, *strSize); - require_action (tmpPath != NULL, errorExit, err = memFullErr;); - } - sprintf(tmpPath, "%s:%s", cDirName, *fullPath); - strcpy(*fullPath, tmpPath); - } while (myPB.dirInfo.ioDrDirID != fsRtDirID); - - PR_DELETE(tmpPath); - - return noErr; - - -errorExit: - PR_DELETE(*fullPath); - PR_DELETE(tmpPath); - - return err; - -} - -static OSErr CreateMacPathFromUnixPath(const char *unixPath, char **macPath) -{ - // Given a Unix style path with '/' directory separators, this allocates - // a path with Mac style directory separators in the path. - // - // It does not do any special directory translation; use ConvertUnixPathToMacPath - // for that. - - const char *src; - char *tgt; - OSErr err = noErr; - - PR_ASSERT(unixPath != nil); - if (nil == unixPath) { - err = paramErr; - goto exit; - } - - // If unixPath is a zero-length string, we copy ":" into - // macPath, so we need a minimum of two bytes to handle - // the case of ":". - *macPath = malloc(strlen(unixPath) + 2); // Will be enough extra space. - require_action (*macPath != NULL, exit, err = memFullErr;); - - src = unixPath; - tgt = *macPath; - - if (PL_strchr(src, PR_DIRECTORY_SEPARATOR) == src) // If weÕre dealing with an absolute - src++; // path, skip the separator - else - *(tgt++) = PR_PATH_SEPARATOR; - - if (PL_strstr(src, UNIX_THIS_DIRECTORY_STR) == src) // If it starts with ./ - src += 2; // skip it. - - while (*src) - { // deal with the rest of the path - if (PL_strstr(src, UNIX_PARENT_DIRECTORY_STR) == src) { // Going up? - *(tgt++) = PR_PATH_SEPARATOR; // simply add an extra colon. - src +=3; - } - else if (*src == PR_DIRECTORY_SEPARATOR) { // Change the separator - *(tgt++) = PR_PATH_SEPARATOR; - src++; - } - else - *(tgt++) = *(src++); - } - - *tgt = NULL; // make sure itÕs null terminated. - -exit: - return err; -} - -static OSErr ConvertUnixPathToMacPath(const char *unixPath, char **macPath) -{ - OSErr err = noErr; - - - // - // Convert UNIX style path names (with . and / separators) into a Macintosh - // style path (with :). - // - // There are also a couple of special paths that need to be dealt with - // by translating them to the appropriate Mac special folders. These include: - // - // /usr/tmp/file => {TempFolder}file - // - // The file conversions we need to do are as follows: - // - // file => file - // dir/file => :dir:file - // ./file => file - // ../file => ::file - // ../dir/file => ::dir:file - // /file => ::BootDrive:file - // /dir/file => ::BootDrive:dir:file - - - if (*unixPath != PR_DIRECTORY_SEPARATOR) { // Not root relative, just convert it. - err = CreateMacPathFromUnixPath(unixPath, macPath); - } - - else { - // WeÕre root-relative. This is either a special Unix directory, or a - // full path (which weÕll support on the Mac since they might be generated). - // This is not condoning the use of full-paths on the Macintosh for file - // specification. - - short foundVRefNum; - long foundDirID; - int pathBufferSize; - char *temp; - char isNetscapeDir = false; - - // Are we dealing with the temp folder? - if (strncmp(unixPath, "/usr/tmp", strlen("/usr/tmp")) == 0){ - unixPath += 8; - if (*unixPath == PR_DIRECTORY_SEPARATOR) - unixPath++; // Skip the slash - err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, // Create if needed - &foundVRefNum, &foundDirID); - } - - if (strncmp(unixPath, "/tmp", strlen("/tmp")) == 0) { - unixPath += 4; // Skip the slash - if (*unixPath == PR_DIRECTORY_SEPARATOR) - unixPath++; // Skip the slash - err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, // Create if needed - &foundVRefNum, &foundDirID); - } - - else if (strncmp(unixPath, "/usr", strlen("/usr")) == 0) { - - int usrNetscapePathLen; - - usrNetscapePathLen = strlen("/usr/local/netscape/"); - - if (strncmp(unixPath, "/usr/local/netscape/", usrNetscapePathLen) == 0) { - unixPath += usrNetscapePathLen; -// err = FindPreferencesFolder(&foundVRefNum, &foundDirID); - err = paramErr; - isNetscapeDir = true; - } - - else { - dprintf("Unable to translate Unix file path %s to Mac path\n", unixPath); - err = -1; - goto Exit_ConvertUnixPathToMacPath; - } - - } - - else { - // This is a root relative directory, weÕll just convert the whole thing. - err = CreateMacPathFromUnixPath(unixPath, macPath); - goto Exit_ConvertUnixPathToMacPath; - } - - // WeÕre dealing with a special folder - if (err == noErr) - // Get the path to the root-relative directory - err = GetFullPath(foundVRefNum, foundDirID, macPath, &pathBufferSize); // mallocs macPath - - if (err == noErr){ - - // copy over the remaining file name, converting - if (pathBufferSize < (strlen(*macPath) + strlen(unixPath))) { - // need to grow string - *macPath = PR_REALLOC(*macPath, (strlen(*macPath) + strlen(unixPath) + - (isNetscapeDir ? strlen("Netscape Ä:") : 0))); - err = (*macPath == NULL ? memFullErr : noErr); - } - - if (isNetscapeDir) - strcat(*macPath, "Netscape Ä:"); - - if (err == noErr) - strcat(*macPath, unixPath); - - // Make sure that all of the /Õs are :Õs in the final pathname - - for (temp = *macPath + strlen(*macPath) - strlen(unixPath); *temp != '\0'; temp++) { - if (*temp == PR_DIRECTORY_SEPARATOR) - *temp = PR_PATH_SEPARATOR; - } - - } - } - - -Exit_ConvertUnixPathToMacPath: - - return err; -} - -OSErr -ConvertUnixPathToFSSpec(const char *unixPath, FSSpec *fileSpec) -{ - char* macPath; - OSErr convertError; - int len; - - convertError = ConvertUnixPathToMacPath(unixPath, &macPath); - if (convertError != noErr) - return convertError; - - len = strlen(macPath); - - if (*macPath == PR_PATH_SEPARATOR) - { - if (len < sizeof(Str255)) - { - short vRefNum; - long dirID; - Str255 pascalMacPath; - - convertError = HGetVol(NULL, &vRefNum, &dirID); - if (convertError == noErr) - { - PStrFromCStr(macPath, pascalMacPath); - convertError = FSMakeFSSpec(vRefNum, dirID, pascalMacPath, fileSpec); - } - } - else - convertError = paramErr; - } - else - { - convertError = FSpLocationFromFullPath(len, macPath, fileSpec); - } - - free(macPath); - - return (convertError); -} - - -#endif - -/* - ********************************************************************** - * - * Memory-mapped files are not implementable on the Mac. - * - ********************************************************************** - */ - -PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size) -{ -#pragma unused (fmap, size) - - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -PRInt32 _MD_GetMemMapAlignment(void) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return -1; -} - -void * _MD_MemMap( - PRFileMap *fmap, - PROffset64 offset, - PRUint32 len) -{ -#pragma unused (fmap, offset, len) - - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} - -PRStatus _MD_MemUnmap(void *addr, PRUint32 len) -{ -#pragma unused (addr, len) - - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -PRStatus _MD_CloseFileMap(PRFileMap *fmap) -{ -#pragma unused (fmap) - - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} diff --git a/nsprpub/pr/src/md/mac/macio.h b/nsprpub/pr/src/md/mac/macio.h deleted file mode 100644 index 06b85a9a272..00000000000 --- a/nsprpub/pr/src/md/mac/macio.h +++ /dev/null @@ -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__ */ - diff --git a/nsprpub/pr/src/md/mac/macrng.c b/nsprpub/pr/src/md/mac/macrng.c deleted file mode 100644 index c869cc3d1e3..00000000000 --- a/nsprpub/pr/src/md/mac/macrng.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include "primpl.h" - -extern PRSize _PR_MD_GetRandomNoise( buf, size ) -{ - uint32 c = TickCount(); - return _pr_CopyLowBits((void *)buf, size, &c, sizeof(c)); -} diff --git a/nsprpub/pr/src/md/mac/macsocket.h b/nsprpub/pr/src/md/mac/macsocket.h deleted file mode 100644 index 7e99faf2875..00000000000 --- a/nsprpub/pr/src/md/mac/macsocket.h +++ /dev/null @@ -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 -#include // All the internet typedefs -#include // 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___ */ diff --git a/nsprpub/pr/src/md/mac/macsockotpt.c b/nsprpub/pr/src/md/mac/macsockotpt.c deleted file mode 100644 index b357eea6740..00000000000 --- a/nsprpub/pr/src/md/mac/macsockotpt.c +++ /dev/null @@ -1,2321 +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 ***** */ - -/* This turns on UNIX style errors in OT 1.1 headers */ -#define OTUNIXERRORS 1 - -#include - -#include -#include -#include -#include - -#define GESTALT_OPEN_TPT_PRESENT gestaltOpenTptPresentMask -#define GESTALT_OPEN_TPT_TCP_PRESENT gestaltOpenTptTCPPresentMask - -#include // All the internet typedefs - -#if (UNIVERSAL_INTERFACES_VERSION >= 0x0330) -// for some reason Apple removed this typedef. -typedef struct OTConfiguration OTConfiguration; -#endif - -#include "primpl.h" - -typedef enum SndRcvOpCode { - kSTREAM_SEND, - kSTREAM_RECEIVE, - kDGRAM_SEND, - kDGRAM_RECEIVE -} SndRcvOpCode; - -static struct { - PRLock * lock; - InetSvcRef serviceRef; - PRThread * thread; - void * cookie; -} dnsContext; - - -static pascal void DNSNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie); -static pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie); -static pascal void RawEndpointNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie); - -static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady); - -void -WakeUpNotifiedThread(PRThread *thread, OTResult result); - -extern void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout); -extern void DoneWaitingOnThisThread(PRThread *thread); - -#if TARGET_CARBON -OTClientContextPtr clientContext = NULL; - -#define INIT_OPEN_TRANSPORT() InitOpenTransportInContext(kInitOTForExtensionMask, &clientContext) -#define OT_OPEN_INTERNET_SERVICES(config, flags, err) OTOpenInternetServicesInContext(config, flags, err, clientContext) -#define OT_OPEN_ENDPOINT(config, flags, info, err) OTOpenEndpointInContext(config, flags, info, err, clientContext) - -#else - -#define INIT_OPEN_TRANSPORT() InitOpenTransport() -#define OT_OPEN_INTERNET_SERVICES(config, flags, err) OTOpenInternetServices(config, flags, err) -#define OT_OPEN_ENDPOINT(config, flags, info, err) OTOpenEndpoint(config, flags, info, err) -#endif /* TARGET_CARBON */ - -static OTNotifyUPP DNSNotifierRoutineUPP; -static OTNotifyUPP NotifierRoutineUPP; -static OTNotifyUPP RawEndpointNotifierRoutineUPP; - -void _MD_InitNetAccess() -{ - OSErr err; - OSStatus errOT; - PRBool hasOTTCPIP = PR_FALSE; - PRBool hasOT = PR_FALSE; - long gestaltResult; - - err = Gestalt(gestaltOpenTpt, &gestaltResult); - if (err == noErr) - if (gestaltResult & GESTALT_OPEN_TPT_PRESENT) - hasOT = PR_TRUE; - - if (hasOT) - if (gestaltResult & GESTALT_OPEN_TPT_TCP_PRESENT) - hasOTTCPIP = PR_TRUE; - - PR_ASSERT(hasOTTCPIP == PR_TRUE); - - DNSNotifierRoutineUPP = NewOTNotifyUPP(DNSNotifierRoutine); - NotifierRoutineUPP = NewOTNotifyUPP(NotifierRoutine); - RawEndpointNotifierRoutineUPP = NewOTNotifyUPP(RawEndpointNotifierRoutine); - - errOT = INIT_OPEN_TRANSPORT(); - PR_ASSERT(err == kOTNoError); - - dnsContext.serviceRef = NULL; - dnsContext.lock = PR_NewLock(); - PR_ASSERT(dnsContext.lock != NULL); - - dnsContext.thread = _PR_MD_CURRENT_THREAD(); - dnsContext.cookie = NULL; - -/* XXX Does not handle absence of open tpt and tcp yet! */ -} - -static void _MD_FinishInitNetAccess() -{ - OSStatus errOT; - - if (dnsContext.serviceRef) - return; - - dnsContext.serviceRef = OT_OPEN_INTERNET_SERVICES(kDefaultInternetServicesPath, NULL, &errOT); - if (errOT != kOTNoError) { - dnsContext.serviceRef = NULL; - return; /* no network -- oh well */ - } - - PR_ASSERT((dnsContext.serviceRef != NULL) && (errOT == kOTNoError)); - - /* Install notify function for DNR Address To String completion */ - errOT = OTInstallNotifier(dnsContext.serviceRef, DNSNotifierRoutineUPP, &dnsContext); - PR_ASSERT(errOT == kOTNoError); - - /* Put us into async mode */ - errOT = OTSetAsynchronous(dnsContext.serviceRef); - PR_ASSERT(errOT == kOTNoError); -} - - -static pascal void DNSNotifierRoutine(void * contextPtr, OTEventCode otEvent, OTResult result, void * cookie) -{ -#pragma unused(contextPtr) - _PRCPU * cpu = _PR_MD_CURRENT_CPU(); - OSStatus errOT; - - dnsContext.thread->md.osErrCode = result; - dnsContext.cookie = cookie; - - switch (otEvent) { - case T_DNRSTRINGTOADDRCOMPLETE: - if (_PR_MD_GET_INTSOFF()) { - dnsContext.thread->md.missedIONotify = PR_TRUE; - cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - } else { - DoneWaitingOnThisThread(dnsContext.thread); - } - break; - - case kOTProviderWillClose: - errOT = OTSetSynchronous(dnsContext.serviceRef); - // fall through to kOTProviderIsClosed case - - case kOTProviderIsClosed: - errOT = OTCloseProvider((ProviderRef)dnsContext.serviceRef); - dnsContext.serviceRef = nil; - - if (_PR_MD_GET_INTSOFF()) { - dnsContext.thread->md.missedIONotify = PR_TRUE; - cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - } else { - DoneWaitingOnThisThread(dnsContext.thread); - } - break; - - default: // or else we don't handle the event - PR_ASSERT(otEvent==NULL); - - } - // or else we don't handle the event - - SignalIdleSemaphore(); -} - - -static void macsock_map_error(OSStatus err) -{ - _PR_MD_CURRENT_THREAD()->md.osErrCode = err; - - if (IsEError(err) || (err >= EPERM && err <= ELASTERRNO)) { - switch (IsEError(err) ? OSStatus2E(err) : err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EADDRNOTAVAIL: - PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err); - break; - case EINPROGRESS: - PR_SetError(PR_IN_PROGRESS_ERROR, err); - break; - case EWOULDBLOCK: - case EAGAIN: - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case ETIMEDOUT: - PR_SetError(PR_IO_TIMEOUT_ERROR, err); - break; - case ECONNREFUSED: - PR_SetError(PR_CONNECT_REFUSED_ERROR, err); - break; - case ENETUNREACH: - PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err); - break; - case EADDRINUSE: - PR_SetError(PR_ADDRESS_IN_USE_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - case ENOENT: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; - case ENXIO: - PR_SetError(PR_IO_ERROR, err); - break; - case EPROTOTYPE: - PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err); - break; - case EOPNOTSUPP: - PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } - } else { - PR_ASSERT(IsXTIError(err)); - switch (err) { - case kOTNoDataErr: - case kOTFlowErr: - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } - } -} - -static void PrepareForAsyncCompletion(PRThread * thread, PRInt32 osfd) -{ - thread->io_pending = PR_TRUE; - thread->io_fd = osfd; - thread->md.osErrCode = noErr; -} - - -void -WakeUpNotifiedThread(PRThread *thread, OTResult result) -{ - _PRCPU * cpu = _PR_MD_CURRENT_CPU(); - - if (thread) { - thread->md.osErrCode = result; - if (_PR_MD_GET_INTSOFF()) { - thread->md.missedIONotify = PR_TRUE; - cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - } else { - DoneWaitingOnThisThread(thread); - } - } - - SignalIdleSemaphore(); -} - -// Notification routine -// Async callback routine. -// A5 is OK. Cannot allocate memory here -// Ref: http://gemma.apple.com/techpubs/mac/NetworkingOT/NetworkingWOT-100.html -// -static pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie) -{ - PRFilePrivate *secret = (PRFilePrivate *) contextPtr; - _MDFileDesc * md = &(secret->md); - EndpointRef endpoint = (EndpointRef)secret->md.osfd; - PRThread * readThread = NULL; // also used for 'misc' - PRThread * writeThread = NULL; - OSStatus err; - OTResult resultOT; - TDiscon discon; - - switch (code) - { -// OTLook Events - - case T_LISTEN: // A connection request is available - // If md->doListen is true, then PR_Listen has been - // called on this endpoint; therefore, we're ready to - // accept connections. But we'll do that with PR_Accept - // (which calls OTListen, OTAccept, etc) instead of - // doing it here. - if (md->doListen) { - readThread = secret->md.misc.thread; - secret->md.misc.thread = NULL; - secret->md.misc.cookie = cookie; - break; - } else { - // Reject the connection, we're not listening - OTSndDisconnect(endpoint, NULL); - } - break; - - case T_CONNECT: // Confirmation of a connect request - // cookie = sndCall parameter from OTConnect() - err = OTRcvConnect(endpoint, NULL); - PR_ASSERT(err == kOTNoError); - - // wake up waiting thread, if any. - writeThread = secret->md.write.thread; - secret->md.write.thread = NULL; - secret->md.write.cookie = cookie; - break; - - case T_DATA: // Standard data is available - // Mark this socket as readable. - secret->md.readReady = PR_TRUE; - - // wake up waiting thread, if any - readThread = secret->md.read.thread; - secret->md.read.thread = NULL; - secret->md.read.cookie = cookie; - break; - - case T_EXDATA: // Expedited data is available - PR_ASSERT(!"T_EXDATA Not implemented"); - return; - - case T_DISCONNECT: // A disconnect is available - discon.udata.len = 0; - err = OTRcvDisconnect(endpoint, &discon); - PR_ASSERT(err == kOTNoError); - secret->md.exceptReady = PR_TRUE; // XXX Check this - - md->disconnectError = discon.reason; // save for _MD_mac_get_nonblocking_connect_error - - // wake up waiting threads, if any - result = -3199 - discon.reason; // obtain the negative error code - if ((readThread = secret->md.read.thread) != NULL) { - secret->md.read.thread = NULL; - secret->md.read.cookie = cookie; - } - - if ((writeThread = secret->md.write.thread) != NULL) { - secret->md.write.thread = NULL; - secret->md.write.cookie = cookie; - } - break; - - case T_ERROR: // obsolete/unused in library - PR_ASSERT(!"T_ERROR Not implemented"); - return; - - case T_UDERR: // UDP Send error; clear the error - (void) OTRcvUDErr((EndpointRef) cookie, NULL); - break; - - case T_ORDREL: // An orderly release is available - err = OTRcvOrderlyDisconnect(endpoint); - PR_ASSERT(err == kOTNoError); - secret->md.readReady = PR_TRUE; // mark readable (to emulate bsd sockets) - // remember connection is closed, so we can return 0 on read or receive - secret->md.orderlyDisconnect = PR_TRUE; - - readThread = secret->md.read.thread; - secret->md.read.thread = NULL; - secret->md.read.cookie = cookie; - break; - - case T_GODATA: // Flow control lifted on standard data - secret->md.writeReady = PR_TRUE; - resultOT = OTLook(endpoint); // clear T_GODATA event - PR_ASSERT(resultOT == T_GODATA); - - // wake up waiting thread, if any - writeThread = secret->md.write.thread; - secret->md.write.thread = NULL; - secret->md.write.cookie = cookie; - break; - - case T_GOEXDATA: // Flow control lifted on expedited data - PR_ASSERT(!"T_GOEXDATA Not implemented"); - return; - - case T_REQUEST: // An Incoming request is available - PR_ASSERT(!"T_REQUEST Not implemented"); - return; - - case T_REPLY: // An Incoming reply is available - PR_ASSERT(!"T_REPLY Not implemented"); - return; - - case T_PASSCON: // State is now T_DATAXFER - // OTAccept() complete, receiving endpoint in T_DATAXFER state - // cookie = OTAccept() resRef parameter - break; - - case T_RESET: // Protocol has been reset - PR_ASSERT(!"T_RESET Not implemented"); - return; - -// Async Completion Events - case T_BINDCOMPLETE: - case T_UNBINDCOMPLETE: - case T_ACCEPTCOMPLETE: - case T_OPTMGMTCOMPLETE: - case T_GETPROTADDRCOMPLETE: - readThread = secret->md.misc.thread; - secret->md.misc.thread = NULL; - secret->md.misc.cookie = cookie; - break; - -// case T_OPENCOMPLETE: // we open endpoints in synchronous mode -// case T_REPLYCOMPLETE: -// case T_DISCONNECTCOMPLETE: // we don't call OTSndDisconnect() -// case T_RESOLVEADDRCOMPLETE: -// case T_GETINFOCOMPLETE: -// case T_SYNCCOMPLETE: -// case T_MEMORYRELEASED: // only if OTAckSends() called on endpoint -// case T_REGNAMECOMPLETE: -// case T_DELNAMECOMPLETE: -// case T_LKUPNAMECOMPLETE: -// case T_LKUPNAMERESULT: - // OpenTptInternet.h -// case T_DNRSTRINGTOADDRCOMPLETE: // DNS is handled by dnsContext in DNSNotifierRoutine() -// case T_DNRADDRTONAMECOMPLETE: -// case T_DNRSYSINFOCOMPLETE: -// case T_DNRMAILEXCHANGECOMPLETE: -// case T_DNRQUERYCOMPLETE: - default: - // we should probably have a bit more sophisticated handling of kOTSystemSleep, etc. - // PR_ASSERT(code != 0); - return; - } - - if (readThread) - WakeUpNotifiedThread(readThread, result); - - if (writeThread && (writeThread != readThread)) - WakeUpNotifiedThread(writeThread, result); -} - - -static OSErr CreateSocket(int type, EndpointRef *endpoint) -{ - OSStatus err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - char * configName; - OTConfiguration *config; - EndpointRef ep; - - // for now we just create the endpoint - // we'll make it asynchronous and give it a notifier routine in _MD_makenonblock() - - switch (type){ - case SOCK_STREAM: configName = kTCPName; break; - case SOCK_DGRAM: configName = kUDPName; break; - } - config = OTCreateConfiguration(configName); - ep = OT_OPEN_ENDPOINT(config, 0, NULL, &err); - if (err != kOTNoError) - goto ErrorExit; - - *endpoint = ep; - PR_ASSERT(*endpoint != NULL); - - return kOTNoError; - -ErrorExit: - return err; -} - - -// Errors returned: -// kOTXXXX - OT returned error -// EPROTONOSUPPORT - bad socket type/protocol -// ENOBUFS - not enough space for another socket, or failure in socket creation routine -PRInt32 _MD_socket(int domain, int type, int protocol) -{ - OSStatus err; - EndpointRef endpoint; - - _MD_FinishInitNetAccess(); - - // We only deal with internet domain - if (domain != AF_INET) { - err = kEPROTONOSUPPORTErr; - goto ErrorExit; - } - - // We only know about tcp & udp - if ((type != SOCK_STREAM) && (type != SOCK_DGRAM)) { - err = kEPROTONOSUPPORTErr; - goto ErrorExit; - } - - // Convert default types to specific types. - if (protocol == 0) { - if (type == SOCK_DGRAM) - protocol = IPPROTO_UDP; - else if (type == SOCK_STREAM) - protocol = IPPROTO_TCP; - } - - // Only support default protocol for tcp - if ((type == SOCK_STREAM) && (protocol != IPPROTO_TCP)) { - err = kEPROTONOSUPPORTErr; - goto ErrorExit; - } - - // Only support default protocol for udp - if ((type == SOCK_DGRAM) && (protocol != IPPROTO_UDP)) { - err = kEPROTONOSUPPORTErr; - goto ErrorExit; - } - - // Create a socket, we might run out of memory - err = CreateSocket(type, &endpoint); - if (err != kOTNoError) - goto ErrorExit; - - PR_ASSERT((PRInt32)endpoint != -1); - - return ((PRInt32)endpoint); - -ErrorExit: - macsock_map_error(err); - return -1; -} - - -// Errors: -// EBADF -- bad socket id -// EFAULT -- bad address format -PRInt32 _MD_bind(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen) -{ - OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; - TBind bindReq; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRUint32 retryCount = 0; - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - if (addr == NULL) { - err = kEFAULTErr; - goto ErrorExit; - } - -/* - * There seems to be a bug with OT related to OTBind failing with kOTNoAddressErr even though - * a proper legal address was supplied. This happens very rarely and just retrying the - * operation after a certain time (less than 1 sec. does not work) seems to succeed. - */ - -TryAgain: - // setup our request - bindReq.addr.len = addrlen; - - bindReq.addr.maxlen = addrlen; - bindReq.addr.buf = (UInt8*) addr; - bindReq.qlen = 1; - - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; - - err = OTBind(endpoint, &bindReq, NULL); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); - goto ErrorExit; - } - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - return kOTNoError; - -ErrorExit: - if ((err == kOTNoAddressErr) && (++retryCount <= 4)) { - unsigned long finalTicks; - - Delay(100,&finalTicks); - goto TryAgain; - } - macsock_map_error(err); - return -1; -} - - -// Errors: -// EBADF -- bad socket id -PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog) -{ - PRInt32 osfd = fd->secret->md.osfd; - OSStatus err = 0; - EndpointRef endpoint = (EndpointRef) osfd; - TBind bindReq; - PRNetAddr addr; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if ((fd == NULL) || (endpoint == NULL)) { - err = EBADF; - goto ErrorExit; - } - - if (backlog == 0) - backlog = 1; - - if (endpoint == NULL) { - err = EBADF; - goto ErrorExit; - } - - addr.inet.family = AF_INET; - addr.inet.port = addr.inet.ip = 0; - - bindReq.addr.maxlen = PR_NETADDR_SIZE (&addr); - bindReq.addr.len = 0; - bindReq.addr.buf = (UInt8*) &addr; - bindReq.qlen = 0; - - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; // tell notifier routine what to wake up - - err = OTGetProtAddress(endpoint, &bindReq, NULL); - if (err != kOTNoError) - goto ErrorExit; - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; // tell notifier routine what to wake up - - err = OTUnbind(endpoint); - if (err != kOTNoError) - goto ErrorExit; - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - /* tell the notifier func that we are interested in pending connections */ - fd->secret->md.doListen = PR_TRUE; - /* accept up to (backlog) pending connections at any one time */ - bindReq.qlen = backlog; - - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; // tell notifier routine what to wake up - - err = OTBind(endpoint, &bindReq, NULL); - if (err != kOTNoError) - goto ErrorExit; - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - - err = me->md.osErrCode; - if (err != kOTNoError) - { - // If OTBind failed, we're really not ready to listen after all. - fd->secret->md.doListen = PR_FALSE; - goto ErrorExit; - } - - return kOTNoError; - -ErrorExit: - me->io_pending = PR_FALSE; // clear pending wait state if any - macsock_map_error(err); - return -1; -} - - -// Errors: -// EBADF -- bad socket id -PRInt32 _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) -{ - OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; - TBind bindReq; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - if (addr == NULL) { - err = kEFAULTErr; - goto ErrorExit; - } - - bindReq.addr.len = *addrlen; - bindReq.addr.maxlen = *addrlen; - bindReq.addr.buf = (UInt8*) addr; - bindReq.qlen = 0; - - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; - - err = OTGetProtAddress(endpoint, &bindReq, NULL); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); - goto ErrorExit; - } - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - *addrlen = PR_NETADDR_SIZE(addr); - return kOTNoError; - -ErrorExit: - macsock_map_error(err); - return -1; -} - - -PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen) -{ - OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; - TOptMgmt cmd; - TOption *opt; - PRThread *me = _PR_MD_CURRENT_THREAD(); - unsigned char optionBuffer[kOTOptionHeaderSize + sizeof(PRSocketOptionData)]; - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - /* - OT wants IPPROTO_IP for level and not XTI_GENERIC. SO_REUSEADDR and SO_KEEPALIVE - are equated to IP level and TCP level options respectively and hence we need to set - the level correctly. - */ - if (level == SOL_SOCKET) { - if (optname == SO_REUSEADDR) - level = IPPROTO_IP; - else if (optname == SO_KEEPALIVE) - level = INET_TCP; - } - - opt = (TOption *)&optionBuffer[0]; - opt->len = sizeof(TOption); - opt->level = level; - opt->name = optname; - opt->status = 0; - - cmd.opt.len = sizeof(TOption); - cmd.opt.maxlen = sizeof(optionBuffer); - cmd.opt.buf = (UInt8*)optionBuffer; - cmd.flags = T_CURRENT; - - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; - - err = OTOptionManagement(endpoint, &cmd, &cmd); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); - goto ErrorExit; - } - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - if (opt->status == T_FAILURE || opt->status == T_NOTSUPPORT){ - err = kEOPNOTSUPPErr; - goto ErrorExit; - } - - PR_ASSERT(opt->status == T_SUCCESS); - - switch (optname) { - case SO_LINGER: - *((t_linger*)optval) = *((t_linger*)&opt->value); - *optlen = sizeof(t_linger); - break; - case SO_REUSEADDR: - case TCP_NODELAY: - case SO_KEEPALIVE: - case SO_RCVBUF: - case SO_SNDBUF: - *((PRIntn*)optval) = *((PRIntn*)&opt->value); - *optlen = sizeof(PRIntn); - break; - case IP_MULTICAST_LOOP: - *((PRUint8*)optval) = *((PRIntn*)&opt->value); - *optlen = sizeof(PRUint8); - break; - case IP_TTL: - *((PRUintn*)optval) = *((PRUint8*)&opt->value); - *optlen = sizeof(PRUintn); - break; - case IP_MULTICAST_TTL: - *((PRUint8*)optval) = *((PRUint8*)&opt->value); - *optlen = sizeof(PRUint8); - break; - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - { - /* struct ip_mreq and TIPAddMulticast are the same size and optval - is pointing to struct ip_mreq */ - *((struct ip_mreq *)optval) = *((struct ip_mreq *)&opt->value); - *optlen = sizeof(struct ip_mreq); - break; - } - case IP_MULTICAST_IF: - { - *((PRUint32*)optval) = *((PRUint32*)&opt->value); - *optlen = sizeof(PRUint32); - break; - } - /*case IP_TOS:*/ /*IP_TOS has same value as TCP_MAXSEG */ - case TCP_MAXSEG: - if (level == IPPROTO_TCP) { /* it is TCP_MAXSEG */ - *((PRIntn*)optval) = *((PRIntn*)&opt->value); - *optlen = sizeof(PRIntn); - } else { /* it is IP_TOS */ - *((PRUintn*)optval) = *((PRUint8*)&opt->value); - *optlen = sizeof(PRUintn); - } - break; - default: - PR_ASSERT(0); - break; - } - - return PR_SUCCESS; - -ErrorExit: - macsock_map_error(err); - return PR_FAILURE; -} - - -PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen) -{ - OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; - TOptMgmt cmd; - TOption *opt; - PRThread *me = _PR_MD_CURRENT_THREAD(); - unsigned char optionBuffer[kOTOptionHeaderSize + sizeof(PRSocketOptionData) + 1]; - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - /* - OT wants IPPROTO_IP for level and not XTI_GENERIC. SO_REUSEADDR and SO_KEEPALIVE - are equated to IP level and TCP level options respectively and hence we need to set - the level correctly. - */ - if (level == SOL_SOCKET) { - if (optname == SO_REUSEADDR) - level = IPPROTO_IP; - else if (optname == SO_KEEPALIVE) - level = INET_TCP; - } - - opt = (TOption *)&optionBuffer[0]; - opt->len = kOTOptionHeaderSize + optlen; - - /* special case adjustments for length follow */ - if (optname == SO_KEEPALIVE) /* we need to pass the timeout value for OT */ - opt->len = kOTOptionHeaderSize + sizeof(t_kpalive); - if (optname == IP_MULTICAST_TTL || optname == IP_TTL) /* it is an unsigned char value */ - opt->len = kOTOneByteOptionSize; - if (optname == IP_TOS && level == IPPROTO_IP) - opt->len = kOTOneByteOptionSize; - - opt->level = level; - opt->name = optname; - opt->status = 0; - - cmd.opt.len = opt->len; - cmd.opt.maxlen = sizeof(optionBuffer); - cmd.opt.buf = (UInt8*)optionBuffer; - - optionBuffer[opt->len] = 0; - - cmd.flags = T_NEGOTIATE; - - switch (optname) { - case SO_LINGER: - *((t_linger*)&opt->value) = *((t_linger*)optval); - break; - case SO_REUSEADDR: - case TCP_NODELAY: - case SO_RCVBUF: - case SO_SNDBUF: - *((PRIntn*)&opt->value) = *((PRIntn*)optval); - break; - case IP_MULTICAST_LOOP: - if (*optval != 0) - opt->value[0] = T_YES; - else - opt->value[0] = T_NO; - break; - case SO_KEEPALIVE: - { - t_kpalive *kpalive = (t_kpalive *)&opt->value; - - kpalive->kp_onoff = *((long*)optval); - kpalive->kp_timeout = 10; /* timeout in minutes */ - break; - } - case IP_TTL: - *((unsigned char*)&opt->value) = *((PRUintn*)optval); - break; - case IP_MULTICAST_TTL: - *((unsigned char*)&opt->value) = *optval; - break; - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - { - /* struct ip_mreq and TIPAddMulticast are the same size and optval - is pointing to struct ip_mreq */ - *((TIPAddMulticast *)&opt->value) = *((TIPAddMulticast *)optval); - break; - } - case IP_MULTICAST_IF: - { - *((PRUint32*)&opt->value) = *((PRUint32*)optval); - break; - } - /*case IP_TOS:*/ /*IP_TOS has same value as TCP_MAXSEG */ - case TCP_MAXSEG: - if (level == IPPROTO_TCP) { /* it is TCP_MAXSEG */ - *((PRIntn*)&opt->value) = *((PRIntn*)optval); - } else { /* it is IP_TOS */ - *((unsigned char*)&opt->value) = *((PRUintn*)optval); - } - break; - default: - PR_ASSERT(0); - break; - } - - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; - - err = OTOptionManagement(endpoint, &cmd, &cmd); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); - goto ErrorExit; - } - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - if (opt->status == T_FAILURE || opt->status == T_NOTSUPPORT){ - err = kEOPNOTSUPPErr; - goto ErrorExit; - } - - if (level == IPPROTO_TCP && optname == TCP_MAXSEG && opt->status == T_READONLY) { - err = kEOPNOTSUPPErr; - goto ErrorExit; - } - - PR_ASSERT(opt->status == T_SUCCESS); - - return PR_SUCCESS; - -ErrorExit: - macsock_map_error(err); - return PR_FAILURE; -} - - -PRInt32 _MD_socketavailable(PRFileDesc *fd) -{ - PRInt32 osfd = fd->secret->md.osfd; - OSStatus err; - EndpointRef endpoint = (EndpointRef) osfd; - size_t bytes; - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - bytes = 0; - - err = OTCountDataBytes(endpoint, &bytes); - if ((err == kOTLookErr) || // Not really errors, we just need to do a read, - (err == kOTNoDataErr)) // or there's nothing there. - err = kOTNoError; - - if (err != kOTNoError) - goto ErrorExit; - - return bytes; - -ErrorExit: - macsock_map_error(err); - return -1; -} - - -typedef struct RawEndpointAndThread -{ - PRThread * thread; - EndpointRef endpoint; -} RawEndpointAndThread; - -// Notification routine for raw endpoints not yet attached to a PRFileDesc. -// Async callback routine. -// A5 is OK. Cannot allocate memory here -static pascal void RawEndpointNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie) -{ - RawEndpointAndThread *endthr = (RawEndpointAndThread *) contextPtr; - PRThread * thread = endthr->thread; - EndpointRef * endpoint = endthr->endpoint; - _PRCPU * cpu = _PR_MD_CURRENT_CPU(); - OSStatus err; - OTResult resultOT; - - switch (code) - { -// OTLook Events - - case T_LISTEN: // A connection request is available - PR_ASSERT(!"T_EXDATA not implemented for raw endpoints"); - break; - - case T_CONNECT: // Confirmation of a connect request - // cookie = sndCall parameter from OTConnect() - err = OTRcvConnect(endpoint, NULL); - PR_ASSERT(err == kOTNoError); - - // wake up waiting thread - break; - - case T_DATA: // Standard data is available - break; - - case T_EXDATA: // Expedited data is available - PR_ASSERT(!"T_EXDATA Not implemented for raw endpoints"); - return; - - case T_DISCONNECT: // A disconnect is available - err = OTRcvDisconnect(endpoint, NULL); - PR_ASSERT(err == kOTNoError); - break; - - case T_ERROR: // obsolete/unused in library - PR_ASSERT(!"T_ERROR Not implemented for raw endpoints"); - return; - - case T_UDERR: // UDP Send error; clear the error - (void) OTRcvUDErr((EndpointRef) cookie, NULL); - break; - - case T_ORDREL: // An orderly release is available - err = OTRcvOrderlyDisconnect(endpoint); - PR_ASSERT(err == kOTNoError); - break; - - case T_GODATA: // Flow control lifted on standard data - resultOT = OTLook(endpoint); // clear T_GODATA event - PR_ASSERT(resultOT == T_GODATA); - - // wake up waiting thread, if any - break; - - case T_GOEXDATA: // Flow control lifted on expedited data - PR_ASSERT(!"T_GOEXDATA Not implemented"); - return; - - case T_REQUEST: // An Incoming request is available - PR_ASSERT(!"T_REQUEST Not implemented"); - return; - - case T_REPLY: // An Incoming reply is available - PR_ASSERT(!"T_REPLY Not implemented"); - return; - - case T_PASSCON: // State is now T_DATAXFER - // OTAccept() complete, receiving endpoint in T_DATAXFER state - // cookie = OTAccept() resRef parameter - break; - -// Async Completion Events - case T_BINDCOMPLETE: - case T_UNBINDCOMPLETE: - case T_ACCEPTCOMPLETE: - case T_OPTMGMTCOMPLETE: - case T_GETPROTADDRCOMPLETE: - break; - - // for other OT events, see NotifierRoutine above - default: - return; - } - - if (thread) { - thread->md.osErrCode = result; - if (_PR_MD_GET_INTSOFF()) { - thread->md.asyncNotifyPending = PR_TRUE; - cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - } else { - DoneWaitingOnThisThread(thread); - } - } - - SignalIdleSemaphore(); -} - -PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) -{ - OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - TBind bindReq; - PRNetAddr bindAddr; - PRInt32 newosfd = -1; - TCall call; - PRNetAddr callAddr; - RawEndpointAndThread *endthr = NULL; - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - memset(&call, 0 , sizeof(call)); - - if (addr != NULL) { - call.addr.maxlen = *addrlen; - call.addr.len = *addrlen; - call.addr.buf = (UInt8*) addr; - } else { - call.addr.maxlen = sizeof(callAddr); - call.addr.len = sizeof(callAddr); - call.addr.buf = (UInt8*) &callAddr; - } - - do { - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; - - // Perform the listen. - err = OTListen (endpoint, &call); - if (err == kOTNoError) - break; // got the call information - else if ((!fd->secret->nonblocking) && (err == kOTNoDataErr)) { - WaitOnThisThread(me, timeout); - err = me->md.osErrCode; - if ((err != kOTNoError) && (err != kOTNoDataErr)) - goto ErrorExit; - // we can get kOTNoError here, but still need - // to loop back to call OTListen, in order - // to get call info for OTAccept - } else { - goto ErrorExit; // we're nonblocking, and/or we got an error - } - } - while(1); - - newosfd = _MD_socket(AF_INET, SOCK_STREAM, 0); - if (newosfd == -1) - return -1; - - // Attach the raw endpoint handler to this endpoint for now. - endthr = (RawEndpointAndThread *) PR_Malloc(sizeof(RawEndpointAndThread)); - endthr->thread = me; - endthr->endpoint = (EndpointRef) newosfd; - - err = OTInstallNotifier((ProviderRef) newosfd, RawEndpointNotifierRoutineUPP, endthr); - PR_ASSERT(err == kOTNoError); - - err = OTSetAsynchronous((EndpointRef) newosfd); - PR_ASSERT(err == kOTNoError); - - // Bind to a local port; let the system assign it. - bindAddr.inet.family = AF_INET; - bindAddr.inet.port = bindAddr.inet.ip = 0; - - bindReq.addr.maxlen = PR_NETADDR_SIZE (&bindAddr); - bindReq.addr.len = 0; - bindReq.addr.buf = (UInt8*) &bindAddr; - bindReq.qlen = 0; - - PrepareForAsyncCompletion(me, newosfd); - err = OTBind((EndpointRef) newosfd, &bindReq, NULL); - if (err != kOTNoError) - goto ErrorExit; - - WaitOnThisThread(me, timeout); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - PrepareForAsyncCompletion(me, newosfd); - - err = OTAccept (endpoint, (EndpointRef) newosfd, &call); - if ((err != kOTNoError) && (err != kOTNoDataErr)) - goto ErrorExit; - - WaitOnThisThread(me, timeout); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - if (addrlen != NULL) - *addrlen = call.addr.len; - - // Remove the temporary notifier we installed to set up the new endpoint. - OTRemoveNotifier((EndpointRef) newosfd); - PR_Free(endthr); // free the temporary context we set up for this endpoint - - return newosfd; - -ErrorExit: - me->io_pending = PR_FALSE; // clear pending wait state if any - if (newosfd != -1) - _MD_closesocket(newosfd); - macsock_map_error(err); - return -1; -} - - -PRInt32 _MD_connect(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) -{ - OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - TCall sndCall; - TBind bindReq; - PRNetAddr bindAddr; - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - if (addr == NULL) { - err = kEFAULTErr; - goto ErrorExit; - } - - // Bind to a local port; let the system assign it. - - bindAddr.inet.family = AF_INET; - bindAddr.inet.port = bindAddr.inet.ip = 0; - - bindReq.addr.maxlen = PR_NETADDR_SIZE (&bindAddr); - bindReq.addr.len = 0; - bindReq.addr.buf = (UInt8*) &bindAddr; - bindReq.qlen = 0; - - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; - - err = OTBind(endpoint, &bindReq, NULL); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); - goto ErrorExit; - } - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - memset(&sndCall, 0 , sizeof(sndCall)); - - sndCall.addr.maxlen = addrlen; - sndCall.addr.len = addrlen; - sndCall.addr.buf = (UInt8*) addr; - - if (!fd->secret->nonblocking) { - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - PR_ASSERT(fd->secret->md.write.thread == NULL); - fd->secret->md.write.thread = me; - } - - err = OTConnect (endpoint, &sndCall, NULL); - if (err == kOTNoError) { - PR_ASSERT(!"OTConnect returned kOTNoError in async mode!?!"); - } - if (fd->secret->nonblocking) { - if (err == kOTNoDataErr) - err = EINPROGRESS; - goto ErrorExit; - } else { - if (err != kOTNoError && err != kOTNoDataErr) { - me->io_pending = PR_FALSE; - goto ErrorExit; - } - } - - WaitOnThisThread(me, timeout); - - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - - return kOTNoError; - -ErrorExit: - macsock_map_error(err); - return -1; -} - - -// Errors: -// EBADF -- bad socket id -// EFAULT -- bad buffer -static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout, SndRcvOpCode opCode) -{ - OSStatus err; - OTResult result; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 bytesLeft = amount; - - PR_ASSERT(flags == 0 || - (opCode == kSTREAM_RECEIVE && flags == PR_MSG_PEEK)); - PR_ASSERT(opCode == kSTREAM_SEND || opCode == kSTREAM_RECEIVE); - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - if (buf == NULL) { - err = kEFAULTErr; - goto ErrorExit; - } - - PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == NULL : - fd->secret->md.read.thread == NULL); - - while (bytesLeft > 0) - { - Boolean disabledNotifications = OTEnterNotifier(endpoint); - - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - - if (opCode == kSTREAM_SEND) { - do { - fd->secret->md.write.thread = me; - fd->secret->md.writeReady = PR_FALSE; // expect the worst - result = OTSnd(endpoint, buf, bytesLeft, NULL); - fd->secret->md.writeReady = (result != kOTFlowErr); - if (fd->secret->nonblocking) // hope for the best - break; - else { - - // We drop through on anything other than a blocking write. - if (result != kOTFlowErr) - break; - - // Blocking write, but the pipe is full. Turn notifications on and - // wait for an event, hoping that it's a T_GODATA event. - if (disabledNotifications) { - OTLeaveNotifier(endpoint); - disabledNotifications = false; - } - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - result = me->md.osErrCode; - if (result != kOTNoError) // got interrupted, or some other error - break; - - // Prepare to loop back and try again - disabledNotifications = OTEnterNotifier(endpoint); - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - } - } - while(1); - } else { - do { - fd->secret->md.read.thread = me; - fd->secret->md.readReady = PR_FALSE; // expect the worst - result = OTRcv(endpoint, buf, bytesLeft, NULL); - if (fd->secret->nonblocking) { - fd->secret->md.readReady = (result != kOTNoDataErr); - break; - } else { - if (result != kOTNoDataErr) { - // If we successfully read a blocking socket, check for more data. - // According to IM:OT, we should be able to rely on OTCountDataBytes - // to tell us whether there is a nonzero amount of data pending. - size_t count; - OSErr tmpResult; - tmpResult = OTCountDataBytes(endpoint, &count); - fd->secret->md.readReady = ((tmpResult == kOTNoError) && (count > 0)); - break; - } - - // Blocking read, but no data available. Turn notifications on and - // wait for an event on this endpoint, and hope that we get a T_DATA event. - if (disabledNotifications) { - OTLeaveNotifier(endpoint); - disabledNotifications = false; - } - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - result = me->md.osErrCode; - if (result != kOTNoError) // interrupted thread, etc. - break; - - // Prepare to loop back and try again - disabledNotifications = OTEnterNotifier(endpoint); - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - } - } - // Retry read if we had to wait for data to show up. - while(1); - } - - me->io_pending = PR_FALSE; - - if (opCode == kSTREAM_SEND) - fd->secret->md.write.thread = NULL; - else - fd->secret->md.read.thread = NULL; - - // turn notifications back on - if (disabledNotifications) - OTLeaveNotifier(endpoint); - - if (result > 0) { - buf = (void *) ( (UInt32) buf + (UInt32)result ); - bytesLeft -= result; - if (opCode == kSTREAM_RECEIVE) { - amount = result; - goto NormalExit; - } - } else { - switch (result) { - case kOTLookErr: - PR_ASSERT(!"call to OTLook() required after all."); - break; - - case kOTFlowErr: - case kOTNoDataErr: - case kEAGAINErr: - case kEWOULDBLOCKErr: - if (fd->secret->nonblocking) { - - if (bytesLeft == amount) { // no data was sent - err = result; - goto ErrorExit; - } - - // some data was sent - amount -= bytesLeft; - goto NormalExit; - } - - WaitOnThisThread(me, timeout); - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - break; - - case kOTOutStateErr: // if provider already closed, fall through to handle error - if (fd->secret->md.orderlyDisconnect) { - amount = 0; - goto NormalExit; - } - // else fall through - default: - err = result; - goto ErrorExit; - } - } - } - -NormalExit: - PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == NULL : - fd->secret->md.read.thread == NULL); - return amount; - -ErrorExit: - PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == NULL : - fd->secret->md.read.thread == NULL); - macsock_map_error(err); - return -1; -} - - -PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - return (SendReceiveStream(fd, buf, amount, flags, timeout, kSTREAM_RECEIVE)); -} - - -PRInt32 _MD_send(PRFileDesc *fd,const void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - return (SendReceiveStream(fd, (void *)buf, amount, flags, timeout, kSTREAM_SEND)); -} - - -// Errors: -// EBADF -- bad socket id -// EFAULT -- bad buffer -static PRInt32 SendReceiveDgram(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, - PRIntervalTime timeout, SndRcvOpCode opCode) -{ - OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 bytesLeft = amount; - TUnitData dgram; - - PR_ASSERT(flags == 0); - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - if (buf == NULL || addr == NULL) { - err = kEFAULTErr; - goto ErrorExit; - } - - if (opCode != kDGRAM_SEND && opCode != kDGRAM_RECEIVE) { - err = kEINVALErr; - goto ErrorExit; - } - - memset(&dgram, 0 , sizeof(dgram)); - dgram.addr.maxlen = *addrlen; - dgram.addr.len = *addrlen; - dgram.addr.buf = (UInt8*) addr; - dgram.udata.maxlen = amount; - dgram.udata.len = amount; - dgram.udata.buf = (UInt8*) buf; - - while (bytesLeft > 0) { - - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - - if (opCode == kDGRAM_SEND) { - fd->secret->md.write.thread = me; - fd->secret->md.writeReady = PR_FALSE; // expect the worst - err = OTSndUData(endpoint, &dgram); - if (err != kOTFlowErr) // hope for the best - fd->secret->md.writeReady = PR_TRUE; - } else { - fd->secret->md.read.thread = me; - fd->secret->md.readReady = PR_FALSE; // expect the worst - err = OTRcvUData(endpoint, &dgram, NULL); - if (err != kOTNoDataErr) // hope for the best - fd->secret->md.readReady = PR_TRUE; - } - - if (err == kOTNoError) { - buf = (void *) ( (UInt32) buf + (UInt32)dgram.udata.len ); - bytesLeft -= dgram.udata.len; - dgram.udata.buf = (UInt8*) buf; - me->io_pending = PR_FALSE; - } else { - PR_ASSERT(err == kOTNoDataErr || err == kOTOutStateErr); - WaitOnThisThread(me, timeout); - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - } - } - - if (opCode == kDGRAM_RECEIVE) - *addrlen = dgram.addr.len; - - return amount; - -ErrorExit: - macsock_map_error(err); - return -1; -} - - -PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, - PRIntervalTime timeout) -{ - return (SendReceiveDgram(fd, buf, amount, flags, addr, addrlen, - timeout, kDGRAM_RECEIVE)); -} - - -PRInt32 _MD_sendto(PRFileDesc *fd,const void *buf, PRInt32 amount, - PRIntn flags, PRNetAddr *addr, PRUint32 addrlen, - PRIntervalTime timeout) -{ - return (SendReceiveDgram(fd, (void *)buf, amount, flags, addr, &addrlen, - timeout, kDGRAM_SEND)); -} - - -PRInt32 _MD_closesocket(PRInt32 osfd) -{ - OSStatus err; - EndpointRef endpoint = (EndpointRef) osfd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (endpoint == NULL) { - err = kEBADFErr; - goto ErrorExit; - } - - if (me->io_pending && me->io_fd == osfd) - me->io_pending = PR_FALSE; - - (void) OTSndOrderlyDisconnect(endpoint); - err = OTCloseProvider(endpoint); - if (err != kOTNoError) - goto ErrorExit; - - return kOTNoError; - -ErrorExit: - macsock_map_error(err); - return -1; -} - - -PRInt32 _MD_writev(PRFileDesc *fd, const struct PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout) -{ -#pragma unused (fd, iov, iov_size, timeout) - - PR_ASSERT(0); - _PR_MD_CURRENT_THREAD()->md.osErrCode = unimpErr; - return -1; -} - -// OT endpoint states are documented here: -// http://gemma.apple.com/techpubs/mac/NetworkingOT/NetworkingWOT-27.html#MARKER-9-65 -// -static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady) -{ - OTResult resultOT; - // hack to emulate BSD sockets; say that a socket that has disconnected - // is still readable. - size_t availableData = 1; - if (!fd->secret->md.orderlyDisconnect) - OTCountDataBytes((EndpointRef)fd->secret->md.osfd, &availableData); - - *readReady = fd->secret->md.readReady && (availableData > 0); - *exceptReady = fd->secret->md.exceptReady; - - resultOT = OTGetEndpointState((EndpointRef)fd->secret->md.osfd); - switch (resultOT) { - case T_IDLE: - case T_UNBND: - // the socket is not connected. Emulating BSD sockets, - // we mark it readable and writable. The next PR_Read - // or PR_Write will then fail. Usually, in this situation, - // fd->secret->md.exceptReady is also set, and returned if - // anyone is polling for it. - *readReady = PR_FALSE; - *writeReady = PR_FALSE; - break; - - case T_DATAXFER: // data transfer - *writeReady = fd->secret->md.writeReady; - break; - - case T_INREL: // incoming orderly release - *writeReady = fd->secret->md.writeReady; - break; - - case T_OUTCON: // outgoing connection pending - case T_INCON: // incoming connection pending - case T_OUTREL: // outgoing orderly release - default: - *writeReady = PR_FALSE; - } - - return *readReady || *writeReady || *exceptReady; -} - -// check to see if any of the poll descriptors have data available -// for reading or writing, by calling their poll methods (layered IO). -static PRInt32 CheckPollDescMethods(PRPollDesc *pds, PRIntn npds, PRInt16 *outReadFlags, PRInt16 *outWriteFlags) -{ - PRInt32 ready = 0; - PRPollDesc *pd, *epd; - PRInt16 *readFlag, *writeFlag; - - for (pd = pds, epd = pd + npds, readFlag = outReadFlags, writeFlag = outWriteFlags; - pd < epd; - pd++, readFlag++, writeFlag++) - { - PRInt16 in_flags_read = 0, in_flags_write = 0; - PRInt16 out_flags_read = 0, out_flags_write = 0; - - pd->out_flags = 0; - - if (NULL == pd->fd || pd->in_flags == 0) continue; - - if (pd->in_flags & PR_POLL_READ) - { - in_flags_read = (pd->fd->methods->poll)( - pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); - } - - if (pd->in_flags & PR_POLL_WRITE) - { - in_flags_write = (pd->fd->methods->poll)( - pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); - } - - if ((0 != (in_flags_read & out_flags_read)) || - (0 != (in_flags_write & out_flags_write))) - { - ready += 1; /* some layer has buffer input */ - pd->out_flags = out_flags_read | out_flags_write; - } - - *readFlag = in_flags_read; - *writeFlag = in_flags_write; - } - - return ready; -} - -// check to see if any of OT endpoints of the poll descriptors have data available -// for reading or writing. -static PRInt32 CheckPollDescEndpoints(PRPollDesc *pds, PRIntn npds, const PRInt16 *inReadFlags, const PRInt16 *inWriteFlags) -{ - PRInt32 ready = 0; - PRPollDesc *pd, *epd; - const PRInt16 *readFlag, *writeFlag; - - for (pd = pds, epd = pd + npds, readFlag = inReadFlags, writeFlag = inWriteFlags; - pd < epd; - pd++, readFlag++, writeFlag++) - { - PRFileDesc *bottomFD; - PRBool readReady, writeReady, exceptReady; - PRInt16 in_flags_read = *readFlag; - PRInt16 in_flags_write = *writeFlag; - - if (NULL == pd->fd || pd->in_flags == 0) continue; - - if ((pd->in_flags & ~pd->out_flags) == 0) { - ready++; - continue; - } - - bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - /* bottomFD can be NULL for pollable sockets */ - if (bottomFD) - { - if (_PR_FILEDESC_OPEN == bottomFD->secret->state) - { - if (GetState(bottomFD, &readReady, &writeReady, &exceptReady)) - { - if (readReady) - { - if (in_flags_read & PR_POLL_READ) - pd->out_flags |= PR_POLL_READ; - if (in_flags_write & PR_POLL_READ) - pd->out_flags |= PR_POLL_WRITE; - } - if (writeReady) - { - if (in_flags_read & PR_POLL_WRITE) - pd->out_flags |= PR_POLL_READ; - if (in_flags_write & PR_POLL_WRITE) - pd->out_flags |= PR_POLL_WRITE; - } - if (exceptReady && (pd->in_flags & PR_POLL_EXCEPT)) - { - pd->out_flags |= PR_POLL_EXCEPT; - } - } - if (0 != pd->out_flags) ready++; - } - else /* bad state */ - { - ready += 1; /* this will cause an abrupt return */ - pd->out_flags = PR_POLL_NVAL; /* bogii */ - } - } - } - - return ready; -} - - -// see how many of the poll descriptors are ready -static PRInt32 CountReadyPollDescs(PRPollDesc *pds, PRIntn npds) -{ - PRInt32 ready = 0; - PRPollDesc *pd, *epd; - - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - if (pd->out_flags) - ready ++; - } - - return ready; -} - -// set or clear the poll thread on the poll descriptors -static void SetDescPollThread(PRPollDesc *pds, PRIntn npds, PRThread* thread) -{ - PRInt32 ready = 0; - PRPollDesc *pd, *epd; - - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - if (pd->fd) - { - PRFileDesc *bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - if (bottomFD && (_PR_FILEDESC_OPEN == bottomFD->secret->state)) - { - if (pd->in_flags & PR_POLL_READ) { - PR_ASSERT(thread == NULL || bottomFD->secret->md.read.thread == NULL); - bottomFD->secret->md.read.thread = thread; - } - - if (pd->in_flags & PR_POLL_WRITE) { - // it's possible for the writing thread to be non-null during - // a non-blocking connect, so we assert that we're on - // the same thread, or the thread is null. - // Note that it's strictly possible for the connect and poll - // to be on different threads, so ideally we need to assert - // that if md.write.thread is non-null, there is a non-blocking - // connect in progress. - PR_ASSERT(thread == NULL || - (bottomFD->secret->md.write.thread == NULL || - bottomFD->secret->md.write.thread == thread)); - bottomFD->secret->md.write.thread = thread; - } - } - } - } -} - - -#define DESCRIPTOR_FLAGS_ARRAY_SIZE 32 - -PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - PRInt16 readFlagsArray[DESCRIPTOR_FLAGS_ARRAY_SIZE]; - PRInt16 writeFlagsArray[DESCRIPTOR_FLAGS_ARRAY_SIZE]; - - PRInt16 *readFlags = readFlagsArray; - PRInt16 *writeFlags = writeFlagsArray; - - PRInt16 *ioFlags = NULL; - - PRThread *thread = _PR_MD_CURRENT_THREAD(); - PRInt32 ready; - - if (npds > DESCRIPTOR_FLAGS_ARRAY_SIZE) - { - // we allocate a single double-size array. The first half is used - // for read flags, and the second half for write flags. - ioFlags = (PRInt16*)PR_Malloc(sizeof(PRInt16) * npds * 2); - if (!ioFlags) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - - readFlags = ioFlags; - writeFlags = &ioFlags[npds]; - } - - // we have to be outside the lock when calling this, since - // it can call arbitrary user code (including other socket - // entry points) - ready = CheckPollDescMethods(pds, npds, readFlags, writeFlags); - - if (!ready && timeout != PR_INTERVAL_NO_WAIT) { - intn is; - - - _PR_INTSOFF(is); - PR_Lock(thread->md.asyncIOLock); - PrepareForAsyncCompletion(thread, 0); - - SetDescPollThread(pds, npds, thread); - - (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags); - - PR_Unlock(thread->md.asyncIOLock); - _PR_FAST_INTSON(is); - - ready = CountReadyPollDescs(pds, npds); - - if (ready == 0) { - WaitOnThisThread(thread, timeout); - - // since we may have been woken by a pollable event firing, - // we have to check both poll methods and endpoints. - (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags); - ready = CheckPollDescEndpoints(pds, npds, readFlags, writeFlags); - } - - thread->io_pending = PR_FALSE; - SetDescPollThread(pds, npds, NULL); - } - else { - ready = CheckPollDescEndpoints(pds, npds, readFlags, writeFlags); - } - - if (readFlags != readFlagsArray) - PR_Free(ioFlags); - - return ready; -} - - -void _MD_initfiledesc(PRFileDesc *fd) -{ - // Allocate a PR_Lock to arbitrate miscellaneous OT calls for this endpoint between threads - // We presume that only one thread will be making Read calls (Recv/Accept) and that only - // one thread will be making Write calls (Send/Connect) on the endpoint at a time. - if (fd->methods->file_type == PR_DESC_SOCKET_TCP || - fd->methods->file_type == PR_DESC_SOCKET_UDP ) - { - PR_ASSERT(fd->secret->md.miscLock == NULL); - fd->secret->md.miscLock = PR_NewLock(); - PR_ASSERT(fd->secret->md.miscLock != NULL); - fd->secret->md.orderlyDisconnect = PR_FALSE; - fd->secret->md.readReady = PR_FALSE; // let's not presume we have data ready to read - fd->secret->md.writeReady = PR_TRUE; // let's presume we can write unless we hear otherwise - fd->secret->md.exceptReady = PR_FALSE; - } -} - - -void _MD_freefiledesc(PRFileDesc *fd) -{ - if (fd->secret->md.miscLock) - { - PR_ASSERT(fd->methods->file_type == PR_DESC_SOCKET_TCP || fd->methods->file_type == PR_DESC_SOCKET_UDP); - PR_DestroyLock(fd->secret->md.miscLock); - fd->secret->md.miscLock = NULL; - } else { - PR_ASSERT(fd->methods->file_type != PR_DESC_SOCKET_TCP && PR_DESC_SOCKET_TCP != PR_DESC_SOCKET_UDP); - } -} - -// _MD_makenonblock is also used for sockets meant to be used for blocking I/O, -// in order to install the notifier routine for async completion. -void _MD_makenonblock(PRFileDesc *fd) -{ - // We simulate non-blocking mode using async mode rather - // than put the endpoint in non-blocking mode. - // We need to install the PRFileDesc as the contextPtr for the NotifierRoutine, but it - // didn't exist at the time the endpoint was created. It does now though... - ProviderRef endpointRef = (ProviderRef)fd->secret->md.osfd; - OSStatus err; - - // Install fd->secret as the contextPtr for the Notifier function associated with this - // endpoint. We use this instead of the fd itself because: - // (a) in cases where you import I/O layers, the containing - // fd changes, but the secret structure does not; - // (b) the notifier func refers only to the secret data structure - // anyway. - err = OTInstallNotifier(endpointRef, NotifierRoutineUPP, fd->secret); - PR_ASSERT(err == kOTNoError); - - // Now that we have a NotifierRoutine installed, we can make the endpoint asynchronous - err = OTSetAsynchronous(endpointRef); - PR_ASSERT(err == kOTNoError); -} - - -void _MD_initfdinheritable(PRFileDesc *fd, PRBool imported) -{ - /* XXX this function needs to be implemented */ - fd->secret->inheritable = _PR_TRI_UNKNOWN; -} - - -void _MD_queryfdinheritable(PRFileDesc *fd) -{ - /* XXX this function needs to be implemented */ - PR_ASSERT(0); -} - - -PR_IMPLEMENT(PRInt32) _MD_shutdown(PRFileDesc *fd, PRIntn how) -{ -#pragma unused (fd, how) - -/* Just succeed silently!!! */ -return (0); -} - - -PR_IMPLEMENT(PRStatus) -_MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - EndpointRef ep = (EndpointRef) fd->secret->md.osfd; - InetAddress inetAddr; - TBind peerAddr; - OSErr err; - - if (*addrlen < sizeof(InetAddress)) { - - err = (OSErr) kEINVALErr; - goto ErrorExit; - } - - peerAddr.addr.maxlen = sizeof(InetAddress); - peerAddr.addr.len = 0; - peerAddr.addr.buf = (UInt8*) &inetAddr; - peerAddr.qlen = 0; - - PrepareForAsyncCompletion(me, fd->secret->md.osfd); - fd->secret->md.misc.thread = me; // tell notifier routine what to wake up - - err = OTGetProtAddress(ep, NULL, &peerAddr); - - if (err != kOTNoError) - goto ErrorExit; - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - - err = me->md.osErrCode; - if ((err == kOTNoError) && (peerAddr.addr.len < sizeof(InetAddress))) - err = kEBADFErr; // we don't understand the address we got - if (err != kOTNoError) - goto ErrorExit; - - // Translate the OT peer information into an NSPR address. - addr->inet.family = AF_INET; - addr->inet.port = (PRUint16) inetAddr.fPort; - addr->inet.ip = (PRUint32) inetAddr.fHost; - - *addrlen = PR_NETADDR_SIZE(addr); // return the amount of data obtained - return PR_SUCCESS; - -ErrorExit: - macsock_map_error(err); - return PR_FAILURE; -} - - -PR_IMPLEMENT(unsigned long) inet_addr(const char *cp) -{ - OSStatus err; - InetHost host; - - _MD_FinishInitNetAccess(); - - err = OTInetStringToHost((char*) cp, &host); - if (err != kOTNoError) - return -1; - - return host; -} - - -static char *sAliases[1] = {NULL}; -static struct hostent sHostEnt = {NULL, &sAliases[0], AF_INET, sizeof (long), NULL}; -static InetHostInfo sHostInfo; -static InetHost *sAddresses[kMaxHostAddrs+1]; - - -PR_IMPLEMENT(struct hostent *) gethostbyname(const char * name) -{ - OSStatus err; - PRUint32 index; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - _MD_FinishInitNetAccess(); - - me->io_pending = PR_TRUE; - me->io_fd = NULL; - me->md.osErrCode = noErr; - - PR_Lock(dnsContext.lock); // so we can safely store our thread ptr in dnsContext - dnsContext.thread = me; // so we know what thread to wake up when OTInetStringToAddress completes - - err = OTInetStringToAddress(dnsContext.serviceRef, (char *)name, &sHostInfo); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - me->md.osErrCode = err; - goto ErrorExit; - } - - WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(dnsContext.lock); - - if (me->md.osErrCode != kOTNoError) - goto ErrorExit; - - sHostEnt.h_name = sHostInfo.name; - for (index=0; indexsecret->md.osfd; - OTResult resultOT = OTGetEndpointState(endpoint); - - switch (resultOT) { - case T_OUTCON: - macsock_map_error(EINPROGRESS); - return -1; - - case T_DATAXFER: - return 0; - - case T_IDLE: - macsock_map_error(fd->secret->md.disconnectError); - fd->secret->md.disconnectError = 0; - return -1; - - case T_INREL: - macsock_map_error(ENOTCONN); - return -1; - - default: - PR_ASSERT(0); - return -1; - } - - return -1; // not reached -} diff --git a/nsprpub/pr/src/md/mac/macthr.c b/nsprpub/pr/src/md/mac/macthr.c deleted file mode 100644 index 292389ea8d5..00000000000 --- a/nsprpub/pr/src/md/mac/macthr.c +++ /dev/null @@ -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 - -#include -#include -#include -#include -#include -#include -#include - -#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 /* 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); - } -} - - diff --git a/nsprpub/pr/src/md/mac/mactime.c b/nsprpub/pr/src/md/mac/mactime.c deleted file mode 100644 index 1e7d2a2223c..00000000000 --- a/nsprpub/pr/src/md/mac/mactime.c +++ /dev/null @@ -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 -#include - -#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); -} - - diff --git a/nsprpub/pr/src/md/mac/mactime.h b/nsprpub/pr/src/md/mac/mactime.h deleted file mode 100644 index a78424df594..00000000000 --- a/nsprpub/pr/src/md/mac/mactime.h +++ /dev/null @@ -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__ */ diff --git a/nsprpub/pr/src/md/mac/mdcriticalregion.c b/nsprpub/pr/src/md/mac/mdcriticalregion.c deleted file mode 100644 index 15eea19ad58..00000000000 --- a/nsprpub/pr/src/md/mac/mdcriticalregion.c +++ /dev/null @@ -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 - * - * 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 - -/* - 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; -} - diff --git a/nsprpub/pr/src/md/mac/mdcriticalregion.h b/nsprpub/pr/src/md/mac/mdcriticalregion.h deleted file mode 100644 index abcd20e3b63..00000000000 --- a/nsprpub/pr/src/md/mac/mdcriticalregion.h +++ /dev/null @@ -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 - * - * 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 -#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___ */ - diff --git a/nsprpub/pr/src/md/mac/mdmac.c b/nsprpub/pr/src/md/mac/mdmac.c deleted file mode 100644 index cda67fb78e2..00000000000 --- a/nsprpub/pr/src/md/mac/mdmac.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#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; -} diff --git a/nsprpub/pr/src/md/mac/mdmac.h b/nsprpub/pr/src/md/mac/mdmac.h deleted file mode 100644 index ad8c3c4d170..00000000000 --- a/nsprpub/pr/src/md/mac/mdmac.h +++ /dev/null @@ -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__ */ diff --git a/nsprpub/pr/src/md/mac/prcpucfg.h b/nsprpub/pr/src/md/mac/prcpucfg.h deleted file mode 100644 index 17d665c65db..00000000000 --- a/nsprpub/pr/src/md/mac/prcpucfg.h +++ /dev/null @@ -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___ */ diff --git a/nsprpub/pr/src/md/windows/ntmisc.c b/nsprpub/pr/src/md/windows/ntmisc.c index b8c09de635a..a62720cfbb5 100644 --- a/nsprpub/pr/src/md/windows/ntmisc.c +++ b/nsprpub/pr/src/md/windows/ntmisc.c @@ -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( diff --git a/nsprpub/pr/src/md/windows/w95io.c b/nsprpub/pr/src/md/windows/w95io.c index db6d0cfa690..41e1635ab3f 100644 --- a/nsprpub/pr/src/md/windows/w95io.c +++ b/nsprpub/pr/src/md/windows/w95io.c @@ -49,6 +49,100 @@ #include #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)