home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-20 | 8.6 KB | 204 lines | [TEXT/CWIE] |
- =head1 Miscellaneous
-
- =head2 BSD memory routines
-
- These are implemented as macros if you
-
- #include <compat.h>
-
- C<void bzero(void * from, int len)> zeroes
- C<len> bytes, starting at
- C<from>.
-
- C<void bfill(void * from, int len, int x)> fills
- C<len> bytes, starting at
- C<from> with
- C<x>.
-
- C<void bcopy(void * from, void * to, int len)> copies
- C<len> bytes from
- C<from> to
- C<to>.
-
- C<int bcmp(void * s1, void * s2, int len)> compares
- C<len> bytes at
- C<s1> against
- C<len> bytes at
- C<s2>, returning zero if the two areas are equal, nonzero otherwise.
-
- =head2 Hooks
-
- You can override some of GUSI's behaviour by providing hooks to GUSI. Note that these
- often get called from deep within GUSI, so be sure you understand what is required
- of a hook before overriding it.
-
- GUSI hooks can be accessed with the following routines:
-
- typedef void (*GUSIHook)(void);
- void GUSISetHook(GUSIHookCode code, GUSIHook hook);
- GUSIHook GUSIGetHook(GUSIHookCode code);
-
- Currently, two hooks are defined. The C<GUSI_SpinHook> is defined in the next section.
- The C<GUSI_ExecHook> is used by GUSI to decide whether a file or folder is to be
- considered "executable" or not. The default hook considers all folders and all
- applications (i.e., files of type C<'APPL'> and C<'appe'> to be executable. To provide
- your own hook, call
-
- GUSISetHook(GUSI_ExecHook, (GUSIHook) my_exec_hook);
-
- where C<my_exec_hook> is defined as
-
- Boolean my_exec_hook(const GUSIFileRef & ref);
-
- The old value is available as:
-
- Boolean (*)(const GUSIFileRef & ref)GUSIgetHook(GUSI_ExecHook);
-
- =head2 Blocking calls
-
- Since the Macintosh doesn't have preemptive task switching, it
- is important that other applications get a chance to run during blocking calls. This
- section discusses the mechanism C<GUSI> uses for that purpose.
-
- While a routine is waiting for a blocking call to terminate, it repeatedly calls a
- spin routine with the following parameters:
-
- typedef enum spin_msg
- {
- SP_MISC, /* some weird thing, usually just return immediately if you get this */
- SP_SELECT, /* in a select call, passes ticks the program is prepared to wait */
- SP_NAME, /* getting a host by name */
- SP_ADDR, /* getting a host by address */
- SP_STREAM_READ, /* Stream read call */
- SP_STREAM_WRITE, /* Stream write call */
- SP_DGRAM_READ, /* Datagram read call */
- SP_DGRAM_WRITE, /* Datagram write call */
- SP_SLEEP, /* sleeping, passes ticks left to sleep */
- SP_AUTO_SPIN /* Automatically spinning, passes spin count */
- } spin_msg;
-
- typedef int (*GUSISpinFn)(spin_msg msg, long param);
-
- If the spin routine returns a nonzero value, the call is interrupted and
- C<EINTR> returned. You can modify the spin routine with the following calls:
-
- GUSISetHook(GUSI_SpinHook, (GUSIHook) my_spin_hook);
- (GUSISpinFn)GUSIGetHook(GUSI_SpinHook);
-
- (For backward compatibility, GUSI also defines the equivalents:)
-
- int GUSISetSpin(GUSISpinFn routine);
- GUSISpinFn GUSIGetSpin(void);
-
- Often, however, the default spin routine will do what you want: It spins a
- cursor and occasionally calls C<GetNextEvent()> or C<WaitNextEvent()>. By default,
- only mouse down and suspend/resume events are handled, but you can change that
- by passing your own C<GUSIEvtTable> to C<GUSISetEvents()>.
-
- int GUSISetEvents(GUSIEvtTable table);
- GUSIEvtHandler * GUSIGetEvents(void);
-
- A C<GUSIEvtTable> is a table of C<GUSIEvtHandlers>, indexed by event code. Presence
- of a non-nil entry in the table will cause that event class to be allowed for
- C<GetNextEvent()> or C<WaitNextEvent()>. C<GUSI> for C<MPW C> and C<PPCC> includes
- one event table to be used with the C<SIOW> library.
-
- typedef void (*GUSIEvtHandler)(EventRecord * ev);
- typedef GUSIEvtHandler GUSIEvtTable[24];
-
- extern GUSIEvtHandler GUSISIOWEvents[];
-
- C<GUSI> also supports three POSIX/BSD routines: C<alarm(unsigned sec)> will after
- C<sec> seconds cancel the current call, raise C<SIGALRM>, and return C<EINTR>.
- Note that the default handler for C<SIGALRM> terminates the program, so be sure
- to install your own handler. C<alarm(0)> cancels an alarm and returns the remaining
- seconds. As opposed to POSIX systems, the C<GUSI> version of C<alarm()> does not use
- real clock interrupts and merely interrupts during a blocking call.
-
- C<sleep(unsigned sec)> sleeps for C<sec> seconds, and C<usleep(unsigned usec)> does
- the same for C<usec> micorseconds (rounded to 60ths of a tick).
-
- =head2 Resources
-
- A few C<GUSI> routines (currently primarily choose()) need resources
- to work correctly. These are added if you Rez your program with C<GUSI.r>. On
- startup, C<GUSI> also looks for a I<preference> resource with type
- C<'GUZI'> (the C<'Z'> actually must be a capital Sigma) and ID C<GUSIRsrcID>,
- which is currently defined as follows:
-
- #ifndef GUSI_PREF_VERSION
- #define GUSI_PREF_VERSION '0102'
- #endif
-
- type 'GUZI' {
- literal longint text = 'TEXT'; /* Type for creat'ed files */
- literal longint mpw = 'MPS '; /* Creator for creat'ed files */
- byte noAutoSpin, autoSpin; /* Automatically spin cursor ? */
- #if GUSI_PREF_VERSION >= '0110'
- boolean useChdir, dontUseChdir; /* Use chdir() ? */
- boolean approxStat, accurateStat; /* statbuf.st_nlink = # of subdirectories ? */
- boolean noTCPDaemon, isTCPDaemon; /* Inetd client ? */
- boolean noUDPDaemon, isUDPDaemon;
- #if GUSI_PREF_VERSION >= '0150'
- boolean noConsole, hasConsole; /* Are we providing our own dev:console ? */
- fill bit[3];
- #else
- fill bit[4];
- #endif
- literal longint = GUSI_PREF_VERSION;
- #if GUSI_PREF_VERSION >= '0120'
- integer = @t$$@>Countof(SuffixArray);
-
- wide array SuffixArray {
- literal longint; /* Suffix of file */
- literal longint; /* Type for file */
- literal longint; /* Creator for file */
- };
- #endif
- #endif
- };
-
- To keep backwards compatible, the preference version is included, and you are free to
- use whatever version of the preferences you want by defining C<GUSI_PREF_VERSION>.
-
- The first two fields define the file type and creator, respectively, to be used
- for files created by C<GUSI>. The type and creator of existing files will never
- be changed unless explicitely requested with fsetfileinfo(). The default is to
- create text files (type `TEXT') owned by the C<MPW Shell> (creator `MPS '). If you
- request a preference version of 1.2.0 and higher, you are also allowed to specify
- a list of suffixes that are given different types. An example of such a list would be:
-
- { 'SYM ', 'MPSY', 'sade' }
-
- The C<autoSpin> value, if nonzero, makes C<GUSI> call the spin routine for every
- call to C<read()>, C<write()>, C<send()>, or C<recv()>. This is useful for making
- an I/O bound program MultiFinder friendly without having to insert explicit calls
- to C<SpinCursor()>. If you don't specify a preference resource, C<autoSpin> is assumed
- to be C<1>. You may specify arbitrary values greater than one to make your program
- even friendlier; note, however, that this will hurt performance.
-
- The C<useChdir> flag tells C<GUSI> whether you change directories with the
- toolbox calls C<PBSetVol()> or C<PBHSetVol()> or with the C<GUSI> call C<chdir()>.
- The current directory will start with the directory your application resides in
- or the current C<MPW> directory, if you're running an C<MPW> tool.
- If C<useChdir> is specified, the current directory will only change with C<chdir()>
- calls. If C<dontUseChdir> is specified, the current directory will change with
- toolbox calls, until you call C<chdir()> the first time. This behaviour is more
- consistent with the standard C<MPW> library, but has IMHO no other redeeming
- value. If you don't specify a preference resource, C<useChdir> is assumed.
-
- If C<approxStat> is specified, C<stat()> and C<lstat()> for directories return in
- C<st_nlink> the number of I<items> in the directory C<+ 2>. If C<accurateStat> is
- specified, they return the number of I<subdirectories> in the directory. The
- latter has probably the best chances of being compatible with some Unix software,
- but the former is often a sufficient upper bound, is much faster, and most programs
- don't care about this value anyway. If you don't specify a preference resource,
- C<approxStat> is assumed.
-
- The C<isTCPDaemon> and C<isUDPDaemon> flags turn C<GUSI> programs into clients
- for David Petersons C<inetd>, as discussed below. If you don't specify a preference
- resource, C<noTCPDaemon> and C<noUDPDaemon> are assumed.
-
- The C<hasConsole> flag should be set if you are overriding the default "dev:console",
- as discussed below.
-