landtransport.c

Go to the documentation of this file.
00001 
00002 /*  $Id: landtransport.c 355 2005-01-11 22:48:55Z andreradke $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 /* file:        IPCLib.c
00029 -- desc:        Implements Interface to the IPC driver.
00030 -- version:     V1.0
00031 -- by:          Don Park
00032 -- when:        November 1988
00033 
00034 -- implementation notes:
00035 --
00036 -- 1.   Only Macintosh applications are allowed to be a Process.  A Process is
00037 --      identified by an unformatted Pascal String and by a unique PID (Process
00038 --      ID).  PID is allocated during runtime.
00039 -- 2.   To allow variable length Messages, Handles are used to store Messages.
00040 -- 3.   All Message handles are initially allocated in the source application
00041 --      heapzone and passed to a device driver named ".IPC" which will create
00042 --      a copy in System heap.  System heap will expand and contract so there
00043 --      is no danger in congesting the System heap with message handles.
00044 -- 4.   Message handles can be deallocated right after calling ipcSend() or it
00045 --      can be kept around and reused later.
00046 -- 5.   IPC Manager routines should NOT be called from Completion Routines, VBL
00047 --      tasks, Time Manager tasks, and Interrupt Service Routines.  Even if the
00048 --      application global area access is controled via imbedding register A5,
00049 --      ipcReceive relies on the current application heapzone to be that of the
00050 --      receiver's.  Other IPC routines are currently safe but this might change.
00051 --
00052 -- terms:   Following terms apply only within the context of IPC communication.
00053 --
00054 --      Process:    an application identified by a unique Pascal string.  No
00055 --                  desk accessory, driver, or code resources are allowed.
00056 --      Message:    a packet of unformatted data stored in a handle.
00057 --
00058 -- data types:
00059 --
00060 --      PIN:    Process Identifier Name (Pascal String)
00061 --      PID:    Process ID (long)
00062 --
00063 -- routines:
00064 --
00065 --      ipcOpen()       - Register a Process using its PIN and get its PID
00066 --      ipcClose()      - Unregister a Process using its PID.
00067 --      ipcFind()       - Find a Process using its PIN.
00068 --      ipcWho()        - Return a Process's name.
00069 --
00070 --      ipcSend()       - Send a Message Handle.
00071 --      ipcReceive()    - Receive a Message Handle.
00072 --      ipcClear()      - Flush all Messages sent to a specific PID.
00073 --      ipcError()      - Return current error code.
00074 --
00075 -- see:     Inside Switcher (on accessing another application's heapzone)
00076 -- hist:    30Nov88 V1.0 DDP    New.
00077 */
00078 
00079 #include <land.h>
00080 
00081 #ifdef MPWC
00082 
00083 #include <devices.h>
00084 
00085 #endif
00086 
00087 #include "landtransport.h"
00088 #include "ipcdriver.h"
00089 
00090 /*------------------------- PRIVATE Structures -------------------------------*/
00091 /*--------------------------- PRIVATE Globals --------------------------------*/
00092 #ifdef GLOBALSOK
00093 OSErr   _ipcErr;        /* last IPC error code */
00094 #endif
00095 
00096 
00097 #define _ipcRefNum  (**(landgetglobals ())).ipcrefnum       /* IPC driver's refnum */
00098 
00099 
00100 pascal char *landgetipcdrivername (void);
00101 
00102 /*------------------------- Function Prototypes ------------------------------*/
00103 
00104 static OSErr    _ipcControl         ( short, _IPCParam* );
00105 
00106 /*---------------------------- PUBLIC Routines ------------------------------*/
00107 
00108 /* name:    ipcOpen()
00109 -- desc:    Register a named Process, installing the IPC driver if is not open
00110 --          already.
00111 -- impl:    Locate the IPC driver and remember its refnum.
00112 --          Send csOpnIPCPrc control call to IPC driver.
00113 --          Return process's PID.
00114 */
00115     OSErr               /* <- Error Code */
00116 ipcOpen (
00117     PIN*    pin,        /* -> Name of Client Process Name (Pascal string) */
00118     PID*    _pid)       /* <- New Client Process ID */
00119 {
00120     register OSErr  err;        /* error code */
00121     _IPCParam       ipcPB;      /* IPC Parameter Block for _ipcControl() */
00122     short           refnum;
00123 
00124     /* Locate the IPC driver and remember its refnum */
00125     if (!(err = OpenDriver((ConstStr255Param)landgetipcdrivername(), &refnum))) {
00126         
00127         (**(landgetglobals ())).ipcrefnum = refnum;
00128 
00129         /* send csOpnIPCPrc control call to IPC driver to register self */
00130         ipcPB.pin = pin;
00131         if (!(err = _ipcControl(csOpnIPCPrc, &ipcPB)))
00132             if (_pid)               /* return process's PID */
00133                 *_pid = ipcPB.pid;
00134     }
00135     
00136 #ifdef GLOBALSOK
00137     return (_ipcErr = err);
00138 #else
00139     return (err);
00140 #endif
00141 }
00142 
00143 /* name:    ipcClose()
00144 -- desc:    Close a Process and remove its name from the IPC process table.
00145 -- impl:    Call IPC driver with csClsIPCPrc control code.
00146 */
00147     OSErr               /* <- Error Code */
00148 ipcClose (
00149     PID     pid)        /* -> PID of Process to be closed */
00150 {
00151     _IPCParam   ipcPB;      /* IPC Parameter Block for _ipcControl() */
00152 
00153     ipcPB.pid = pid;
00154 
00155 #ifdef GLOBALSOK
00156     return (_ipcErr = _ipcControl(csClsIPCPrc, &ipcPB));
00157 #else
00158      return (_ipcControl(csClsIPCPrc, &ipcPB));
00159 #endif
00160 }
00161 
00162 /* name:    ipcFind()
00163 --          Find a named Process and return its PID.
00164 -- impl:    Call IPC driver with csFndIPCPrc control code.
00165 */
00166     OSErr               /* <- Error Code */
00167 ipcFind (
00168     PIN*    pin,        /* -> Name of Target Process Name (Pascal string) */
00169     PID*    _pid)       /* <- Target Process ID */
00170 {
00171     OSErr       err;        /* error code */
00172     _IPCParam   ipcPB;      /* IPC Parameter Block for _ipcControl() */
00173 
00174     ipcPB.pin = pin;
00175     if (!(err = _ipcControl(csFndIPCPrc, &ipcPB)) && _pid)
00176         *_pid = ipcPB.pid;
00177 
00178 #ifdef GLOBALSOK
00179     return (_ipcErr = err);
00180 #else
00181     return (err);
00182 #endif
00183 }
00184 
00185 /* name:    ipcWho()
00186 -- desc:    Return a Process's name.
00187 -- impl:    Call IPC driver with csFndIPCPrc control code.
00188 */
00189     OSErr               /* <- Error Code */
00190 ipcWho (
00191     PID     pid,        /* -> Process ID */
00192     PIN*    _pin)       /* <- Name of Target Process Name (Pascal string) */
00193 {
00194     _IPCParam   ipcPB;      /* IPC Parameter Block for _ipcControl() */
00195 
00196     ipcPB.pid = pid;
00197     ipcPB.pin = _pin;
00198 
00199 #ifdef  GLOBALSOK
00200     return (_ipcErr = _ipcControl(csWhoIPCPrc, &ipcPB));
00201 #else
00202     return (_ipcControl(csWhoIPCPrc, &ipcPB));
00203 #endif
00204 }
00205 
00206 /* name:    ipcSend()
00207 -- desc:    Send a Message handle to another Process.
00208 -- note:    Caller is responsible for allocating the Message handle.  Allocate
00209 --              it in your application heap.  The handle can be deallocated using
00210 --              DisposHandle() when this function returns.
00211 -- impl:    Setup _IPCParam fields
00212 --              Call csSndIPCMsg to the IPC driver
00213 */
00214     OSErr               /* <- Error Code */
00215 ipcSend (
00216     PID     sender,     /* -> PID of Process sending Message handle */
00217     PID     receiver,   /* -> PID of Process receiving Message handle */
00218     Handle  message)    /* -> Message handle (can not be 0L) */
00219 {
00220     _IPCParam   ipcPB;      /* IPC Parameter Block for _ipcControl() */
00221 
00222     ipcPB.sender = sender;
00223     ipcPB.receiver = receiver;
00224     ipcPB.message = message;
00225 
00226 #ifdef GLOBALSOK
00227     return (_ipcErr = _ipcControl(csSndIPCMsg, &ipcPB));
00228 #else
00229     return (_ipcControl(csSndIPCMsg, &ipcPB));
00230 #endif
00231 }
00232 
00233 /* name:    ipcReceive()
00234 -- desc:    Receive a Message handle from another Process.
00235 -- note:    Receiver is responsible for deallocating the Message handle.
00236 --          If returned message handle is NIL then nothing was received.  
00237 -- impl:    Setup _IPCParam fields
00238 --          Call csRcvIPCMsg to the IPC driver
00239 */
00240     OSErr               /* <- Error Code */
00241 ipcReceive (
00242     PID     receiver,   /* -> PID of Process receiving Message handle */
00243     PID*    _sender,    /* <- PID of Process sending Message handle */
00244     Handle* _msg)       /* <- Message handle (can not be 0L) */
00245 {
00246     OSErr       err;        /* error code */
00247     _IPCParam   ipcPB;      /* IPC Parameter Block for _ipcControl() */
00248 
00249     ipcPB.receiver = receiver;
00250     if (!(err = _ipcControl(csRcvIPCMsg, &ipcPB)))  {
00251         if (_sender)
00252             *_sender = ipcPB.sender;
00253         if (_msg)
00254             *_msg = ipcPB.message;
00255     }
00256 #ifdef GLOBALSOK
00257     return (_ipcErr = err);
00258 #else
00259     return (err);
00260 #endif
00261 }
00262 
00263 /* name:    ipcClear()
00264 -- desc:    Clear all Messages sent to a Process.
00265 -- note:    Use this routine only to flush Messages sent to your own Process.
00266 --          Do NOT pass other Process's PID.
00267 -- impl:    Setup _IPCParam fields
00268 --          Call csClrIPCMsg to the IPC driver
00269 */
00270     OSErr               /* <- Error Code */
00271 ipcClear (
00272     PID     receiver)   /* -> PID of Process receiving Message handle */
00273 {
00274     _IPCParam   ipcPB;      /* IPC Parameter Block for _ipcControl() */
00275 
00276     ipcPB.receiver = receiver;
00277 
00278 #ifdef GLOBALSOK
00279     return (_ipcErr = _ipcControl(csClrIPCMsg, &ipcPB));
00280 #else
00281     return (_ipcControl(csClrIPCMsg, &ipcPB));
00282 #endif
00283 }
00284 
00285 
00286 #ifdef GLOBALSOK
00287 /* name:    ipcError()
00288 -- desc:    Return current error status for Dave.
00289 -- note:    Dave, although you might prefer obtaining error codes using a
00290 --          separate function, some programmers might want it returned from the
00291 --          function that caused the error.  I have decided to return the error
00292 --          code, because you can just ignore the returned error code or use it
00293 --          as Boolean value which is TRUE if an error occured.  Don't worry,
00294 --          adding '!' to each function call does not add any extra code in
00295 --          both THINK C and in MPW C.
00296 -- impl:    return error code from local global _ipcErr.
00297 */
00298     OSErr               /* <- Error Code */
00299 ipcError ( )
00300 {
00301     return _ipcErr;
00302 }
00303 #endif
00304 
00305 /*--------------------------- PRIVATE Routines -------------------------------*/
00306 
00307 /* name:    _ipcControl()
00308 -- desc:    Send a control code and a _IPCParam to IPC driver
00309 -- impl:    set up CntrlParam fields.
00310 --          if there is a _IPCParam block to be sent, copy it into CntrlParam.
00311 --          call PBControl to IPC driver.
00312 --          if no error and there is a _IPCParam block, copy result into it.
00313 */
00314     OSErr                   /* <- Error Code */
00315 _ipcControl (
00316     short       csCode,     /* -> control selector code */
00317     _IPCParam*  ipcParam)   /* -> IPC Parameter Block */
00318 {
00319     OSErr       err;        /* error code from PBControl() */
00320     CntrlParam  ctrlPB;     /* Parameter Block for PBControl() call */
00321 
00322     ctrlPB.ioVRefNum = 0;           /* no drive number */
00323 
00324 #ifdef FOOBAR   
00325 #ifdef THINKC
00326 
00327     ctrlPB.ioRefNum = _ipcRefNum;   /* IPC driver refnum */
00328     
00329     ctrlPB.csCode = csCode;         /* control selector code */
00330     if (ipcParam)
00331         BlockMove((Ptr) ipcParam, (Ptr) &ctrlPB.csParam, sizeof(_IPCParam));
00332     if (!(err = PBControl((Ptr) &ctrlPB, false)) && ipcParam)
00333         BlockMove((Ptr) &ctrlPB.csParam, (Ptr) ipcParam, sizeof(_IPCParam));
00334 #endif
00335 #endif
00336 
00337 #ifndef MPWCX
00338 
00339     ctrlPB.ioCRefNum = _ipcRefNum; /* IPC driver refnum */
00340     
00341     ctrlPB.csCode = csCode;         /* control selector code */
00342     
00343     if (ipcParam)
00344         BlockMove((Ptr) ipcParam, (Ptr) ctrlPB.csParam, sizeof(_IPCParam));
00345     
00346     err = PBControl((ParmBlkPtr) &ctrlPB, false);
00347     
00348     if (!(err) && ipcParam)
00349         BlockMove((Ptr) ctrlPB.csParam, (Ptr) ipcParam, sizeof(_IPCParam));
00350 #endif
00351 
00352     return err;
00353 }
00354 

Generated on Wed May 31 18:19:50 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6