1 /*********************************************************************
2 Project : GUSI - Grand Unified Socket Interface
3 File : GUSI_P.h - Private stuff
4 Author : Matthias Neeracher
8 Revision 1.1 2000/09/12 20:24:46 jack
11 Revision 1.1 1998/08/18 14:52:33 jack
12 Putting Python-specific GUSI modifications under CVS.
14 Revision 1.3 1994/12/31 01:30:26 neeri
15 Reorganize filename dispatching.
17 Revision 1.2 1994/08/10 00:41:05 neeri
18 Sanitized for universal headers.
20 Revision 1.1 1994/02/25 02:57:01 neeri
23 Revision 0.22 1993/07/17 00:00:00 neeri
24 GUSIRingBuffer::proc -> defproc
26 Revision 0.21 1993/07/17 00:00:00 neeri
27 GUSIO_MAX_DOMAIN -> AF_MAX
29 Revision 0.20 1993/06/27 00:00:00 neeri
30 Socket::{pre,post}_select
32 Revision 0.19 1993/06/27 00:00:00 neeri
35 Revision 0.18 1993/02/09 00:00:00 neeri
36 Socket::lurking, Socket::lurkdescr
38 Revision 0.17 1993/01/31 00:00:00 neeri
39 GUSIConfiguration::daemon
41 Revision 0.16 1993/01/17 00:00:00 neeri
42 Destructors for Socketdomain
44 Revision 0.15 1993/01/17 00:00:00 neeri
47 Revision 0.14 1993/01/03 00:00:00 neeri
50 Revision 0.13 1992/09/24 00:00:00 neeri
53 Revision 0.12 1992/09/13 00:00:00 neeri
54 SPINVOID didn't return
56 Revision 0.11 1992/08/30 00:00:00 neeri
59 Revision 0.10 1992/08/03 00:00:00 neeri
62 Revision 0.9 1992/07/30 00:00:00 neeri
65 Revision 0.8 1992/07/26 00:00:00 neeri
68 Revision 0.7 1992/07/13 00:00:00 neeri
69 Make AppleTalkSockets global
71 Revision 0.6 1992/06/27 00:00:00 neeri
74 Revision 0.5 1992/06/07 00:00:00 neeri
77 Revision 0.4 1992/05/21 00:00:00 neeri
80 Revision 0.3 1992/04/19 00:00:00 neeri
83 Revision 0.2 1992/04/18 00:00:00 neeri
84 changed read/write/send/recv dispatchers
86 Revision 0.1 1992/04/18 00:00:00 neeri
89 *********************************************************************/
94 #define __useAppleExts__
97 #include <GUSIRsrc_P.h>
98 #include <TFileSpec.h>
101 #include <sys/errno.h>
103 #include <sys/socket.h>
110 int GUSI_error(int err
);
111 void * GUSI_error_nil(int err
);
117 #include <AppleEvents.h>
118 #include <Processes.h>
119 #include <MixedMode.h>
129 #define GUSI_MAX_DOMAIN AF_MAX
130 #define DEFAULT_BUFFER_SIZE 4096
133 * In use and shutdown status.
135 #define SOCK_STATUS_USED 0x1 /* Used socket table entry */
136 #define SOCK_STATUS_NOREAD 0x2 /* No more reading allowed from socket */
137 #define SOCK_STATUS_NOWRITE 0x4 /* No more writing allowed to socket */
140 * Socket connection states.
142 #define SOCK_STATE_NO_STREAM 0 /* Socket doesn't have a MacTCP stream yet */
143 #define SOCK_STATE_UNCONNECTED 1 /* Socket is unconnected. */
144 #define SOCK_STATE_LISTENING 2 /* Socket is listening for connection. */
145 #define SOCK_STATE_LIS_CON 3 /* Socket is in transition from listen to connected. */
146 #define SOCK_STATE_CONNECTING 4 /* Socket is initiating a connection. */
147 #define SOCK_STATE_CONNECTED 5 /* Socket is connected. */
148 #define SOCK_STATE_CLOSING 6 /* Socket is closing */
149 #define SOCK_STATE_LIS_CLOSE 7 /* Socket closed while listening */
151 #define min(a,b) ( (a) < (b) ? (a) : (b))
152 #define max(a,b) ( (a) > (b) ? (a) : (b))
154 extern GUSISpinFn GUSISpin
;
155 extern "C" int GUSIDefaultSpin(spin_msg
, long);
156 extern int GUSICheckAlarm();
158 #define GUSI_INTERRUPT(mesg,param) (GUSICheckAlarm() || (GUSISpin && (*GUSISpin)(mesg,param)))
160 /* SPIN returns a -1 on user cancel for fn returning integers */
161 #define SPIN(cond,mesg,param) \
163 if (GUSI_INTERRUPT(mesg,param)) \
164 return GUSI_error(EINTR); \
167 /* SPINP returns a NULL on user cancel, for fn returning pointers */
168 #define SPINP(cond,mesg,param) \
170 if (GUSI_INTERRUPT(mesg,param)) { \
176 /* SPINVOID just returns on user cancel, for fn returning void */
177 #define SPINVOID(cond,mesg,param) \
179 if (GUSI_INTERRUPT(mesg,param)) { \
185 /* SAFESPIN doesn't return, you have to check errno */
186 #define SAFESPIN(cond,mesg,param) \
188 if (GUSI_INTERRUPT(mesg,param)) { \
196 // Library functions are never allowed to clear errno, so we have to save
200 ErrnoSaver() { fSavedErrno
= ::errno
; ::errno
= 0; }
201 ~ErrnoSaver() { if (!::errno
) ::errno
= fSavedErrno
; }
206 #define SAVE_AND_CLEAR_ERRNO ErrnoSaver saveErrno
210 #if PRAGMA_ALIGN_SUPPORTED
211 #pragma options align=mac68k
215 friend class SocketTable
;
221 virtual int bind(void * name
, int namelen
);
222 virtual int connect(void * address
, int addrlen
);
223 virtual int listen(int qlen
);
224 virtual Socket
* accept(void * address
, int * addrlen
);
225 virtual int read(void * buffer
, int buflen
);
226 virtual int write(void * buffer
, int buflen
);
227 virtual int recvfrom(void * buffer
, int buflen
, int flags
, void * from
, int * fromlen
);
228 virtual int sendto(void * buffer
, int buflen
, int flags
, void * to
, int tolen
);
229 virtual int getsockname(void * name
, int * namelen
);
230 virtual int getpeername(void * name
, int * namelen
);
231 virtual int getsockopt(int level
, int optname
, void *optval
, int * optlen
);
232 virtual int setsockopt(int level
, int optname
, void *optval
, int optlen
);
233 virtual int fcntl(unsigned int cmd
, int arg
);
234 virtual int ioctl(unsigned int request
, void *argp
);
235 virtual int fstat(struct stat
* buf
);
236 virtual long lseek(long offset
, int whence
);
237 virtual int ftruncate(long offset
);
238 virtual int isatty();
239 virtual int shutdown(int how
);
240 virtual void pre_select(Boolean wantRead
, Boolean wantWrite
, Boolean wantExcept
);
241 virtual int select(Boolean
* canRead
, Boolean
* canWrite
, Boolean
* exception
);
242 virtual void post_select(Boolean wantRead
, Boolean wantWrite
, Boolean wantExcept
);
245 void operator++() { ++refCount
; }
246 void operator--() { if (!--refCount
) delete this; }
250 #if PRAGMA_ALIGN_SUPPORTED
251 #pragma options align=reset
255 static SocketDomain
* domains
[GUSI_MAX_DOMAIN
];
256 static ProcessSerialNumber process
;
258 SocketDomain(int domain
);
259 virtual ~SocketDomain();
261 inline static SocketDomain
* Domain(int domain
);
264 // Optionally override the following
266 virtual Socket
* socket(int type
, short protocol
);
268 // Optionally override the following
270 virtual int socketpair(int type
, short protocol
, Socket
* sockets
[]);
272 // Optionally define the following
282 // Never override the following
288 Socket
* sockets
[GUSI_MAX_FD
];
289 Boolean needsConsole
;
295 int Install(Socket
* sock
, int start
= 0);
297 Socket
* operator[](int fd
);
306 #if PRAGMA_ALIGN_SUPPORTED
307 #pragma options align=mac68k
311 // I learned the hard way not to rely on bit field alignments
314 struct GUSIConfigRsrc
{
316 OSType defaultCreator
;
323 GUSISuffix suffices
[1];
326 #if PRAGMA_ALIGN_SUPPORTED
327 #pragma options align=reset
330 struct GUSIConfiguration
{
332 OSType defaultCreator
;
336 Boolean noChdir
; // Set current directory without chdir()
337 Boolean accurStat
; // Return # of subdirectories + 2 in st_nlink
338 Boolean hasConsole
; // Do we have our own console ?
339 Boolean noAutoInitGraf
; // Never automatically do InitGraf
340 Boolean sharedOpen
; // Open files with shared permissions
341 Boolean sigPipe
; // raise SIGPIPE on write to closed socket
342 Boolean noAppleEvents
; // Don't solicit AppleEvents for MPW tools
343 Boolean delayConsole
; // Do not open console until needed
347 GUSISuffix
* suffices
;
350 void GUSILoadConfiguration(Handle config
);
352 void SetDefaultFType(const TFileSpec
& name
) const;
353 void DoAutoSpin() const;
354 void AutoInitGraf() const { if (!noAutoInitGraf
) DoAutoInitGraf(); }
355 void DoAutoInitGraf() const;
356 Boolean
DelayConsole() const;
358 static Boolean firstTime
;
362 extern GUSIConfiguration GUSIConfig
;
363 extern SocketTable Sockets
;
365 typedef pascal OSErr (*OSErrInitializer
)();
366 typedef pascal void (*voidInitializer
)();
371 Feature(unsigned short trapNum
, TrapType tTyp
);
372 Feature(OSType type
, long value
);
373 Feature(OSType type
, long mask
, long value
);
374 Feature(const Feature
& precondition
, OSErrInitializer init
);
375 Feature(OSErrInitializer init
);
376 Feature(const Feature
& precondition
, voidInitializer init
);
377 Feature(voidInitializer init
);
378 Feature(const Feature
& cond1
, const Feature
& cond2
);
380 operator void*() const { return (void *) good
; }
383 extern Feature hasMakeFSSpec
;
384 extern Feature hasAlias
;
385 extern Feature hasNewSF
;
386 extern Feature hasProcessMgr
;
387 extern Feature hasCRM
;
388 extern Feature hasCTB
;
389 extern Feature hasStdNBP
;
390 extern Feature hasCM
;
391 extern Feature hasFT
;
392 extern Feature hasTM
;
393 extern Feature hasPPC
;
394 extern Feature hasRevisedTimeMgr
;
402 const struct iovec
* io
;
404 ScattGath(const struct iovec
*iov
, int cnt
);
405 virtual ~ScattGath();
407 void * buffer() { return buf
; }
408 int buflen() { return len
; }
409 int length(int l
) { return len
= l
; }
410 operator void *() { return buf
; }
413 class Scatterer
: public ScattGath
{
415 Scatterer(const struct iovec
*iov
, int count
);
416 virtual ~Scatterer();
419 class Gatherer
: public ScattGath
{
421 Gatherer(const struct iovec
*iov
, int count
);
425 typedef pascal void (*Deferred
)(void *);
428 // Valid bytes are between consume and produce
429 // Free bytes are between produce and consume
430 // bytes between endbuf-spare and endbuf are neither
443 RingBuffer(u_short bufsiz
);
446 Ptr
Producer(long & len
); // Find continuous memory for producer
447 Ptr
Consumer(long & len
); // Find continuous memory for consumer
448 void Validate(long len
); // Validate this, unallocate rest
449 void Invalidate(long len
);
450 void Produce(Ptr from
, long & len
);// Allocate, copy & validate
451 void Consume(Ptr to
, long & len
); // Copy & invalidate
453 long Free() { return free
; }
454 long Valid() { return valid
; }
456 void Defer() { lock
= true; }
457 void Undefer() { lock
= false; if (defproc
) defproc(arg
);}
458 Boolean
Locked() { return lock
; }
459 void Later(Deferred def
, void * ar
){ defproc
= def
; arg
= ar
; }
461 operator void *() { return buffer
; }
464 Boolean
GUSIInterrupt();
466 Boolean
CopyIconFamily(short srcResFile
, short srcID
, short dstResFile
, short dstID
);
468 pascal OSErr
PPCInit_P();
470 OSErr
AppleTalkIdentity(short & net
, short & node
);
472 void CopyC2PStr(const char * cstr
, StringPtr pstr
);