Ditched '_find_SET()', since it was a no-value-added wrapper around
[python/dscho.git] / Mac / GUSI-mods / into-include / GUSI_P.h
blob1bc5523a794abddc10ef663dd5e5ca63f0810d6c
1 /*********************************************************************
2 Project : GUSI - Grand Unified Socket Interface
3 File : GUSI_P.h - Private stuff
4 Author : Matthias Neeracher
5 Language : MPW C/C++
7 $Log$
8 Revision 1.1 1998/08/18 14:52:33 jack
9 Putting Python-specific GUSI modifications under CVS.
11 Revision 1.3 1994/12/31 01:30:26 neeri
12 Reorganize filename dispatching.
14 Revision 1.2 1994/08/10 00:41:05 neeri
15 Sanitized for universal headers.
17 Revision 1.1 1994/02/25 02:57:01 neeri
18 Initial revision
20 Revision 0.22 1993/07/17 00:00:00 neeri
21 GUSIRingBuffer::proc -> defproc
23 Revision 0.21 1993/07/17 00:00:00 neeri
24 GUSIO_MAX_DOMAIN -> AF_MAX
26 Revision 0.20 1993/06/27 00:00:00 neeri
27 Socket::{pre,post}_select
29 Revision 0.19 1993/06/27 00:00:00 neeri
30 Socket::ftruncate
32 Revision 0.18 1993/02/09 00:00:00 neeri
33 Socket::lurking, Socket::lurkdescr
35 Revision 0.17 1993/01/31 00:00:00 neeri
36 GUSIConfiguration::daemon
38 Revision 0.16 1993/01/17 00:00:00 neeri
39 Destructors for Socketdomain
41 Revision 0.15 1993/01/17 00:00:00 neeri
42 SAFESPIN
44 Revision 0.14 1993/01/03 00:00:00 neeri
45 GUSIConfig
47 Revision 0.13 1992/09/24 00:00:00 neeri
48 Include GUSIRsrc_P.h
50 Revision 0.12 1992/09/13 00:00:00 neeri
51 SPINVOID didn't return
53 Revision 0.11 1992/08/30 00:00:00 neeri
54 AppleTalkIdentity()
56 Revision 0.10 1992/08/03 00:00:00 neeri
57 RingBuffer
59 Revision 0.9 1992/07/30 00:00:00 neeri
60 Initializer Features
62 Revision 0.8 1992/07/26 00:00:00 neeri
63 UnixSockets.choose()
65 Revision 0.7 1992/07/13 00:00:00 neeri
66 Make AppleTalkSockets global
68 Revision 0.6 1992/06/27 00:00:00 neeri
69 choose(), hasNewSF
71 Revision 0.5 1992/06/07 00:00:00 neeri
72 Feature
74 Revision 0.4 1992/05/21 00:00:00 neeri
75 Implemented select()
77 Revision 0.3 1992/04/19 00:00:00 neeri
78 C++ rewrite
80 Revision 0.2 1992/04/18 00:00:00 neeri
81 changed read/write/send/recv dispatchers
83 Revision 0.1 1992/04/18 00:00:00 neeri
84 ppc Domain
86 *********************************************************************/
88 #ifndef __GUSI_P__
89 #define __GUSI_P__
91 #define __useAppleExts__
93 #include <GUSI.h>
94 #include <GUSIRsrc_P.h>
95 #include <TFileSpec.h>
98 #include <sys/errno.h>
99 #include <sys/uio.h>
100 #include <sys/socket.h>
102 extern "C" {
104 #include <stdio.h>
105 #include <string.h>
107 int GUSI_error(int err);
108 void * GUSI_error_nil(int err);
111 #include <Memory.h>
112 #include <Gestalt.h>
113 #include <Traps.h>
114 #include <AppleEvents.h>
115 #include <Processes.h>
116 #include <MixedMode.h>
118 #if MSLGUSI
119 using namespace std;
120 #endif
122 #if GENERATING68K
123 #pragma segment GUSI
124 #endif
126 #define GUSI_MAX_DOMAIN AF_MAX
127 #define DEFAULT_BUFFER_SIZE 4096
130 * In use and shutdown status.
132 #define SOCK_STATUS_USED 0x1 /* Used socket table entry */
133 #define SOCK_STATUS_NOREAD 0x2 /* No more reading allowed from socket */
134 #define SOCK_STATUS_NOWRITE 0x4 /* No more writing allowed to socket */
137 * Socket connection states.
139 #define SOCK_STATE_NO_STREAM 0 /* Socket doesn't have a MacTCP stream yet */
140 #define SOCK_STATE_UNCONNECTED 1 /* Socket is unconnected. */
141 #define SOCK_STATE_LISTENING 2 /* Socket is listening for connection. */
142 #define SOCK_STATE_LIS_CON 3 /* Socket is in transition from listen to connected. */
143 #define SOCK_STATE_CONNECTING 4 /* Socket is initiating a connection. */
144 #define SOCK_STATE_CONNECTED 5 /* Socket is connected. */
145 #define SOCK_STATE_CLOSING 6 /* Socket is closing */
146 #define SOCK_STATE_LIS_CLOSE 7 /* Socket closed while listening */
148 #define min(a,b) ( (a) < (b) ? (a) : (b))
149 #define max(a,b) ( (a) > (b) ? (a) : (b))
151 extern GUSISpinFn GUSISpin;
152 extern "C" int GUSIDefaultSpin(spin_msg, long);
153 extern int GUSICheckAlarm();
155 #define GUSI_INTERRUPT(mesg,param) (GUSICheckAlarm() || (GUSISpin && (*GUSISpin)(mesg,param)))
157 /* SPIN returns a -1 on user cancel for fn returning integers */
158 #define SPIN(cond,mesg,param) \
159 do { \
160 if (GUSI_INTERRUPT(mesg,param)) \
161 return GUSI_error(EINTR); \
162 } while(cond)
164 /* SPINP returns a NULL on user cancel, for fn returning pointers */
165 #define SPINP(cond,mesg,param) \
166 do { \
167 if (GUSI_INTERRUPT(mesg,param)) { \
168 GUSI_error(EINTR); \
169 return NULL; \
171 } while(cond)
173 /* SPINVOID just returns on user cancel, for fn returning void */
174 #define SPINVOID(cond,mesg,param) \
175 do { \
176 if (GUSI_INTERRUPT(mesg,param)) { \
177 GUSI_error(EINTR); \
178 return; \
180 } while(cond)
182 /* SAFESPIN doesn't return, you have to check errno */
183 #define SAFESPIN(cond,mesg,param) \
184 do { \
185 if (GUSI_INTERRUPT(mesg,param)) { \
186 GUSI_error(EINTR); \
187 break; \
188 } else \
189 errno = 0; \
190 } while(cond)
193 // Library functions are never allowed to clear errno, so we have to save
195 class ErrnoSaver {
196 public:
197 ErrnoSaver() { fSavedErrno = ::errno; ::errno = 0; }
198 ~ErrnoSaver() { if (!::errno) ::errno = fSavedErrno; }
199 private:
200 int fSavedErrno;
203 #define SAVE_AND_CLEAR_ERRNO ErrnoSaver saveErrno
205 class SocketTable;
207 #if PRAGMA_ALIGN_SUPPORTED
208 #pragma options align=mac68k
209 #endif
211 class Socket {
212 friend class SocketTable;
214 short refCount;
215 protected:
216 Socket();
217 public:
218 virtual int bind(void * name, int namelen);
219 virtual int connect(void * address, int addrlen);
220 virtual int listen(int qlen);
221 virtual Socket * accept(void * address, int * addrlen);
222 virtual int read(void * buffer, int buflen);
223 virtual int write(void * buffer, int buflen);
224 virtual int recvfrom(void * buffer, int buflen, int flags, void * from, int * fromlen);
225 virtual int sendto(void * buffer, int buflen, int flags, void * to, int tolen);
226 virtual int getsockname(void * name, int * namelen);
227 virtual int getpeername(void * name, int * namelen);
228 virtual int getsockopt(int level, int optname, void *optval, int * optlen);
229 virtual int setsockopt(int level, int optname, void *optval, int optlen);
230 virtual int fcntl(unsigned int cmd, int arg);
231 virtual int ioctl(unsigned int request, void *argp);
232 virtual int fstat(struct stat * buf);
233 virtual long lseek(long offset, int whence);
234 virtual int ftruncate(long offset);
235 virtual int isatty();
236 virtual int shutdown(int how);
237 virtual void pre_select(Boolean wantRead, Boolean wantWrite, Boolean wantExcept);
238 virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
239 virtual void post_select(Boolean wantRead, Boolean wantWrite, Boolean wantExcept);
240 virtual ~Socket();
242 void operator++() { ++refCount; }
243 void operator--() { if (!--refCount) delete this; }
247 #if PRAGMA_ALIGN_SUPPORTED
248 #pragma options align=reset
249 #endif
251 class SocketDomain {
252 static SocketDomain * domains[GUSI_MAX_DOMAIN];
253 static ProcessSerialNumber process;
254 protected:
255 SocketDomain(int domain);
256 virtual ~SocketDomain();
257 public:
258 inline static SocketDomain * Domain(int domain);
259 static void Ready();
261 // Optionally override the following
263 virtual Socket * socket(int type, short protocol);
265 // Optionally override the following
267 virtual int socketpair(int type, short protocol, Socket * sockets[]);
269 // Optionally define the following
271 virtual int choose(
272 int type,
273 char * prompt,
274 void * constraint,
275 int flags,
276 void * name,
277 int * namelen);
279 // Never override the following
281 void DontStrip();
284 class SocketTable {
285 Socket * sockets[GUSI_MAX_FD];
286 Boolean needsConsole;
287 public:
288 SocketTable();
289 ~SocketTable();
291 void InitConsole();
292 int Install(Socket * sock, int start = 0);
293 int Remove(int fd);
294 Socket * operator[](int fd);
297 struct GUSISuffix {
298 char suffix[4];
299 OSType suffType;
300 OSType suffCreator;
303 #if PRAGMA_ALIGN_SUPPORTED
304 #pragma options align=mac68k
305 #endif
308 // I learned the hard way not to rely on bit field alignments
311 struct GUSIConfigRsrc {
312 OSType defaultType;
313 OSType defaultCreator;
315 char autoSpin;
316 unsigned char flags;
318 OSType version;
319 short numSuffices;
320 GUSISuffix suffices[1];
323 #if PRAGMA_ALIGN_SUPPORTED
324 #pragma options align=reset
325 #endif
327 struct GUSIConfiguration {
328 OSType defaultType;
329 OSType defaultCreator;
331 char autoSpin;
333 Boolean noChdir; // Set current directory without chdir()
334 Boolean accurStat; // Return # of subdirectories + 2 in st_nlink
335 Boolean hasConsole; // Do we have our own console ?
336 Boolean noAutoInitGraf; // Never automatically do InitGraf
337 Boolean sharedOpen; // Open files with shared permissions
338 Boolean sigPipe; // raise SIGPIPE on write to closed socket
339 Boolean noAppleEvents; // Don't solicit AppleEvents for MPW tools
340 Boolean delayConsole; // Do not open console until needed
342 OSType version;
343 short numSuffices;
344 GUSISuffix * suffices;
346 GUSIConfiguration();
347 void GUSILoadConfiguration(Handle config);
349 void SetDefaultFType(const TFileSpec & name) const;
350 void DoAutoSpin() const;
351 void AutoInitGraf() const { if (!noAutoInitGraf) DoAutoInitGraf(); }
352 void DoAutoInitGraf() const;
353 Boolean DelayConsole() const;
354 private:
355 static Boolean firstTime;
356 static short we;
359 extern GUSIConfiguration GUSIConfig;
360 extern SocketTable Sockets;
362 typedef pascal OSErr (*OSErrInitializer)();
363 typedef pascal void (*voidInitializer)();
365 class Feature {
366 Boolean good;
367 public:
368 Feature(unsigned short trapNum, TrapType tTyp);
369 Feature(OSType type, long value);
370 Feature(OSType type, long mask, long value);
371 Feature(const Feature & precondition, OSErrInitializer init);
372 Feature(OSErrInitializer init);
373 Feature(const Feature & precondition, voidInitializer init);
374 Feature(voidInitializer init);
375 Feature(const Feature & cond1, const Feature & cond2);
377 operator void*() const { return (void *) good; }
380 extern Feature hasMakeFSSpec;
381 extern Feature hasAlias;
382 extern Feature hasNewSF;
383 extern Feature hasProcessMgr;
384 extern Feature hasCRM;
385 extern Feature hasCTB;
386 extern Feature hasStdNBP;
387 extern Feature hasCM;
388 extern Feature hasFT;
389 extern Feature hasTM;
390 extern Feature hasPPC;
391 extern Feature hasRevisedTimeMgr;
393 class ScattGath {
394 Handle scratch;
395 protected:
396 void * buf;
397 int len;
398 int count;
399 const struct iovec * io;
401 ScattGath(const struct iovec *iov, int cnt);
402 virtual ~ScattGath();
403 public:
404 void * buffer() { return buf; }
405 int buflen() { return len; }
406 int length(int l) { return len = l; }
407 operator void *() { return buf; }
410 class Scatterer : public ScattGath {
411 public:
412 Scatterer(const struct iovec *iov, int count);
413 virtual ~Scatterer();
416 class Gatherer : public ScattGath {
417 public:
418 Gatherer(const struct iovec *iov, int count);
419 virtual ~Gatherer();
422 typedef pascal void (*Deferred)(void *);
424 class RingBuffer {
425 // Valid bytes are between consume and produce
426 // Free bytes are between produce and consume
427 // bytes between endbuf-spare and endbuf are neither
428 Ptr buffer;
429 Ptr endbuf;
430 Ptr consume;
431 Ptr produce;
432 u_short free;
433 u_short valid;
434 u_short spare;
435 Boolean lock;
436 Deferred defproc;
437 void * arg;
439 public:
440 RingBuffer(u_short bufsiz);
441 ~RingBuffer();
443 Ptr Producer(long & len); // Find continuous memory for producer
444 Ptr Consumer(long & len); // Find continuous memory for consumer
445 void Validate(long len); // Validate this, unallocate rest
446 void Invalidate(long len);
447 void Produce(Ptr from, long & len);// Allocate, copy & validate
448 void Consume(Ptr to, long & len); // Copy & invalidate
450 long Free() { return free; }
451 long Valid() { return valid; }
453 void Defer() { lock = true; }
454 void Undefer() { lock = false; if (defproc) defproc(arg);}
455 Boolean Locked() { return lock; }
456 void Later(Deferred def, void * ar){ defproc = def; arg = ar; }
458 operator void *() { return buffer; }
461 Boolean GUSIInterrupt();
463 Boolean CopyIconFamily(short srcResFile, short srcID, short dstResFile, short dstID);
465 pascal OSErr PPCInit_P();
467 OSErr AppleTalkIdentity(short & net, short & node);
469 void CopyC2PStr(const char * cstr, StringPtr pstr);
471 #endif