Fix three PyChecker-detected gotchas.
[python/dscho.git] / Mac / Unsupported / GUSI1-mods / GUSI_P.h
blob66ee3a76c80798426beff35b5e1d1c62a87f5f1b
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 2000/09/12 20:24:46 jack
9 Moved to Unsupported.
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
21 Initial revision
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
33 Socket::ftruncate
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
45 SAFESPIN
47 Revision 0.14 1993/01/03 00:00:00 neeri
48 GUSIConfig
50 Revision 0.13 1992/09/24 00:00:00 neeri
51 Include GUSIRsrc_P.h
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
57 AppleTalkIdentity()
59 Revision 0.10 1992/08/03 00:00:00 neeri
60 RingBuffer
62 Revision 0.9 1992/07/30 00:00:00 neeri
63 Initializer Features
65 Revision 0.8 1992/07/26 00:00:00 neeri
66 UnixSockets.choose()
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
72 choose(), hasNewSF
74 Revision 0.5 1992/06/07 00:00:00 neeri
75 Feature
77 Revision 0.4 1992/05/21 00:00:00 neeri
78 Implemented select()
80 Revision 0.3 1992/04/19 00:00:00 neeri
81 C++ rewrite
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
87 ppc Domain
89 *********************************************************************/
91 #ifndef __GUSI_P__
92 #define __GUSI_P__
94 #define __useAppleExts__
96 #include <GUSI.h>
97 #include <GUSIRsrc_P.h>
98 #include <TFileSpec.h>
101 #include <sys/errno.h>
102 #include <sys/uio.h>
103 #include <sys/socket.h>
105 extern "C" {
107 #include <stdio.h>
108 #include <string.h>
110 int GUSI_error(int err);
111 void * GUSI_error_nil(int err);
114 #include <Memory.h>
115 #include <Gestalt.h>
116 #include <Traps.h>
117 #include <AppleEvents.h>
118 #include <Processes.h>
119 #include <MixedMode.h>
121 #if MSLGUSI
122 using namespace std;
123 #endif
125 #if GENERATING68K
126 #pragma segment GUSI
127 #endif
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) \
162 do { \
163 if (GUSI_INTERRUPT(mesg,param)) \
164 return GUSI_error(EINTR); \
165 } while(cond)
167 /* SPINP returns a NULL on user cancel, for fn returning pointers */
168 #define SPINP(cond,mesg,param) \
169 do { \
170 if (GUSI_INTERRUPT(mesg,param)) { \
171 GUSI_error(EINTR); \
172 return NULL; \
174 } while(cond)
176 /* SPINVOID just returns on user cancel, for fn returning void */
177 #define SPINVOID(cond,mesg,param) \
178 do { \
179 if (GUSI_INTERRUPT(mesg,param)) { \
180 GUSI_error(EINTR); \
181 return; \
183 } while(cond)
185 /* SAFESPIN doesn't return, you have to check errno */
186 #define SAFESPIN(cond,mesg,param) \
187 do { \
188 if (GUSI_INTERRUPT(mesg,param)) { \
189 GUSI_error(EINTR); \
190 break; \
191 } else \
192 errno = 0; \
193 } while(cond)
196 // Library functions are never allowed to clear errno, so we have to save
198 class ErrnoSaver {
199 public:
200 ErrnoSaver() { fSavedErrno = ::errno; ::errno = 0; }
201 ~ErrnoSaver() { if (!::errno) ::errno = fSavedErrno; }
202 private:
203 int fSavedErrno;
206 #define SAVE_AND_CLEAR_ERRNO ErrnoSaver saveErrno
208 class SocketTable;
210 #if PRAGMA_ALIGN_SUPPORTED
211 #pragma options align=mac68k
212 #endif
214 class Socket {
215 friend class SocketTable;
217 short refCount;
218 protected:
219 Socket();
220 public:
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);
243 virtual ~Socket();
245 void operator++() { ++refCount; }
246 void operator--() { if (!--refCount) delete this; }
250 #if PRAGMA_ALIGN_SUPPORTED
251 #pragma options align=reset
252 #endif
254 class SocketDomain {
255 static SocketDomain * domains[GUSI_MAX_DOMAIN];
256 static ProcessSerialNumber process;
257 protected:
258 SocketDomain(int domain);
259 virtual ~SocketDomain();
260 public:
261 inline static SocketDomain * Domain(int domain);
262 static void Ready();
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
274 virtual int choose(
275 int type,
276 char * prompt,
277 void * constraint,
278 int flags,
279 void * name,
280 int * namelen);
282 // Never override the following
284 void DontStrip();
287 class SocketTable {
288 Socket * sockets[GUSI_MAX_FD];
289 Boolean needsConsole;
290 public:
291 SocketTable();
292 ~SocketTable();
294 void InitConsole();
295 int Install(Socket * sock, int start = 0);
296 int Remove(int fd);
297 Socket * operator[](int fd);
300 struct GUSISuffix {
301 char suffix[4];
302 OSType suffType;
303 OSType suffCreator;
306 #if PRAGMA_ALIGN_SUPPORTED
307 #pragma options align=mac68k
308 #endif
311 // I learned the hard way not to rely on bit field alignments
314 struct GUSIConfigRsrc {
315 OSType defaultType;
316 OSType defaultCreator;
318 char autoSpin;
319 unsigned char flags;
321 OSType version;
322 short numSuffices;
323 GUSISuffix suffices[1];
326 #if PRAGMA_ALIGN_SUPPORTED
327 #pragma options align=reset
328 #endif
330 struct GUSIConfiguration {
331 OSType defaultType;
332 OSType defaultCreator;
334 char autoSpin;
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
345 OSType version;
346 short numSuffices;
347 GUSISuffix * suffices;
349 GUSIConfiguration();
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;
357 private:
358 static Boolean firstTime;
359 static short we;
362 extern GUSIConfiguration GUSIConfig;
363 extern SocketTable Sockets;
365 typedef pascal OSErr (*OSErrInitializer)();
366 typedef pascal void (*voidInitializer)();
368 class Feature {
369 Boolean good;
370 public:
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;
396 class ScattGath {
397 Handle scratch;
398 protected:
399 void * buf;
400 int len;
401 int count;
402 const struct iovec * io;
404 ScattGath(const struct iovec *iov, int cnt);
405 virtual ~ScattGath();
406 public:
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 {
414 public:
415 Scatterer(const struct iovec *iov, int count);
416 virtual ~Scatterer();
419 class Gatherer : public ScattGath {
420 public:
421 Gatherer(const struct iovec *iov, int count);
422 virtual ~Gatherer();
425 typedef pascal void (*Deferred)(void *);
427 class RingBuffer {
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
431 Ptr buffer;
432 Ptr endbuf;
433 Ptr consume;
434 Ptr produce;
435 u_short free;
436 u_short valid;
437 u_short spare;
438 Boolean lock;
439 Deferred defproc;
440 void * arg;
442 public:
443 RingBuffer(u_short bufsiz);
444 ~RingBuffer();
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);
474 #endif