First Imported.

This commit is contained in:
chombier 2001-03-07 09:55:27 +00:00
parent f28b3dadf4
commit f820e6eab4
1902 changed files with 261459 additions and 0 deletions

51
GUSI/DCon/Headers/DCon.h Executable file
View File

@ -0,0 +1,51 @@
#ifndef _DCON_
#define _DCON_
#include <MacTypes.h>
#include <stdarg.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
void dopen(const char *log);
void dprintf(const char *format,...);
void vdprintf(const char *format,va_list arg);
void dprintmem(const void *data,size_t len);
void dfprintf(const char *log,const char *format,...);
void vdfprintf(const char *log,const char *format,va_list arg);
void dfprintmem(const char *log,const void *data,size_t len);
#ifndef DCON
#define DCON 1
#endif
#if DCON
#define dAssertPrint(condition) dprintf(NULL,"Assert failed: " condition " %s:%d\n",__FILE__,__LINE__)
#define dAssertIfTrue(condition) ((condition) ? dAssertPrint(#condition) : ((void)0))
#define dAssertIfFalse(condition) ((condition) ? ((void)0) : dAssertPrint(#condition))
#define dAssert(condition) dAssertIfFalse(condition)
#else
#define dAssertPrint(condition) ((void)0)
#define dAssertIfTrue(condition) ((condition) ? ((void)0) : ((void)0))
#define dAssertIfFalse(condition) ((condition) ? ((void)0) : ((void)0))
#define dAssert(condition) dAssertIfFalse(condition)
#define dopen while(0)
#define dprintf while(0)
#define vdprintf while(0)
#define dprintmem while(0)
#define dfprintf while(0)
#define vfdprintf while(0)
#define dfprintmem while(0)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _DCON_ */

481
GUSI/Examples/GUSIFileTest.c Executable file
View File

@ -0,0 +1,481 @@
/*********************************************************************
File : GUSI - Grand Unified Socket Interface
File : GUSIFileTest - Test plain files
Author : Matthias Neeracher <neeri@iis.ethz.ch>
Language : MPW C
$Log$
Revision 1.1.1.1 2001/03/03 21:49:36 chombier
Initial import
Revision 1.4 2000/05/23 06:38:53 neeri
Added descriptor tests
Revision 1.3 2000/01/17 01:38:32 neeri
Fix rename() directory separator handling
Revision 1.2 1999/04/10 04:24:53 neeri
Reimplement ls and ll in a more standard way
Revision 1.1 1998/10/25 11:57:25 neeri
Ready to release 2.0a3
Revision 1.2 1994/12/31 01:10:41 neeri
ANSIfy.
Test FSSpec encoding.
Revision 1.1 1994/02/25 02:46:54 neeri
Initial revision
Revision 0.9 1993/07/29 00:00:00 neeri
scandir
Revision 0.8 1993/07/18 00:00:00 neeri
dirent -> struct dirent
Revision 0.7 1992/12/20 00:00:00 neeri
Allow defaults for choose()
Revision 0.6 1992/12/08 00:00:00 neeri
Pwd()
Revision 0.5 1992/10/27 00:00:00 neeri
Forgot to adapt it to dirent.h
Revision 0.4 1992/09/07 00:00:00 neeri
RdLink()
Revision 0.3 1992/07/25 00:00:00 neeri
Isolated testing gear in GUSITest
Revision 0.2 1992/07/13 00:00:00 neeri
Test choose()
Revision 0.1 1992/06/14 00:00:00 neeri
More tests
*********************************************************************/
#include "GUSITest.h"
#include "GUSIFileSpec.h"
#include <Types.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/unistd.h>
#include <sys/stat.h>
void Stat(char ch1, char ch2, const char * cmd)
{
int res;
struct stat statbuf;
char filename[80];
if (sscanf(cmd, "%s", filename) != 1)
Usage(ch1, ch2);
else {
if (ch2 == 'l') {
cmd = "lstat";
res = lstat(filename, &statbuf);
} else {
cmd = "stat";
res = stat(filename, &statbuf);
}
if (res) {
printf("# %s(\"%s\") returned error %s\n", cmd, filename, Explain());
} else {
printf("# %s(\"%s\") =\n", cmd, filename);
DUMP(statbuf.st_dev,d);
DUMP(statbuf.st_ino,d);
DUMP(statbuf.st_mode,o);
DUMP(statbuf.st_nlink,d);
DUMP(statbuf.st_uid,d);
DUMP(statbuf.st_gid,d);
DUMP(statbuf.st_rdev,d);
DUMP(statbuf.st_size,d);
DUMP(statbuf.st_atime,u);
DUMP(statbuf.st_mtime,u);
DUMP(statbuf.st_ctime,u);
DUMP(statbuf.st_blksize,d);
DUMP(statbuf.st_blocks,d);
}
Where();
}
}
void ChDir(char ch1, char ch2, const char * cmd)
{
char directory[80];
if (sscanf(cmd, "%s", directory) != 1)
Usage(ch1, ch2);
else if (chdir(directory)) {
printf("# chdir(\"%s\") returned error %s\n", directory, Explain());
Where();
}
}
void MkDir(char ch1, char ch2, const char * cmd)
{
char directory[80];
if (sscanf(cmd, "%s", directory) != 1)
Usage(ch1, ch2);
else if (mkdir(directory)) {
printf("# mkdir(\"%s\") returned error %s\n", directory, Explain());
Where();
}
}
void RmDir(char ch1, char ch2, const char * cmd)
{
char directory[80];
if (sscanf(cmd, "%s", directory) != 1)
Usage(ch1, ch2);
else if (rmdir(directory)) {
printf("# rmdir(\"%s\") returned error %s\n", directory, Explain());
Where();
}
}
void List(char ch1, char ch2, const char * cmd)
{
int count;
int i;
DIR * dir;
struct dirent * entry;
char * dirend;
char directory[80];
struct stat statbuf;
if (sscanf(cmd, "%s", directory) != 1)
strcpy(directory, ":");
if (ch2 == 'l' && !strchr(directory, ':')) {
directory[0] = ':';
sscanf(cmd, "%s", directory+1);
}
if (!(dir = opendir(directory))) {
printf("# opendir(\"%s\") returned error %s\n", directory, Explain());
goto error;
}
printf("# directory \"%s\" =\n", directory);
dirend = directory + strlen(directory);
if (dirend[-1] != ':')
*dirend++ = ':';
while (entry = readdir(dir))
if (ch2 == 's')
printf("# %s\n", entry->d_name);
else {
strcpy(dirend, entry->d_name);
if (lstat(directory, &statbuf))
printf("# lstat(\"%s\") returned error %s\n", entry->d_name, Explain());
else
printf("# %c %7d %s\n",
(statbuf.st_mode & S_IFMT) == S_IFREG ? 'F' :
(statbuf.st_mode & S_IFMT) == S_IFDIR ? 'D' :
(statbuf.st_mode & S_IFMT) == S_IFLNK ? 'L' : '?',
statbuf.st_size,
entry->d_name);
}
closedir(dir);
error:
Where();
}
void Type(char ch1, char ch2, const char * cmd)
{
FILE * fl;
char line[500];
char filename[80];
if (sscanf(cmd, "%s", filename) != 1)
Usage(ch1, ch2);
else {
fl = fopen(filename, "r");
if (!fl)
printf("# open(\"%s\") returned error %s\n", filename, Explain());
else {
printf("# \"%s\" =\n", filename);
while (fgets(line, 500, fl))
fputs(line, stdout);
fclose(fl);
}
Where();
}
}
void Encode(char ch1, char ch2, const char * cmd)
{
#if 0
OSErr err;
char filename[80];
if (sscanf(cmd, "%s", filename) != 1)
Usage(ch1, ch2);
else {
FSSpec spec;
if (err = Path2FSSpec(filename, &spec))
fprintf(stderr, "Path2FSSpec(%s) returned error %d\n", filename, err);
else
fprintf(stderr, "%s -> %s\n", filename, FSp2Encoding(&spec));
}
#endif
}
void Glob(char ch1, char ch2, const char * cmd)
{
#if 0
OSErr err;
FileGlobRef glob;
char filename[80];
if (sscanf(cmd, "%s", filename) != 1)
Usage(ch1, ch2);
else if (!(glob = NewFileGlob(filename)))
fprintf(stderr, "NewFileGlob(%s) failed.\n", filename);
else {
FSSpec spec;
fprintf(stderr, "Glob(%s) matched:\n", filename);
while (FileGlob2FSSpec(glob, &spec)) {
fprintf(stderr, " %s\n", FSp2FullPath(&spec));
NextFileGlob(glob);
}
DisposeFileGlob(glob);
}
#endif
}
void Edit(char ch1, char ch2, const char * cmd)
{
FILE * fl;
char line[500];
char filename[80];
if (sscanf(cmd, "%s", filename) != 1)
Usage(ch1, ch2);
else {
fl = fopen(filename, "w");
if (!fl)
printf("# open(\"%s\") returned error %s\n", filename, Explain());
else {
printf("# Enter \"%s\", terminate with \".\"\n", filename);
while (fgets(line, 500, stdin))
if (strcmp(line, ".\n"))
fputs(line, fl);
else
break;
fclose(fl);
}
}
}
void Rm(char ch1, char ch2, const char * cmd)
{
char filename[80];
if (sscanf(cmd, "%s", filename) != 1)
Usage(ch1, ch2);
else if (remove(filename)) {
printf("# remove(\"%s\") returned error %s\n", filename, Explain());
Where();
}
}
void Mv(char ch1, char ch2, const char * cmd)
{
struct stat statbuf;
char oldfilename[80];
char newfilename[80];
if (sscanf(cmd, "%s %s", oldfilename, newfilename) != 2)
Usage(ch1, ch2);
else {
if (!stat(newfilename, &statbuf) && (statbuf.st_mode & S_IFMT) == S_IFDIR) {
char * fn;
char * next;
int len = strlen(newfilename);
/* Extract file name part from oldfilename */
for (fn = oldfilename; (next = strchr(fn, ':')) && next[1]; fn = next+1);
if (!strchr(newfilename, ':')) { /* Prepend ':' if necessary */
newfilename[0] = ':';
sscanf(cmd, "%s %s", oldfilename, newfilename+1);
++len;
}
if (newfilename[len-1] != ':')
newfilename[len++] = ':';
strcpy(newfilename+len, fn);
}
if (rename(oldfilename, newfilename)) {
printf("# rename(\"%s\", \"%s\") returned error %s\n", oldfilename, newfilename, Explain());
Where();
}
}
}
void Link(char ch1, char ch2, const char * cmd)
{
char oldfilename[80];
char newfilename[80];
if (sscanf(cmd, "%s %s", oldfilename, newfilename) != 2)
Usage(ch1, ch2);
else {
if (symlink(oldfilename, newfilename)) {
printf("# symlink(\"%s\", \"%s\") returned error %s\n", oldfilename, newfilename, Explain());
Where();
}
}
}
void RdLink(char ch1, char ch2, const char * cmd)
{
char path[200];
char link[200];
int len;
if (sscanf(cmd, "%s", path) != 1)
Usage(ch1, ch2);
len = readlink(path, link, 199);
if (len < 0)
printf("# readlink(\"%s\") returned error %s\n", path, Explain());
else {
link[len] = 0;
printf("# readlink(\"%s\") returned \"%s\"\n", path, link);
}
Where();
}
void Pwd(char ch1, char ch2, const char * cmd)
{
char * buf;
buf = getcwd(NULL, 1024);
if (!buf)
printf("# getcwd() returned error %s\n", Explain());
else {
printf("# getcwd() returned \"%s\"\n", buf);
free(buf);
}
Where();
}
void Access(char ch1, char ch2, const char * cmd)
{
char filename[80];
if (sscanf(cmd, "%s", filename) != 1)
Usage(ch1, ch2);
else {
if (access(filename, F_OK))
printf("# access(\"%s\", F_OK) returned error %s\n", filename, Explain());
else
printf("# access(\"%s\", F_OK) succeeded.\n", filename, Explain());
if (access(filename, R_OK))
printf("# access(\"%s\", R_OK) returned error %s\n", filename, Explain());
else
printf("# access(\"%s\", R_OK) succeeded.\n", filename, Explain());
if (access(filename, W_OK))
printf("# access(\"%s\", W_OK) returned error %s\n", filename, Explain());
else
printf("# access(\"%s\", W_OK) succeeded.\n", filename, Explain());
if (access(filename, X_OK))
printf("# access(\"%s\", X_OK) returned error %s\n", filename, Explain());
else
printf("# access(\"%s\", X_OK) succeeded.\n", filename, Explain());
Where();
}
}
void Open(char ch1, char ch2, const char * cmd)
{
char filename[80];
if (sscanf(cmd, "%s", filename) != 1)
Usage(ch1, ch2);
else if ((sock = open(filename, O_RDONLY)) < 0)
printf("# open(\"%s\") returned error %s\n", filename, Explain());
}
void Seek(char ch1, char ch2, const char * cmd)
{
int whence;
int offset;
int result;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (sscanf(cmd, "%d %d", &offset, &whence) != 2) {
Usage(ch1, ch2);
return;
}
if ((result = lseek(sock, offset, whence)) < 0)
printf("# lseek(%d %d) returned error %s\n", offset, whence, Explain());
else
printf("# lseek(%d %d) ended up at offset %d\n", offset, whence, result);
}
main(int argc, char ** argv)
{
printf("GUSIFileTest MN 21May00\n\n");
AddDescriptorCommands();
COMMAND('s', 't', Stat, "filename", "Call stat() on a file");
COMMAND('s', 'l', Stat, "filename", "Call lstat() on a file");
COMMAND('c', 'd', ChDir, "directory", "Call chdir()");
COMMAND('l', 's', List, "[ directory ]", "List a directory");
COMMAND('l', 'l', List, "[ directory ]", "List a directory with more info");
COMMAND('m', 'd', MkDir, "directory", "Make a new directory");
COMMAND('d', 'd', RmDir, "directory", "Delete an empty directory");
COMMAND('t', 'y', Type, "filename", "Type out the contents of a file");
COMMAND('e', 'd', Edit, "filename", "Enter the contents of a new file");
COMMAND('m', 'v', Mv, "oldfile newfile", "Rename/Move a file");
COMMAND('r', 'm', Rm, "filename", "Delete a file");
COMMAND('r', 'l', RdLink,"filename", "Read symbolic link");
COMMAND('l', 'n', Link, "oldfile newfile", "Create a symbolic link");
COMMAND('p', 'w', Pwd, "", "Print current directory");
COMMAND('e', 'n', Encode,"filename", "Translate filename to encoded FSSpec");
COMMAND('g', 'l', Glob, "filename", "Expand wildcards");
COMMAND('a', 'c', Access,"filename", "Test access rights");
COMMAND('o', 'p', Open, "filename", "Open a file (to test commands on open files)");
COMMAND('s', 'k', Seek, "offset whence", "Seek on open descriptor");
RunTest(argc, argv);
}

601
GUSI/Examples/GUSIINETTest.c Executable file
View File

@ -0,0 +1,601 @@
/*********************************************************************
Project : GUSI - Grand Unified Socket Interface
File : GUSIINETTest - Test unix domain sockets
Author : Matthias Neeracher <neeri@iis.ethz.ch>
Language : MPW C
$Log$
Revision 1.1.1.1 2001/03/03 21:49:39 chombier
Initial import
Revision 1.4 2000/10/15 21:49:20 neeri
Add multiple connection test
Revision 1.3 2000/05/23 06:40:03 neeri
Add Linger, Getsockname tests
Revision 1.2 2000/03/06 08:28:32 neeri
Releasing 2.0.5
Revision 1.1 1998/10/25 11:57:26 neeri
Ready to release 2.0a3
Revision 1.1 1994/12/31 00:50:27 neeri
Initial revision
Revision 0.6 1993/08/25 00:00:00 neeri
gethostbyaddr()
Revision 0.5 1993/07/29 00:00:00 neeri
servent tests
Revision 0.4 1993/03/03 00:00:00 neeri
Added performance test
Revision 0.3 1992/09/14 00:00:00 neeri
Misinterpreted hostent structure
Revision 0.2 1992/09/08 00:00:00 neeri
Factor out common socket routines
Revision 0.1 1992/09/08 00:00:00 neeri
First attempt
*********************************************************************/
#include "GUSITest.h"
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <netdb.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "Events.h"
char addrstr[100];
void Socket(char ch1, char ch2, const char * line)
{
sock = socket(AF_INET, (ch1 == 's') ? SOCK_STREAM : SOCK_DGRAM, 0);
if (sock == -1) {
printf("# socket() returned error %d [%s]\n", errno, Explain());
Where();
}
}
void Bind(char ch1, char ch2, const char * cmd)
{
int len;
struct sockaddr_in addr;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (sscanf(cmd, "%s %hd", addrstr, &addr.sin_port) == 2) {
addr.sin_addr.s_addr = inet_addr(addrstr);
addr.sin_family = AF_INET;
len = sizeof(struct sockaddr_in);
} else {
Usage(ch1, ch2);
return;
}
if (bind(sock, (struct sockaddr *) &addr, len)) {
printf(
"bind(%s:%d) returned error %d [%s]\n",
inet_ntoa(addr.sin_addr),
addr.sin_port,
errno, Explain());
Where();
}
}
void NoDelay(char , char , const char * cmd)
{
int one = 1;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(int)))
printf(
"setsockopt(IPPROTO_TCP, TCP_NODELAY) returned error %d [%s]\n",
errno, Explain());
}
void Linger(char ch1, char ch2, const char * cmd)
{
struct linger l;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (sscanf(cmd, "%d", &l.l_linger) == 1) {
l.l_onoff = l.l_linger > -1;
} else {
Usage(ch1, ch2);
return;
}
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char*)&l, sizeof(struct linger)))
printf(
"setsockopt(SOL_SOCKET, SO_LINGER) returned error %d [%s]\n",
errno, Explain());
}
void Accept(char ch1, char ch2, const char * line)
{
socklen_t len;
struct sockaddr_in addr;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (accsock != -1) {
printf("# can't accept more than one connection\n");
Where();
return;
}
len = sizeof(struct sockaddr_in);
sock = accept(accsock = sock, (struct sockaddr *) &addr, &len);
if (sock < 0) {
printf("# accept() returned error %d [%s]\n", errno, Explain());
sock = accsock;
accsock = -1;
} else {
printf(
"# accepted connection from %s port %d\n",
inet_ntoa(addr.sin_addr),
addr.sin_port);
}
Where();
}
void Getsockname(char ch1, char ch2, const char * line)
{
socklen_t len;
struct sockaddr_in addr;
int err;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
len = sizeof(struct sockaddr_in);
if (ch2 == 's')
err = getsockname(accsock = sock, (struct sockaddr *) &addr, &len);
else
err = getpeername(accsock = sock, (struct sockaddr *) &addr, &len);
if (err < 0) {
printf("# get%sname() returned error %d [%s]\n",
(ch2 == 's' ? "sock" : "peer"), errno, Explain());
} else {
printf(
"# %s are %s port %d\n", (ch2 == 's' ? "We" : "They"),
inet_ntoa(addr.sin_addr),
addr.sin_port);
}
Where();
}
void Connect(char ch1, char ch2, const char * cmd)
{
int len;
struct sockaddr_in addr;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (sscanf(cmd, "%s %hd", addrstr, &addr.sin_port) == 2) {
addr.sin_addr.s_addr = inet_addr(addrstr);
addr.sin_family = AF_INET;
len = sizeof(struct sockaddr_in);
} else {
Usage(ch1, ch2);
return;
}
if (connect(sock, (struct sockaddr *) &addr, len)) {
printf(
"connect(%s:%d) returned error %s\n",
inet_ntoa(addr.sin_addr),
addr.sin_port,
Explain());
Where();
}
}
static int sSock[1000];
static int sSockUsed;
void MultiConn(char ch1, char ch2, const char * cmd)
{
int len;
int count;
int i;
struct sockaddr_in addr;
if (sscanf(cmd, "%d %s %hd", &count, addrstr, &addr.sin_port) == 3) {
addr.sin_addr.s_addr = inet_addr(addrstr);
addr.sin_family = AF_INET;
len = sizeof(struct sockaddr_in);
} else {
Usage(ch1, ch2);
return;
}
if (count > 1000-sSockUsed)
count = 1000-sSockUsed;
for (i=0; i<count; ++i) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (connect(sock, (struct sockaddr *) &addr, len)) {
printf(
"#%d: connect(%s:%d) returned error %s\n",
i,
inet_ntoa(addr.sin_addr),
addr.sin_port,
Explain());
Where();
close(sock);
if (!i)
break;
} else {
struct sockaddr_in addr;
socklen_t len;
len = sizeof(struct sockaddr_in);
getsockname(sock, (struct sockaddr *) &addr, &len);
printf("#%d connected from port %d\n", i, addr.sin_port);
sSock[sSockUsed++] = sock;
}
}
}
void MultiDis(char, char, const char * cmd)
{
while (sSockUsed > 0)
close(sSock[--sSockUsed]);
}
int ReadWhileUCan()
{
int res;
char * outline;
fd_set rdfds;
fd_set exfds;
struct timeval delay;
char out[500];
for (;;) {
FD_ZERO(&rdfds);
FD_ZERO(&exfds);
FD_SET(sock, &rdfds);
FD_SET(sock, &exfds);
delay.tv_sec = 1;
delay.tv_usec = 0;
res = select(sock+1, &rdfds, nil, &exfds, &delay);
if (res < 0) {
printf("# select() returned error %d [%s]\n", errno, Explain());
return -1;
} else if (!res)
return 0;
else if (res && FD_ISSET(sock, &exfds)) {
printf("# select() returned an exception\n");
return -1;
} else if (res && FD_ISSET(sock, &rdfds)) {
res = read(sock, out, 500);
if (res < 0) {
printf("# read() returned error %d [%s]\n", errno, Explain());
return -1;
}
out[res] = 0;
for (outline = strtok(out, "\n\r"); outline; outline = strtok(nil, "\n\r"))
printf("%s\n", outline);
}
}
}
void Telnet(char ch1, char ch2, const char * cmd)
{
int len;
int part;
int res;
char * line;
char * outline;
fd_set rdfds;
fd_set wrfds;
fd_set exfds;
struct timeval delay;
char in[100];
char out[500];
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
printf("# Entering Poor Man's Telnet mode\n");
for (;;) {
if (ReadWhileUCan())
break;
Prompt();
if (!fgets(in, 100, input))
break;
++inputline;
if (!strcmp(in, ".\n"))
break;
if (!strcmp(in, "?\n"))
continue;
len = strlen(in);
in[len++] = '\r';
in[len] = 0;
for (line = in; len; len -= part, line += part) {
part = 0;
FD_ZERO(&rdfds);
FD_ZERO(&wrfds);
FD_ZERO(&exfds);
FD_SET(sock, &rdfds);
FD_SET(sock, &wrfds);
FD_SET(sock, &exfds);
delay.tv_sec = 10;
delay.tv_usec = 0;
res = select(sock+1, &rdfds, &wrfds, &exfds, &delay);
if (res < 0) {
printf("# select() returned error %d [%s]\n", errno, Explain());
return;
} else if (!res) {
printf("# select() timed out\n");
return;
} else if (FD_ISSET(sock, &exfds)) {
printf("# select() returned an exception\n");
return;
}
if (FD_ISSET(sock, &rdfds)) {
res = read(sock, out, 500);
if (res < 0) {
printf("# read() returned error %d [%s]\n", errno, Explain());
return;
}
out[res] = 0;
for (outline = strtok(out, "\n\r"); outline; outline = strtok(nil, "\n\r"))
printf("%s\n", outline);
} else if (FD_ISSET(sock, &wrfds)) {
res = write(sock, line, len);
if (res < 0) {
line[strlen(line) - 2] = 0;
printf("# write(\"%s\") returned error %s\n", line, Explain());
return;
}
part = res;
}
}
}
printf("# Leaving Poor Man's Telnet mode\n");
}
void N2Addr(char ch1, char ch2, const char * cmd)
{
struct in_addr addr;
struct hostent * ent;
if (sscanf(cmd, "%s", addrstr) == 1)
if (ent = gethostbyname(addrstr)) {
memcpy(&addr, ent->h_addr, sizeof(struct in_addr));
printf("# gethostbyname(%s) returned %s\n", addrstr, inet_ntoa(addr));
} else
printf("# gethostbyname(%s) failed.\n", addrstr);
else
Usage(ch1, ch2);
}
void A2Name(char ch1, char ch2, const char * cmd)
{
in_addr_t addr;
struct hostent * ent;
if (sscanf(cmd, "%s", addrstr) == 1) {
addr = inet_addr(addrstr);
if (ent = gethostbyaddr((char *) &addr, 0, 0)) {
printf("# gethostbyaddr(%s) returned %s\n", addrstr, ent->h_name);
} else
printf("# gethostbyaddr(%s) failed.\n", addrstr);
} else
Usage(ch1, ch2);
}
void PerfTest(char ch1, char ch2, const char * cmd)
{
int count;
int i;
long ticks;
char buf[1024];
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (sscanf(cmd, "%d", &count) == 1) {
ticks = TickCount();
for (i=0; i<count; i++) {
write(sock, buf, 1);
read(sock, buf, 1024);
}
printf("# Did %d iterations in %d ticks.\n", count, TickCount()-ticks);
} else
Usage(ch1, ch2);
}
void ServByName(char ch1, char ch2, const char * cmd)
{
struct servent * ent;
char proto[6];
if (sscanf(cmd, "%s %s", addrstr, proto) == 2)
if (ent = getservbyname(addrstr, proto))
printf("# getservbyname(%s %s) returned %d\n", addrstr, proto, ent->s_port);
else
printf("# getservbyname(%s %s) failed.\n", addrstr, proto);
else if (sscanf(cmd, "%s", addrstr) == 1)
if (ent = getservbyname(addrstr, NULL))
printf("# getservbyname(%s) returned %d\n", addrstr, ent->s_port);
else
printf("# getservbyname(%s) failed.\n", addrstr);
else
Usage(ch1, ch2);
}
void PrintServEnt(struct servent * ent, Boolean full)
{
char ** al;
printf("%s", ent->s_name);
if (full)
printf(" %d/%s", ent->s_port, ent->s_proto);
for (al = ent->s_aliases; *al; ++al)
printf(" %s", *al);
putchar('\n');
}
void ServByPort(char ch1, char ch2, const char * cmd)
{
int port;
struct servent * ent;
char proto[6];
if (sscanf(cmd, "%d %s", &port, proto) == 2)
if (ent = getservbyport(port, proto)) {
printf("# getservbyport(%d %s) returned ", port, proto);
PrintServEnt(ent, false);
} else
printf("# getservbyport(%d %s) failed.\n", addrstr, proto);
else if (sscanf(cmd, "%d %s", &port) == 1)
if (ent = getservbyport(port, NULL)) {
printf("# getservbyport(%d) returned ", port);
PrintServEnt(ent, false);
} else
printf("# getservbyport(%d) failed.\n", addrstr);
else
Usage(ch1, ch2);
}
void ServList(char ch1, char ch2, const char * line)
{
struct servent * ent;
setservent(0);
while (ent = getservent()) {
printf("# ");
PrintServEnt(ent, true);
}
}
main(int argc, char ** argv)
{
printf("GUSIINETTest MN 14May00\n\n");
COMMAND('s', 's', Socket, "", "Create a stream socket");
COMMAND('d', 's', Socket, "", "Create a datagram socket");
COMMAND('b', 'd', Bind, "addr port", "Bind to address");
COMMAND('c', 'o', Connect, "addr port", "Connect to address");
COMMAND('m', 'c', MultiConn, "# addr port", "Connect multiple times to address");
COMMAND('m', 'd', MultiDis, "", "Disconnect the connections");
COMMAND('a', 'c', Accept, "", "Accept a connection");
COMMAND('t', 'n', Telnet, "", "Play telnet");
COMMAND('n', 'a', N2Addr, "name", "Convert name to address");
COMMAND('a', 'n', A2Name, "addr", "Convert address to name");
COMMAND('p', 't', PerfTest,"count", "Do a performance test");
COMMAND('s', 'n', ServByName, "name", "Convert service name to port number");
COMMAND('s', 'p', ServByPort, "port", "Convert port number to service name");
COMMAND('s', 'l', ServList, "", "List services");
COMMAND('n', 'd', NoDelay, "", "Turn on NODELAY TCP option");
COMMAND('l', 'g', Linger, "", "Set LINGER socket option");
COMMAND('g', 's', Getsockname, "", "Get socket name");
COMMAND('g', 'p', Getsockname, "", "Get peer name");
AddSocketCommands();
RunTest(argc, argv);
CleanupSockets();
}

198
GUSI/Examples/GUSIPPCTest.c Executable file
View File

@ -0,0 +1,198 @@
/*********************************************************************
File : GUSI - Grand Unified Socket Interface
File : GUSIPPCTest - Test PPC sockets
Author : Matthias Neeracher <neeri@iis.ethz.ch>
Language : MPW C
$Log$
Revision 1.1.1.1 2001/03/03 21:49:39 chombier
Initial import
Revision 1.1 2000/10/29 20:31:53 neeri
Releasing 2.1.3
Revision 1.2 1994/12/31 01:05:05 neeri
ANSIfy (omitting parameter names was illegal).
Revision 1.1 1994/02/25 02:47:36 neeri
Initial revision
Revision 0.3 1993/06/20 00:00:00 neeri
New sa_constr
Revision 0.2 1992/10/14 00:00:00 neeri
Fix NBP type, usage messages
Revision 0.1 1992/09/08 00:00:00 neeri
Factor out common socket routines
*********************************************************************/
#include "GUSITest.h"
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ppc.h>
#include <Events.h>
#include <TextUtils.h>
#include <PLStringFuncs.h>
void Socket(char ch1, char ch2, const char * line)
{
sock = socket(AF_PPC, SOCK_STREAM, 0);
if (sock == -1) {
printf("# socket() returned error %s\n", Explain());
Where();
}
}
void Bind(char ch1, char ch2, const char * cmd)
{
struct sockaddr_ppc addr;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
addr.sppc_family = AF_PPC;
addr.sppc_port.nameScript = smRoman;
addr.sppc_port.portKindSelector = ppcByString;
addr.sppc_location.locationKindSelector = ppcNBPTypeLocation;
if (sscanf(cmd, "%s %s", addr.sppc_port.name+1, addr.sppc_location.u.nbpType+1) != 2) {
Usage(ch1, ch2);
return;
}
addr.sppc_port.name[0] = strlen(((char *)addr.sppc_port.name)+1);
addr.sppc_location.u.nbpType[0] = strlen(((char *)&addr.sppc_location.u.nbpType)+1);
PLstrcpy((StringPtr) &addr.sppc_port.u.portTypeStr, "\pGUSIPPCTest");
if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_ppc))) {
printf("bind() returned error %s\n", Explain());
Where();
}
}
void Accept(char ch1, char ch2, const char * line)
{
socklen_t len;
struct sockaddr_ppc addr;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (accsock != -1) {
printf("# can't accept more than one connection\n");
Where();
return;
}
len = sizeof(struct sockaddr_ppc);
sock = accept(accsock = sock, (struct sockaddr *) &addr, &len);
if (sock < 0) {
printf("# accept() returned error %s\n", Explain());
sock = accsock;
accsock = -1;
} else {
addr.sppc_port.name[addr.sppc_port.name[0]+1] = 0;
addr.sppc_port.u.portTypeStr[addr.sppc_port.u.portTypeStr[0]+1] = 0;
printf(
"# accepted connection from %s[%s]",
((char *)addr.sppc_port.name)+1,
((char *)addr.sppc_port.u.portTypeStr)+1);
switch (addr.sppc_location.locationKindSelector) {
case ppcNBPLocation:
addr.sppc_location.u.nbpEntity.objStr[addr.sppc_location.u.nbpEntity.objStr[0]+1] = 0;
addr.sppc_location.u.nbpEntity.typeStr[addr.sppc_location.u.nbpEntity.typeStr[0]+1] = 0;
addr.sppc_location.u.nbpEntity.zoneStr[addr.sppc_location.u.nbpEntity.zoneStr[0]+1] = 0;
printf(
"@%s:%s:%s\n",
((char *)addr.sppc_location.u.nbpEntity.objStr)+1,
((char *)addr.sppc_location.u.nbpEntity.typeStr)+1,
((char *)addr.sppc_location.u.nbpEntity.zoneStr)+1);
break;
case ppcNBPTypeLocation:
addr.sppc_location.u.nbpType[addr.sppc_location.u.nbpType[0]+1] = 0;
printf("@%s\n", ((char *)addr.sppc_location.u.nbpType)+1);
break;
default:
printf("\n");
break;
}
}
Where();
}
Boolean BrowseForName(struct sockaddr_ppc * name)
{
PortInfoRec info;
if (PPCBrowser(
"\pConnect where?",
(StringPtr) "\p",
false,
&name->sppc_location,
&info,
(PPCFilterUPP)nil,
"\pGUSIPPCTest"))
return false;
name->sppc_family = AF_PPC;
name->sppc_port = info.name;
return true;
}
void Connect(char ch1, char ch2, const char * cmd)
{
socklen_t len;
struct sockaddr_ppc addr;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (!BrowseForName(&addr))
return;
if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_ppc))) {
printf("# connect() returned error %s\n", Explain());
Where();
}
}
main(int argc, char ** argv)
{
printf("GUSIPPCTest MN 10Jan98\n\n");
COMMAND('s', 's', Socket, "", "Create a stream socket");
COMMAND('b', 'd', Bind, "Name Type", "Bind to address");
COMMAND('c', 'o', Connect, "", "Connect to address");
COMMAND('a', 'c', Accept, "", "Accept a connection");
AddSocketCommands();
RunTest(argc, argv);
CleanupSockets();
}

395
GUSI/Examples/GUSISocketTest.c Executable file
View File

@ -0,0 +1,395 @@
/*********************************************************************
File : GUSI - Grand Unified Socket Interface
File : GUSISocketTest.c - Socket testing gear
Author : Matthias Neeracher <neeri@iis.ethz.ch>
Language : MPW C
$Log$
Revision 1.1.1.1 2001/03/03 21:49:39 chombier
Initial import
Revision 1.6 2000/05/23 06:41:40 neeri
Separate out descriptor commands
Revision 1.5 1999/12/13 03:07:24 neeri
Releasing 2.0.2
Revision 1.4 1999/11/15 07:52:30 neeri
Last Call for 2.0.1
Revision 1.3 1999/08/02 06:59:24 neeri
Added support for asynchronous errors
Revision 1.2 1999/04/10 04:25:54 neeri
Change to more standard compliant headers
Revision 1.1 1998/10/25 11:57:27 neeri
Ready to release 2.0a3
Revision 1.2 1994/12/31 01:12:21 neeri
ANSIfy.
Roundtrip benchmark.
Revision 1.1 1994/02/25 02:47:47 neeri
Initial revision
Revision 0.1 1992/09/08 00:00:00 neeri
Factor out more common code
*********************************************************************/
#include "GUSITest.h"
#include <Types.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <LowMem.h>
int sock = -1;
int accsock = -1;
void Close(char ch1, char ch2, const char * cmd)
{
if (close(sock)) {
printf("# close() returned error %s\n", Explain());
Where();
}
sock = accsock;
accsock = -1;
}
void Listen(char ch1, char ch2, const char * cmd)
{
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (listen(sock, 5)) {
printf("# listen() returned error %s\n", Explain());
Where();
}
}
void Write(char ch1, char ch2, const char * line)
{
int len = strlen(line);
int part;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
for (; len; len -= part, line += part) {
part = write(sock, line, len);
if (part < 0) {
printf("# write(\"%s\") returned error %s\n", line, Explain());
Where();
break;
}
}
}
void Read(char ch1, char ch2, const char * cmd)
{
int len;
char buf[500];
char * line;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
len = read(sock, buf, 500);
if (len < 0) {
printf("# read() returned error %s\n", Explain());
} else {
buf[len] = 0;
printf("# read() returned:\n");
for (line = strtok(buf, "\n\r"); line; line = strtok(nil, "\n\r"))
printf("# %s\n", line);
}
Where();
}
void Select(char ch1, char ch2, const char * cmd)
{
int res;
fd_set rdfds;
fd_set wrfds;
fd_set exfds;
struct timeval delay;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
FD_ZERO(&rdfds);
FD_ZERO(&wrfds);
FD_ZERO(&exfds);
FD_SET(sock, &rdfds);
FD_SET(sock, &wrfds);
FD_SET(sock, &exfds);
delay.tv_sec = 10;
delay.tv_usec = 0;
res = select(sock+1, &rdfds, &wrfds, &exfds, &delay);
if (res < 0) {
printf("# select() returned error %s\n", Explain());
} else if (!res) {
printf("# select() timed out\n");
} else {
printf(
"# select() returned %s%s%s\n",
FD_ISSET(sock, &rdfds) ? "canRead " : "",
FD_ISSET(sock, &wrfds) ? "canWrite " : "",
FD_ISSET(sock, &exfds) ? "exception " : "");
}
Where();
}
void TogBlk(char ch1, char ch2, const char * cmd)
{
int block;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
switch (fcntl(sock, F_GETFL, 0)) {
case 0:
block = 1;
break;
default:
block = 0;
break;
case -1:
printf("# fcntl(F_GETFL) returned error %s\n", Explain());
Where();
return;
}
if (fcntl(sock, F_SETFL, block ? O_NONBLOCK : 0))
printf(
"# ioctl(FIONBIO, %s) returned error %s\n",
block ? "true" : "false",
Explain());
else
printf("# Socket is now %s\n", block ? "nonblocking" : "blocking");
Where();
}
void NRead(char ch1, char ch2, const char * cmd)
{
int nread;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (ioctl(sock, FIONREAD, (long *) &nread))
printf("# ioctl(FIONREAD) returned error %s\n", Explain());
else
printf("# %d bytes waiting to be read\n", nread);
Where();
}
void GetError(char ch1, char ch2, const char * cmd)
{
int err;
socklen_t len = sizeof(int);
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len))
printf("# getsockopt(SOL_SOCKET, SO_ERROR) returned error %s\n", Explain());
else {
errno = err;
printf("# Asynchronous error was %d (%s)\n", err, Explain());
}
Where();
}
static char BenchBuf[8192];
void BenchSer(char ch1, char ch2, const char * cmd)
{
char * at;
int requestSize;
int responseSize;
int packetSize;
int count;
int i;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
at = BenchBuf;
do {
at += read(sock, at, 1024);
*at = 0;
} while (!strchr(BenchBuf, '\015'));
sscanf(BenchBuf, "%d %d %d\015", &requestSize, &responseSize, &count);
write(sock, BenchBuf, 1);
for (i=0; i++<count; ) {
packetSize = 0;
do {
packetSize += read(sock, BenchBuf, 8192);
} while (packetSize < requestSize);
write(sock, BenchBuf, responseSize);
}
}
void BenchCli(char ch1, char ch2, const char * cmd)
{
int requestSize;
int responseSize;
int packetSize;
int contribSize;
int count;
int i;
long startTime;
long transTime;
Sampler readSamp;
Sampler writeSamp;
Sampler sizeSamp;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (sscanf(cmd, "%d %d %d", &requestSize, &responseSize, &count) != 3) {
Usage(ch1, ch2);
return;
}
InitSampler(&readSamp);
InitSampler(&writeSamp);
InitSampler(&sizeSamp);
write(sock, cmd, strlen(cmd)-1);
write(sock, "\015", 1);
read(sock, BenchBuf, 1);
startTime = LMGetTicks();
for (i=0; i++<count; ) {
transTime = LMGetTicks();
write(sock, BenchBuf, requestSize);
Sample(&writeSamp, LMGetTicks()-transTime);
packetSize = 0;
transTime = LMGetTicks();
do {
contribSize = read(sock, BenchBuf, 8192);
packetSize += contribSize;
Sample(&sizeSamp, contribSize);
} while (packetSize < responseSize);
Sample(&readSamp, LMGetTicks()-transTime);
}
printf("# Test took %d ticks.\n", LMGetTicks() - startTime);
printf("# Read min: %2d max: %2d avg: %2.1f\n",
readSamp.min, readSamp.max, ((double)readSamp.sum) / readSamp.count);
printf("# Size min: %2d max: %2d avg: %2.1f\n",
sizeSamp.min, sizeSamp.max, ((double)sizeSamp.sum) / sizeSamp.count);
printf("# Write min: %2d max: %2d avg: %2.1f\n",
writeSamp.min, writeSamp.max, ((double)writeSamp.sum) / writeSamp.count);
}
void Shutdown(char ch1, char ch2, const char * cmd)
{
int what;
if (sock == -1) {
printf("# socket is not open\n");
Where();
return;
}
if (sscanf(cmd, "%d", &what) != 1) {
Usage(ch1, ch2);
return;
}
if (shutdown(sock, what))
printf("# shutdown(%d) returned error %s\n", what, Explain());
}
void AddDescriptorCommands()
{
COMMAND('c', 'l', Close, "", "Close socket");
COMMAND('w', 'r', Write, "text", "Write a line");
COMMAND('r', 'd', Read, "", "Read");
COMMAND('s', 'e', Select, "", "Select a socket");
COMMAND('t', 'b', TogBlk, "", "Toggle blocking status");
COMMAND('n', 'r', NRead, "", "Number of bytes to be read");
}
void AddSocketCommands()
{
AddDescriptorCommands();
COMMAND('l', 'i', Listen, "", "Listen to socket");
COMMAND('b', 's', BenchSer,"", "Benchmark, server side");
COMMAND('b', 'c', BenchCli,"reqSz resSz ct","Benchmark, client side");
COMMAND('g', 'e', GetError,"", "Get asynchronous error");
COMMAND('s', 'd', Shutdown,"", "Shutdown one side of socket");
}
void CleanupSockets()
{
if (sock != -1)
close(sock);
if (accsock != -1)
close(accsock);
}

Binary file not shown.

310
GUSI/Examples/GUSITest.c Executable file
View File

@ -0,0 +1,310 @@
/*********************************************************************
File : GUSI - Grand Unified Socket Interface
File : GUSITest.c - Common testing gear
Author : Matthias Neeracher <neeri@iis.ethz.ch>
Language : MPW C
$Log$
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
Initial import
Revision 1.4 2000/05/23 06:45:28 neeri
Add profiler support
Revision 1.3 1999/06/28 05:43:30 neeri
Handle signals
Revision 1.2 1999/04/10 04:26:22 neeri
Get rid of nonstandard error codes
Revision 1.1 1998/10/25 11:57:28 neeri
Ready to release 2.0a3
Revision 1.2 1994/12/31 01:15:09 neeri
ANSIfy.
Benchmark support.
Revision 1.1 1994/02/25 02:47:57 neeri
Initial revision
Revision 0.2 1992/09/20 00:00:00 neeri
Allow empty lines & comments
Revision 0.1 1992/09/08 00:00:00 neeri
Factor out more common code
*********************************************************************/
#include <Memory.h>
#include <QuickDraw.h>
#include "GUSITest.h"
#include <Types.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/errno.h>
#if __profile__
#include <Profiler.h>
#endif
#ifdef __MWERKS__
#include <SIOUX.h>
#endif
Boolean HellHoundOnMyTrail = true; /* Gotta keep on moving */
char infilename[200];
char * inputfrom;
FILE * input;
int inputline;
CmdDef commands[NROFCMDS];
void Help(char ch1, char ch2, const char * cmd)
{
printf("Commands are:\n\n");
for (ch1 = 'a'; ch1 <= 'z'; ++ch1)
for (ch2 = 0; ch2 <= 'z'; ch2 ? ++ch2 : (ch2 = 'a'))
if (HELPMSG(ch1,ch2))
printf(
" %c%c %-25s -- %s\n",
ch1,
ch2 ? ch2 : ' ',
USAGE(ch1,ch2),
HELPMSG(ch1,ch2));
printf("\n");
}
void Where()
{
if (inputfrom)
printf("File '%s'; Line %d\n", inputfrom, inputline);
}
void Prompt()
{
if (!inputfrom)
printf("[%d]%c", inputline, ' ');
}
#define CASE(code) case code: return #code
const char * Explain()
{
switch (errno) {
CASE(EPERM);
CASE(ENOENT);
CASE(ESRCH);
CASE(EINTR);
CASE(EIO);
CASE(ENXIO);
CASE(E2BIG);
CASE(ENOEXEC);
CASE(EBADF);
CASE(ECHILD);
CASE(ENOMEM);
CASE(EACCES);
CASE(EFAULT);
CASE(EBUSY);
CASE(EEXIST);
CASE(EXDEV);
CASE(ENODEV);
CASE(ENOTDIR);
CASE(EISDIR);
CASE(EINVAL);
CASE(ENFILE);
CASE(EMFILE);
CASE(ENOTTY);
CASE(EFBIG);
CASE(ENOSPC);
CASE(ESPIPE);
CASE(EROFS);
CASE(EMLINK);
CASE(EPIPE);
CASE(EDOM);
CASE(ERANGE);
CASE(EWOULDBLOCK);
CASE(EINPROGRESS);
CASE(EALREADY);
CASE(ENOTSOCK);
CASE(EDESTADDRREQ);
CASE(EMSGSIZE);
CASE(EPROTOTYPE);
CASE(ENOPROTOOPT);
CASE(EPROTONOSUPPORT);
CASE(ESOCKTNOSUPPORT);
CASE(EOPNOTSUPP);
CASE(EPFNOSUPPORT);
CASE(EAFNOSUPPORT);
CASE(EADDRINUSE);
CASE(EADDRNOTAVAIL);
CASE(ENETDOWN);
CASE(ENETUNREACH);
CASE(ENETRESET);
CASE(ECONNABORTED);
CASE(ECONNRESET);
CASE(ENOBUFS);
CASE(EISCONN);
CASE(ENOTCONN);
CASE(ESHUTDOWN);
CASE(ETOOMANYREFS);
CASE(ETIMEDOUT);
CASE(ECONNREFUSED);
CASE(ELOOP);
CASE(ENAMETOOLONG);
CASE(EHOSTDOWN);
CASE(EHOSTUNREACH);
CASE(ENOTEMPTY);
CASE(ENOLCK);
CASE(ENOSYS);
default:
return "Unknown";
}
}
void Usage(char ch1, char ch2)
{
printf("# Usage is: %c%c %s\n", ch1, ch2 ? ch2 : ' ', USAGE(ch1,ch2));
Where();
}
void Dispatch(const char * command)
{
char ch1 = command[0];
char ch2 = command[1];
TestCmd exec;
/* We are guaranteed to have at least one valid character */
switch (ch1) {
case '\n':
case '#':
return;
}
if (!ch2)
++command;
else {
if (isspace(ch2)) {
command += 1;
ch2 = 0;
} else
command += 2;
/* Skip rest of first word */
for (; *command && !isspace(*command); ++command);
/* Skip whitespace */
while (isspace(*command))
++command;
}
if (isalpha(ch1) && (!ch2 || isalpha(ch2)) && (exec = DISPATCH(ch1,ch2)))
exec(ch1, ch2, command);
else {
if (ch2)
printf("# Unknown command: '%c%c'\n", ch1, ch2);
else
printf("# Unknown command: '%c'\n", ch1);
printf("# Type 'h' for a list of known commands.\n");
Where();
}
}
void Quit(char ch1, char ch2, const char * cmd)
{
HellHoundOnMyTrail = false;
}
void signal_handler(int sig)
{
/* Don't do anything, just interrupt system calls */
}
void Alarm(char ch1, char ch2, const char * cmd)
{
signal(SIGALRM, signal_handler);
alarm(atoi(cmd));
}
void InitSampler(Sampler * samp)
{
samp->count = 0;
samp->min = 0x7FFFFFFF;
samp->max = -samp->min;
samp->sum = 0;
}
void Sample(Sampler * samp, long sample)
{
++samp->count;
if (sample < samp->min)
samp->min = sample;
if (sample > samp->max)
samp->max = sample;
samp->sum += sample;
}
void RunTest(int argc, char ** argv)
{
struct sigaction act;
char cmd[80];
#if __profile__
ProfilerInit(collectDetailed, bestTimeBase, 100, 20);
ProfilerSetStatus(0);
#endif
COMMAND('h', 0, Help, "", "Print this list");
COMMAND('a', 'l', Alarm, "n", "Raise an alarm in n seconds");
COMMAND('q', 0, Quit, "", "End the sad existence of this program");
#ifdef __MWERKS__
SIOUXSettings.asktosaveonclose = false;
#else
InitGraf((Ptr) &qd.thePort);
#endif
act.sa_handler = signal_handler;
act.sa_mask = 0;
act.sa_flags = 0;
sigaction(SIGINT, &act, NULL);
if (--argc <= 0)
Help('h', 0, "");
do {
if (argc > 0 && strcmp(inputfrom = *++argv, "-")) {
printf("Executing %sÉ\n", inputfrom);
input = fopen(inputfrom, "r");
} else {
inputfrom = 0;
input = stdin;
}
inputline = 1;
while (HellHoundOnMyTrail && (Prompt(), fgets(cmd, 80, input))) {
#if __profile__
ProfilerSetStatus(1);
#endif
Dispatch(cmd);
#if __profile__
ProfilerSetStatus(0);
#endif
++inputline;
}
} while (HellHoundOnMyTrail && --argc > 0);
#if __profile__
ProfilerDump("\pGUSI.prof");
ProfilerTerm();
#endif
printf("So long, it's been good to know you.\n");
}

110
GUSI/Examples/GUSITest.h Executable file
View File

@ -0,0 +1,110 @@
/*********************************************************************
File : GUSI - Grand Unified Socket Interface
File : GUSITest.h - Common testing gear
Author : Matthias Neeracher <neeri@iis.ethz.ch>
Language : MPW C
$Log$
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
Initial import
Revision 1.2 2000/05/23 06:43:25 neeri
Separate out descriptor commands
Revision 1.1 1998/10/25 11:57:29 neeri
Ready to release 2.0a3
Revision 1.2 1994/12/31 01:18:29 neeri
Benchmark support.
Revision 1.1 1994/02/25 02:48:06 neeri
Initial revision
Revision 0.1 1992/09/08 00:00:00 neeri
Factor out more common code
*********************************************************************/
#ifndef _GUSITEST_
#define _GUSITEST_
typedef void (*TestCmd)(char ch1, char ch2, const char * restcmd);
#include "GUSITest_P.h"
#include <stdio.h>
extern FILE * input;
extern int inputline;
/* void COMMAND(
char ch1, char ch2, Command name
TestCmd p, Command to be run
char * s, Arguments to command
char * h); Explanation for command
Example:
COMMAND('m', 'd', MkDir, "directory", "Make a new directory");
*/
#define COMMAND(ch1,ch2,p,s,h) \
DISPATCH(ch1,ch2) = (p), \
USAGE(ch1,ch2) = (s), \
HELPMSG(ch1,ch2) = (h)
/* An useful macro for dumping variables.
Example:
DUMP(statbuf.st_dev,d);
*/
#define DUMP(EXPR, MODE) printf("# %s = %"#MODE"\n", #EXPR, EXPR)
/* Add common commands for descriptors */
void AddDescriptorCommands();
/* Add common commands for sockets */
void AddSocketCommands();
/* Run the test. Define your commands with COMMAND and call this */
void RunTest(int argc, char ** argv);
/* Print a MPW executable location note */
void Where();
/* Print a prompt */
void Prompt();
/* Return a string of the current error number, e.g. "EINVAL" */
const char * Explain();
/* Print a usage message for a command */
void Usage(char ch1, char ch2);
/* Clean up sockets */
void CleanupSockets();
extern int sock; /* Socket to read/write to */
extern int accsock; /* Socket to accept connections on */
/* Keep statistics on a series of values */
typedef struct {
int count;
long min;
long max;
long sum;
} Sampler;
void InitSampler(Sampler * samp);
void Sample(Sampler * samp, long sample);
#endif

37
GUSI/Examples/GUSITest.r Executable file
View File

@ -0,0 +1,37 @@
/*********************************************************************
Project : GUSI - Grand Unified Socket Interface
File : GUSITest - Testing gear
Author : Matthias Neeracher <neeri@iis.ethz.ch>
Language : MPW C
$Log$
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
Initial import
Revision 1.1 1998/10/25 11:57:30 neeri
Ready to release 2.0a3
Revision 1.2 1994/12/31 01:16:51 neeri
Add GU·I resource.
Revision 1.1 1994/02/25 02:48:17 neeri
Initial revision
Revision 0.2 1993/03/03 00:00:00 neeri
define GUSI_PREF_VERSION
Revision 0.1 1992/07/13 00:00:00 neeri
Include GUSI.r
*********************************************************************/
#define GUSI_PREF_VERSION '0150'
#include "GUSI.r"
resource 'GU·I' (GUSIRsrcID) {
text, mpw, noAutoSpin, useChdir, approxStat,
noTCPDaemon, noUDPDaemon,
noConsole,
{};
};

BIN
GUSI/Examples/GUSITest.rsrc Executable file

Binary file not shown.

38
GUSI/Examples/GUSITest_P.h Executable file
View File

@ -0,0 +1,38 @@
/*********************************************************************
File : GUSI - Grand Unified Socket Interface
File : GUSITest_P.h - Common testing gear
Author : Matthias Neeracher <neeri@iis.ethz.ch>
Language : MPW C
$Log$
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
Initial import
Revision 1.1 1994/02/25 02:48:27 neeri
Initial revision
*********************************************************************/
#ifndef _GUSITEST_P_
#define _GUSITEST_P_
#include <CType.h>
#define NROFCHARS 26
#define DECODE(ch) ((ch) ? (ch) - (isupper(ch) ? 'A' : 'a') + 1 : 0)
#define CMDCODE(ch1,ch2) (DECODE(ch1)*(NROFCHARS+1)+DECODE(ch2))
#define NROFCMDS (NROFCHARS+1)*(NROFCHARS+1)
typedef struct {
TestCmd proc;
const char * syntax;
const char * help;
} CmdDef;
extern CmdDef commands[NROFCMDS];
#define DISPATCH(ch1,ch2) commands[CMDCODE(ch1,ch2)].proc
#define USAGE(ch1,ch2) commands[CMDCODE(ch1,ch2)].syntax
#define HELPMSG(ch1,ch2) commands[CMDCODE(ch1,ch2)].help
#endif

147
GUSI/Examples/GUSIThreadTest.c Executable file
View File

@ -0,0 +1,147 @@
/*********************************************************************
File : GUSI - Grand Unified Socket Interface
File : GUSIThreadTest - Testthread related features
Author : Matthias Neeracher <neeri@iis.ethz.ch>
Language : MPW C
$Log$
Revision 1.1.1.1 2001/03/03 21:49:54 chombier
Initial import
Revision 1.1 2000/10/29 20:31:53 neeri
Releasing 2.1.3
*********************************************************************/
#include "GUSITest.h"
#include <pthread.h>
#include <sched.h>
#include <LowMem.h>
typedef struct {
pthread_mutex_t fMutex;
int fCounter;
int fLoops;
char fType;
} Shared;
void *
MutexPerformanceProc(void *arg)
{
Shared * shared = (Shared *)arg;
int i;
if (shared->fType == 'm') {
for (i = 0; i < shared->fLoops; i++) {
pthread_mutex_lock(&shared->fMutex);
shared->fCounter++;
pthread_mutex_unlock(&shared->fMutex);
}
} else {
pthread_mutex_lock(&shared->fMutex);
pthread_mutex_unlock(&shared->fMutex);
for (i = 0; i < shared->fLoops; i++) {
shared->fCounter++;
if (shared->fType == 'y')
sched_yield();
}
}
return(NULL);
}
/* end incr */
void MutexPerformance(char ch1, char ch2, const char * cmd)
{
int nloops;
int nthreads;
pthread_t tid[20];
Shared shared;
int i;
int fairness;
unsigned long start_time;
unsigned long stop_time;
if (sscanf(cmd, "%d %d", &shared.fLoops, &nthreads) != 2)
Usage(ch1, ch2);
else {
if (nthreads < 1) {
printf("Too few threads specified, using 1\n");
nthreads = 1;
} else if (nthreads > 20) {
printf("Too many threads specified, using 20\n");
nthreads = 20;
}
shared.fCounter = 0;
shared.fType = ch1;
pthread_mutex_init(&shared.fMutex, NULL);
pthread_mutex_lock(&shared.fMutex);
for (i = 0; i < nthreads; i++)
pthread_create(&tid[i], NULL, MutexPerformanceProc, &shared);
start_time = LMGetTicks();
pthread_mutex_unlock(&shared.fMutex);
/* 4wait for all the threads */
pthread_join(tid[0], NULL);
fairness = shared.fCounter;
for (i = 1; i < nthreads; i++)
pthread_join(tid[i], NULL);
stop_time = LMGetTicks();
printf("Time: %f seconds, Fairness: %.2f%\n",
(stop_time - start_time) / 60.0,
(fairness * 100.0) / ((shared.fLoops-1) * nthreads + 1));
if (shared.fCounter != shared.fLoops * nthreads)
printf("error: counter = %ld\n", shared.fCounter);
pthread_mutex_destroy(&shared.fMutex);
}
}
void Sleep(char ch1, char ch2, const char * cmd)
{
int seconds;
if (sscanf(cmd, "%d", &seconds) != 1)
Usage(ch1, ch2);
else
printf("Remaining: %ds\n", sleep(seconds));
}
void Times(char ch1, char ch2, const char * cmd)
{
time_t lmk, gmk;
time_t now = time(NULL);
struct tm * t = localtime(&now);
printf("Localtime %d/%d/%d %d:%02d:%02d %s\n",
t->tm_year+1900, t->tm_mon+1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, t->tm_isdst ? "DST" : "");
lmk = mktime(t);
t = gmtime(&now);
printf("GMtime %d/%d/%d %d:%02d:%02d %s\n",
t->tm_year+1900, t->tm_mon+1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, t->tm_isdst ? "DST" : "");
gmk = mktime(t);
printf("Now %u Local %u GM %u\n", now, lmk, gmk);
}
main(int argc, char ** argv)
{
printf("GUSIFileTest MN 25OCt00\n\n");
COMMAND('m', 'p', MutexPerformance, "#loops #threads", "Test mutex performance");
COMMAND('y', 'p', MutexPerformance, "#loops #threads", "Test yield performance");
COMMAND('n', 'p', MutexPerformance, "#loops #threads", "Test noyield performance");
COMMAND('s', 'l', Sleep, "seconds", "sleep");
COMMAND('t', 'm', Times, "", "Test time related functions");
RunTest(argc, argv);
}

BIN
GUSI/Examples/MSLGUSITest.pch Executable file

Binary file not shown.

BIN
GUSI/Examples/Makefile Executable file

Binary file not shown.

BIN
GUSI/GUSIConfig.mk Executable file

Binary file not shown.

BIN
GUSI/GUSIConfig/GUSIConfig Executable file

Binary file not shown.

BIN
GUSI/GUSI_Install.MPW Executable file

Binary file not shown.

BIN
GUSI/MANIFEST Executable file

Binary file not shown.

BIN
GUSI/MacDistr Executable file

Binary file not shown.

BIN
GUSI/Makefile.mk Executable file

Binary file not shown.

BIN
GUSI/README Executable file

Binary file not shown.

BIN
GUSI/STLport_Install.MPW Executable file

Binary file not shown.

BIN
GUSI/doc/GUSI.pdf Executable file

Binary file not shown.

BIN
GUSI/doc/GUSI_CW_Guide.pdf Executable file

Binary file not shown.

BIN
GUSI/doc/pod/GUSI.cmd Executable file

Binary file not shown.

BIN
GUSI/doc/pod/GUSI.pod Executable file

Binary file not shown.

BIN
GUSI/doc/pod/GUSI_Common.pod Executable file

Binary file not shown.

BIN
GUSI/doc/pod/GUSI_Files.pod Executable file

Binary file not shown.

BIN
GUSI/doc/pod/GUSI_Install.pod Executable file

Binary file not shown.

BIN
GUSI/doc/pod/GUSI_Misc.pod Executable file

Binary file not shown.

BIN
GUSI/doc/pod/GUSI_Sockets.pod Executable file

Binary file not shown.

BIN
GUSI/doc/pod/GUSI_Threads.pod Executable file

Binary file not shown.

173
GUSI/include/GUSIBasics.h Executable file
View File

@ -0,0 +1,173 @@
// <GUSIBasics.h>=
#ifndef _GUSIBasics_
#define _GUSIBasics_
#ifdef GUSI_SOURCE
#include <errno.h>
#include <sys/cdefs.h>
#include <stdarg.h>
#include <ConditionalMacros.h>
// \section{Definition of compiler features}
//
// If possible, we use unnamed namespaces to wrap internal code.
//
// <Definition of compiler features>=
#ifdef __MWERKS__
#define GUSI_COMPILER_HAS_NAMESPACE
#endif
#ifdef GUSI_COMPILER_HAS_NAMESPACE
#define GUSI_USING_STD_NAMESPACE using namespace std; using namespace std::rel_ops;
#else
#define GUSI_USING_STD_NAMESPACE
#endif
// Asynchronous MacOS calls need completion procedures which in classic 68K code
// often take parameters in address registers. The way to handle this differs
// a bit between compilers. Note that the [[pascal]] keyword is ignored when
// generating CFM code.
//
// <Definition of compiler features>=
#if GENERATINGCFM
#define GUSI_COMPLETION_PROC_A0(proc, type) \
void (*const proc##Entry)(type * param) = proc;
#define GUSI_COMPLETION_PROC_A1(proc, type) \
void (*const proc##Entry)(type * param) = proc;
#elif defined(__MWERKS__)
#define GUSI_COMPLETION_PROC_A0(proc, type) \
static pascal void proc##Entry(type * param : __A0) { proc(param); }
#define GUSI_COMPLETION_PROC_A1(proc, type) \
static pascal void proc##Entry(type * param : __A1) { proc(param); }
#else
void * GUSIGetA0() ONEWORDINLINE(0x2008);
void * GUSIGetA1() ONEWORDINLINE(0x2009);
#define GUSI_COMPLETION_PROC_A0(proc, type) \
static pascal void proc##Entry() \
{ proc(reinterpret_cast<type *>(GUSIGetA0())); }
#define GUSI_COMPLETION_PROC_A1(proc, type) \
static pascal void proc##Entry() \
{ proc(reinterpret_cast<type *>(GUSIGetA1())); }
#endif
// %define GUSI_COMPLETION_PROC_A0 GUSI_COMPLETION_PROC_A1
//
// SC seems to have an issue with mutable fields.
//
// <Definition of compiler features>=
#if defined(__SC__)
#define mutable
#define GUSI_MUTABLE(class, field) const_cast<class *>(this)->field
#else
#define GUSI_MUTABLE(class, field) field
#endif
// SC pretends to support standard scoping rules, but is in fact broken in
// some cases.
//
// <Definition of compiler features>=
#if defined(__SC__)
#define for if (0) ; else for
#endif
// The MPW compilers don't predeclare [[qd]].
//
// <Definition of compiler features>=
#if defined(__SC__) || defined(__MRC__)
#define GUSI_NEEDS_QD QDGlobals qd;
#else
#define GUSI_NEEDS_QD
#endif
// \section{Definition of hook handling}
//
// GUSI supports a number of hooks. Every one of them has a different prototype,
// but is passed as a [[GUSIHook]]. Hooks are encoded with an [[OSType]].
//
// <Definition of hook handling>=
typedef unsigned long OSType;
typedef void (*GUSIHook)(void);
void GUSISetHook(OSType code, GUSIHook hook);
GUSIHook GUSIGetHook(OSType code);
// Currently, three hooks are supported: [[GUSI_SpinHook]] defines a function to
// be called when GUSI waits on an event.
// [[GUSI_ExecHook]] defines a function that determines whether a file is to be
// considered ``executable''. [[GUSI_EventHook]] defines a routine that is called
// when a certain event happens. To install an event hook, pass [[GUSI_EventHook]]
// plus the event code. A few events, that is mouse-down and high level events,
// are handled automatically by GUSI. Passing [[-1]] for the hook disables default
// handling of an event.
//
// <Definition of hook handling>=
typedef bool (*GUSISpinFn)(bool wait);
#define GUSI_SpinHook 'spin'
struct FSSpec;
typedef bool (*GUSIExecFn)(const FSSpec * file);
#define GUSI_ExecHook 'exec'
struct EventRecord;
typedef void (*GUSIEventFn)(EventRecord * ev);
#define GUSI_EventHook 'evnt'
// For the purposes of the functions who actually call the hooks, here's the direct
// interface.
//
// <Definition of hook handling>=
#ifdef GUSI_INTERNAL
extern GUSISpinFn gGUSISpinHook;
extern GUSIExecFn gGUSIExecHook;
#endif /* GUSI_INTERNAL */
// \section{Definition of error handling}
//
// Like a good POSIX citizen, GUSI reports all errors in the [[errno]] global
// variable. This happens either through the [[GUSISetPosixError]] routine, which
// stores its argument untranslated, or through the [[GUSISetMacError]] routine,
// which translates MacOS error codes into the correct POSIX codes. The mapping
// of [[GUSISetMacError]] is not always appropriate, so some routines will have to
// preprocess some error codes. [[GUSIMapMacError]] returns the POSIX error corresponding
// to a MacOS error.
//
// The domain name routines use an analogous variable [[h_errno]], which is
// manipulated with [[GUSISetHostError]] and [[GUSISetMacHostError]].
//
// All routines return 0 if 0 was passed and -1 otherwise.
//
// <Definition of error handling>=
typedef short OSErr;
int GUSISetPosixError(int error);
int GUSISetMacError(OSErr error);
int GUSIMapMacError(OSErr error);
int GUSISetHostError(int error);
int GUSISetMacHostError(OSErr error);
// POSIX routines should never set [[errno]] from nonzero to zero. On the other
// hand, it's sometimes useful to see whether some particular region of the
// program set the error code or not. Therefore, we have such regions allocate
// a [[GUSIErrorSaver]] statically, which guarantees that previous error codes
// get restored if necessary.
//
// <Definition of error handling>=
class GUSIErrorSaver {
public:
GUSIErrorSaver() { fSavedErrno = ::errno; ::errno = 0; }
~GUSIErrorSaver() { if (!::errno) ::errno = fSavedErrno; }
private:
int fSavedErrno;
};
// \section{Definition of event handling}
//
// [[GUSIHandleNextEvent]] events by calling handlers installed
// using the [[GUSI_EventHook]] mechanism.
//
// <Definition of event handling>=
void GUSIHandleNextEvent(long sleepTime);
// \section{Definition of string formatting}
//
// We occasionally need sprintf. To keep compatibility with MSL, Stdio, and Sfio,
// we use an internal version which can be overridden.
//
// <Definition of string formatting>=
int GUSI_vsprintf(char * s, const char * format, va_list args);
int GUSI_sprintf(char * s, const char * format, ...);
#endif /* GUSI_SOURCE */
#endif /* _GUSIBasics_ */

409
GUSI/include/GUSIBuffer.h Executable file
View File

@ -0,0 +1,409 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIBuffer.nw - Buffering for GUSI
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:08 chombier
// % Initial import
// %
// % Revision 1.20 2001/01/17 08:33:14 neeri
// % Need to set fOldBuffer to nil after deleting
// %
// % Revision 1.19 2000/10/16 04:34:22 neeri
// % Releasing 2.1.2
// %
// % Revision 1.18 2000/05/23 06:53:14 neeri
// % Improve formatting
// %
// % Revision 1.17 2000/03/15 07:22:06 neeri
// % Enforce alignment choices
// %
// % Revision 1.16 1999/09/09 07:19:18 neeri
// % Fix read-ahead switch-off
// %
// % Revision 1.15 1999/08/26 05:44:59 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.14 1999/06/30 07:42:05 neeri
// % Getting ready to release 2.0b3
// %
// % Revision 1.13 1999/05/30 03:09:29 neeri
// % Added support for MPW compilers
// %
// % Revision 1.12 1999/03/17 09:05:05 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.11 1998/11/22 23:06:50 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.10 1998/10/25 11:28:43 neeri
// % Added MSG_PEEK support, recursive locks.
// %
// % Revision 1.9 1998/08/02 12:31:36 neeri
// % Another typo
// %
// % Revision 1.8 1998/08/02 11:20:06 neeri
// % Fixed some typos
// %
// % Revision 1.7 1998/01/25 20:53:51 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.6 1997/11/13 21:12:08 neeri
// % Fall 1997
// %
// % Revision 1.5 1996/12/22 19:57:55 neeri
// % TCP streams work
// %
// % Revision 1.4 1996/12/16 02:16:02 neeri
// % Add Size(), make inlines inline, use BlockMoveData
// %
// % Revision 1.3 1996/11/24 13:00:26 neeri
// % Fix comment leaders
// %
// % Revision 1.2 1996/11/24 12:52:05 neeri
// % Added GUSIPipeSockets
// %
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
// % Imported into CVS
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Buffering for GUSI}
//
// This section defines four classes that handle buffering for GUSI:
// [[GUSIScatterer]], [[GUSIGatherer]], and their common ancestor
// [[GUSIScattGath]] convert between [[iovecs]] and simple buffers in the
// absence of specialized communications routines. A [[GUSIRingBuffer]]
// mediates between a producer and a consumer, one of which is typically
// normal code and the other interrupt level code.
//
//
// <GUSIBuffer.h>=
#ifndef _GUSIBuffer_
#define _GUSIBuffer_
#ifdef GUSI_SOURCE
#include <sys/types.h>
#include <sys/uio.h>
#include <MacTypes.h>
#include "GUSIDiag.h"
#include "GUSIBasics.h"
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of scattering/gathering}
//
// A [[GUSIScattGath]] translates between an array of [[iovecs]] and a simple buffer,
// allocating scratch space if necessary.
//
// <Definition of class [[GUSIScattGath]]>=
class GUSIScattGath {
protected:
// On constructing a [[GUSIScattGath]], we pass an array of [[iovecs]]. For the
// simpler functions, a variant with a single [[buffer]] and [[length]] is also
// available.
//
// <Constructor and destructor for [[GUSIScattGath]]>=
GUSIScattGath(const iovec *iov, int count, bool gather);
GUSIScattGath(void * buffer, size_t length, bool gather);
virtual ~GUSIScattGath();
public:
// The [[iovec]], the buffer and its length are then available for public scrutinity.
// Copy constructor and assignment both are a bit nontrivial.
//
// <Public interface to [[GUSIScattGath]]>=
const iovec * IOVec() const;
int Count() const;
void * Buffer() const;
operator void *() const;
int Length() const;
int SetLength(int len) const;
void operator=(const GUSIScattGath & other);
GUSIScattGath(const GUSIScattGath & other);
private:
// \section{Implementation of scattering/gathering}
//
// A [[GUSIScattGath]] always consists of [[fIo]], an array of [[iovecs]], [[fCount]],
// the number of sections in the array, and [[fLen]], the total size of the data area.
// If [[fCount]] is 1, [[fBuf]] will be a copy of the pointer to the single section. If
// [[fCount]] is greater than 1, [[fScratch]] will contain a [[Handle]] to a scratch
// area of size [[len]] and [[fBuf]] will contain [[*scratch]]. If the object was
// constructed without providing an [[iovec]] array, [[fTrivialIo]] will be set up
// to hold one.
//
// <Privatissima of [[GUSIScattGath]]>=
const iovec * fIo;
iovec fTrivialIo;
mutable int fCount;
mutable Handle fScratch;
mutable void * fBuf;
mutable int fLen;
bool fGather;
};
// A [[GUSIScatterer]] distributes the contents of a buffer over an array of
// [[iovecs]].
//
// <Definition of class [[GUSIScatterer]]>=
class GUSIScatterer : public GUSIScattGath {
public:
GUSIScatterer(const iovec *iov, int count)
: GUSIScattGath(iov, count, false) {}
GUSIScatterer(void * buffer, size_t length)
: GUSIScattGath(buffer, length, false) {}
GUSIScatterer & operator=(const GUSIScatterer & other)
{ *static_cast<GUSIScattGath *>(this) = other; return *this; }
};
// A [[GUSIGatherer]] collects the contents of an array of [[iovecs]] into a single
// buffer.
//
// <Definition of class [[GUSIGatherer]]>=
class GUSIGatherer : public GUSIScattGath {
public:
GUSIGatherer(const struct iovec *iov, int count)
: GUSIScattGath(iov, count, true) {}
GUSIGatherer(const void * buffer, size_t length)
: GUSIScattGath(const_cast<void *>(buffer), length, true) {}
GUSIGatherer & operator=(const GUSIGatherer & other)
{ *static_cast<GUSIScattGath *>(this) = other; return *this; }
};
// \section{Definition of ring buffering}
//
// A [[GUSIRingBuffer]] typically has on one side a non-preeemptive piece of code
// and on the other side a piece of interrupt code. To transfer data from and to
// the buffer, two interfaces are available: A direct interface that transfers
// memory, and an indirect interface that allocates memory regions and then
// has OS routines transfer data from or to them
//
// <Definition of class [[GUSIRingBuffer]]>=
class GUSIRingBuffer {
public:
// On construction of a [[GUSIRingBuffer]], a buffer of the specified size is
// allocated and not released until destruction. [[operator void*]] may be used
// to determine whether construction was successful.
//
// <Constructor and destructor for [[GUSIRingBuffer]]>=
GUSIRingBuffer(size_t bufsiz);
~GUSIRingBuffer();
operator void*();
// The direct interface to [[GUSIRingBuffer]] is straightforward: [[Produce]] copies
// memory into the buffer, [[Consume]] copies memory from the buffer, [[Free]]
// determines how much space there is for [[Produce]] and [[Valid]] determines
// how much space there is for [[Consume]].
//
// <Direct interface for [[GUSIRingBuffer]]>=
void Produce(void * from, size_t & len);
void Produce(const GUSIGatherer & gather, size_t & len, size_t & offset);
void Produce(const GUSIGatherer & gather, size_t & len);
void Consume(void * to, size_t & len);
void Consume(const GUSIScatterer & scatter, size_t & len, size_t & offset);
void Consume(const GUSIScatterer & scatter, size_t & len);
size_t Free();
size_t Valid();
// [[ProduceBuffer]] tries to find in the ring buffer a contiguous free block of
// memory of the specified size [[len]] or otherwise the biggest available free
// block, returns a pointer to it and sets [[len]] to its length. [[ValidBuffer]]
// specifies that the next [[len]] bytes of the ring buffer now contain valid data.
//
// [[ConsumeBuffer]] returns a pointer to the next valid byte and sets [[len]] to
// the minimum of the number of contiguous valid bytes and the value of len on
// entry. [[FreeBuffer]] specifies that the next [[len]] bytes of the ring
// buffer were consumed and are no longer needed.
//
// <Indirect interface for [[GUSIRingBuffer]]>=
void * ProduceBuffer(size_t & len);
void * ConsumeBuffer(size_t & len);
void ValidBuffer(void * buffer, size_t len);
void FreeBuffer(void * buffer, size_t len);
// Before the nonpreemptive partner changes any of the buffer's data structures,
// the [[GUSIRingBuffer]] member functions call [[Lock]], and after the change is
// complete, they call [[Release]]. An interrupt level piece of code before
// changing any data structures has to determine whether the buffer is locked by
// calling [[Locked]]. If the buffer is locked or otherwise in an unsuitable state,
// the code can specify a procedure to be called during the next [[Release]] by
// calling [[Defer]]. A deferred procedure should call [[ClearDefer]] to avoid
// getting activated again at the next opportunity.
//
// <Synchronization support for [[GUSIRingBuffer]]>=
void Lock();
void Release();
bool Locked();
typedef void (*Deferred)(void *);
void Defer(Deferred def, void * ar);
void ClearDefer();
// It is possible to switch buffer sizes during the existence of a buffer, but we
// have to be somewhat careful, since some asynchronous call may still be writing
// into the old buffer. [[PurgeBuffers]], called at safe times, cleans up old
// buffers.
//
// <Buffer switching for [[GUSIRingBuffer]]>=
void SwitchBuffer(size_t bufsiz);
size_t Size();
void PurgeBuffers();
// Sometimes, it's necessary to do nondestructive reads, a task complex enough to
// warrant its own class.
//
// <Definition of class [[GUSIRingBuffer::Peeker]]>=
class Peeker {
public:
Peeker(GUSIRingBuffer & buffer);
~Peeker();
void Peek(void * to, size_t & len);
void Peek(const GUSIScatterer & scatter, size_t & len);
private:
// A [[GUSIRingBuffer::Peeker]] has to keep its associated [[GUSIRingBuffer]] locked during
// its entire existence.
//
// <Privatissima of [[GUSIRingBuffer::Peeker]]>=
GUSIRingBuffer & fTopBuffer;
GUSIRingBuffer * fCurBuffer;
Ptr fPeek;
// The core routine for reading is [[PeekBuffer]] which automatically advances the
// peeker as well.
//
// <Privatissima of [[GUSIRingBuffer::Peeker]]>=
void * PeekBuffer(size_t & len);
};
friend class Peeker;
void Peek(void * to, size_t & len);
void Peek(const GUSIScatterer & scatter, size_t & len);
private:
// \section{Implementation of ring buffering}
//
// The buffer area of a ring buffer extends between [[fBuffer]] and [[fEnd]]. [[fValid]]
// contains the number of valid bytes, while [[fFree]] and [[fSpare]] (Whose purpose
// will be explained later) sum up to the number of free bytes. [[fProduce]] points at the
// next free byte, while [[fConsume]] points at the next valid byte. [[fInUse]]
// indicates that an asynchronous call might be writing into the buffer.
//
// <Privatissima of [[GUSIRingBuffer]]>=
Ptr fBuffer;
Ptr fEnd;
Ptr fConsume;
Ptr fProduce;
size_t fFree;
size_t fValid;
size_t fSpare;
bool fInUse;
// The relationships between the various pointers are captured by [[Invariant]] which
// uses the auxiliary function [[Distance]] to determine the distance between two
// pointers in the presence of wrap around areas.
//
// <Privatissima of [[GUSIRingBuffer]]>=
bool Invariant();
size_t Distance(Ptr from, Ptr to);
// The lock mechanism relies on [[fLocked]], and the deferred procedure and its argument
// are stored in [[fDeferred]] and [[fDeferredArg]].
//
// <Privatissima of [[GUSIRingBuffer]]>=
int fLocked;
Deferred fDeferred;
void * fDeferredArg;
// We only switch the next time the buffer is empty, so we are prepared to create
// the new buffer dynamically and forward requests to it for a while.
//
// <Privatissima of [[GUSIRingBuffer]]>=
GUSIRingBuffer * fNewBuffer;
GUSIRingBuffer * fOldBuffer;
void ObsoleteBuffer();
// The scatter/gather variants of [[Produce]] and [[Consume]] rely on a common
// strategy.
//
// <Privatissima of [[GUSIRingBuffer]]>=
void IterateIOVec(const GUSIScattGath & sg, size_t & len, size_t & offset, bool produce);
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// Clients need readonly access to the buffer address and read/write access to the length.
// [[operator void*]] server to check whether the [[GUSIScattGath]] was constructed
// successfully.
//
// <Inline member functions for class [[GUSIScattGath]]>=
inline const iovec * GUSIScattGath::IOVec() const
{ return fIo; }
inline int GUSIScattGath::Count() const
{ return fCount; }
inline GUSIScattGath::operator void *() const
{ return Buffer(); }
inline int GUSIScattGath::Length() const
{ return fLen; }
inline int GUSIScattGath::SetLength(int len) const
{ return GUSI_MUTABLE(GUSIScattGath, fLen) = len; }
// <Inline member functions for class [[GUSIRingBuffer]]>=
inline void GUSIRingBuffer::Produce(const GUSIGatherer & gather, size_t & len, size_t & offset)
{
IterateIOVec(gather, len, offset, true);
}
inline void GUSIRingBuffer::Consume(const GUSIScatterer & scatter, size_t & len, size_t & offset)
{
IterateIOVec(scatter, len, offset, false);
}
inline void GUSIRingBuffer::Produce(const GUSIGatherer & gather, size_t & len)
{
size_t offset = 0;
IterateIOVec(gather, len, offset, true);
}
inline void GUSIRingBuffer::Consume(const GUSIScatterer & scatter, size_t & len)
{
size_t offset = 0;
IterateIOVec(scatter, len, offset, false);
}
// The lock support is rather straightforward.
//
// <Inline member functions for class [[GUSIRingBuffer]]>=
inline void GUSIRingBuffer::Lock() { ++fLocked; }
inline bool GUSIRingBuffer::Locked() { return (fLocked!=0); }
inline void GUSIRingBuffer::ClearDefer() { fDeferred = nil; }
inline void GUSIRingBuffer::Release()
{
GUSI_CASSERT_INTERNAL(fLocked > 0);
if (--fLocked <= 0 && fDeferred)
fDeferred(fDeferredArg);
}
inline void GUSIRingBuffer::Defer(Deferred def, void * ar)
{
fDeferred = def;
fDeferredArg = ar;
}
// The size is stored only implicitely.
//
// <Inline member functions for class [[GUSIRingBuffer]]>=
inline size_t GUSIRingBuffer::Size() { return fEnd - fBuffer; }
// <Inline member functions for class [[GUSIRingBuffer]]>=
inline void GUSIRingBuffer::Peek(void * to, size_t & len)
{
Peeker peeker(*this);
peeker.Peek(to, len);
}
inline void GUSIRingBuffer::Peek(const GUSIScatterer & scatter, size_t & len)
{
Peeker peeker(*this);
peeker.Peek(scatter, len);
}
#endif /* GUSI_SOURCE */
#endif /* _GUSIBuffer_ */

289
GUSI/include/GUSIConfig.h Executable file
View File

@ -0,0 +1,289 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIConfig.nw - Configuration settings
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
// % Initial import
// %
// % Revision 1.18 2001/01/22 04:31:11 neeri
// % Last minute changes for 2.1.5
// %
// % Revision 1.17 2001/01/17 08:40:17 neeri
// % Prevent inlining of overridable functions
// %
// % Revision 1.16 2000/05/23 06:54:39 neeri
// % Improve formatting, update to latest universal headers
// %
// % Revision 1.15 2000/03/15 07:10:29 neeri
// % Fix suffix searching code
// %
// % Revision 1.14 2000/03/06 06:24:34 neeri
// % Fix plausibility tests for A5
// %
// % Revision 1.13 1999/09/26 03:56:44 neeri
// % Sanity check for A5
// %
// % Revision 1.12 1999/08/26 05:44:59 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.11 1999/06/28 05:57:03 neeri
// % Support SIGINT generation
// %
// % Revision 1.10 1999/05/29 06:26:41 neeri
// % Fixed header guards
// %
// % Revision 1.9 1999/03/29 09:51:28 neeri
// % New configuration system with support for hardcoded configurations.
// %
// % Revision 1.8 1999/03/17 09:05:05 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.7 1998/10/11 16:45:10 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.6 1998/08/01 21:32:01 neeri
// % About ready for 2.0a1
// %
// % Revision 1.5 1998/01/25 20:53:52 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.4 1997/11/13 21:12:10 neeri
// % Fall 1997
// %
// % Revision 1.3 1996/11/24 13:00:27 neeri
// % Fix comment leaders
// %
// % Revision 1.2 1996/11/24 12:52:06 neeri
// % Added GUSIPipeSockets
// %
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
// % Imported into CVS
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{GUSI Configuration settings}
//
// GUSI stores its global configuration settings in the [[GUSIConfiguration]]
// singleton class. To create the instance, GUSI calls the [[GUSISetupConfig]]
// hook.
//
// <GUSIConfig.h>=
#ifndef _GUSIConfig_
#define _GUSIConfig_
#ifdef GUSI_SOURCE
#include "GUSIFileSpec.h"
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of configuration settings}
//
// The GUSIConfiguration has a single instance with read only access, accessible
// with the static [[Instance]] member function.
//
// <Definition of class [[GUSIConfiguration]]>=
class GUSIConfiguration {
public:
enum { kNoResource = -1, kDefaultResourceID = 10240 };
static GUSIConfiguration * Instance();
static GUSIConfiguration * CreateInstance(short resourceID = kDefaultResourceID);
// To determine the file type and creator of a newly created file, we first try
// to match one of the [[FileSuffix]] suffices.
//
// <Type and creator rules for newly created files>=
struct FileSuffix {
char suffix[4];
OSType suffType;
OSType suffCreator;
};
short fNumSuffices;
FileSuffix * fSuffices;
void ConfigureSuffices(short numSuffices, FileSuffix * suffices);
// If none of the suffices matches, we apply the default type and creator. These
// rules are applied with [[SetDefaultFType]].
//
// <Type and creator rules for newly created files>=
OSType fDefaultType;
OSType fDefaultCreator;
void ConfigureDefaultTypeCreator(OSType defaultType, OSType defaultCreator);
void SetDefaultFType(const GUSIFileSpec & name) const;
// To simplify Macintosh friendly ports of simple, I/O bound programs it is
// possible to specify automatic yielding on read() and write() calls.
// [[AutoSpin]] will spin a cursor and/or yield the CPU if desired.
//
// <Automatic cursor spin>=
bool fAutoSpin;
void ConfigureAutoSpin(bool autoSpin);
void AutoSpin() const;
// GUSI applications can crash hard if QuickDraw is not initialized. Therefore, we
// offer to initialize it automatically with the [[fAutoInitGraf]] feature.
//
// <Automatic initialization of QuickDraw>=
bool fAutoInitGraf;
void ConfigureAutoInitGraf(bool autoInitGraf);
void AutoInitGraf();
// Due to the organization of a UNIX filesystem, it is fairly easy to find
// out how many subdirectories a given directory has, since the [[nlink]] field of
// its inode will automatically contain the number of subdirectories[[+2]]. Therefore,
// some UNIX derived code depends on this behaviour. When [[fAccurateStat]] is set,
// GUSI emulates this behaviour, but be warned that this makes [[stat]] on
// directories a much more expensive operation. If [[fAccurateStat]] is not set,
// stat() gives the total number of entries in the directory[[+2]] as a conservative
// estimate.
//
// <Various flags>=
bool fAccurateStat;
void ConfigureAccurateStat(bool accurateState);
// The [[fSigPipe]] feature causes a signal [[SIGPIPE]] to be raised if an attempt
// is made to write to a broken pipe.
//
// <Various flags>=
bool fSigPipe;
void ConfigureSigPipe(bool sigPipe);
void BrokenPipe();
// The [[fSigInt]] feature causes a signal [[SIGINT]] to be raised if the user presses
// command-period.
//
// <Various flags>=
bool fSigInt;
void ConfigureSigInt(bool sigInt);
void CheckInterrupt();
// If [[fSharedOpen]] is set, open() opens files with shared read/write permission.
//
// <Various flags>=
bool fSharedOpen;
void ConfigureSharedOpen(bool sharedOpen);
// If [[fHandleAppleEvents]] is set, GUSI automatically handles AppleEvents in its
// event handling routine.
//
// <Various flags>=
bool fHandleAppleEvents;
void ConfigureHandleAppleEvents(bool handleAppleEvents);
protected:
GUSIConfiguration(short resourceID = kDefaultResourceID);
private:
// \section{Implementation of configuration settings}
//
// The sole instance of [[GUSIConfiguration]] is created on demand.
//
// <Privatissima of [[GUSIConfiguration]]>=
static GUSIConfiguration * sInstance;
// [[ConfigureSuffices]] sets up the suffix table.
//
// <Privatissima of [[GUSIConfiguration]]>=
bool fWeOwnSuffices;
// [[AutoSpin]] tests the flag inline, but performs the actual spinning out of
// line.
//
// <Privatissima of [[GUSIConfiguration]]>=
void DoAutoSpin() const;
// [[AutoInitGraf]] works rather similarly to [[AutoSpin]].
//
// <Privatissima of [[GUSIConfiguration]]>=
void DoAutoInitGraf();
// [[CheckInterrupt]] raises a [[SIGINT]] signal if desired.
//
// <Privatissima of [[GUSIConfiguration]]>=
bool CmdPeriod(const EventRecord * event);
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// To create the sole instance of [[GUSIConfiguration]], we call [[GUSISetupConfig]]
// which has to call [[GUSIConfiguration::CreateInstance]].
//
// <Definition of [[GUSISetupConfig]] hook>=
#ifdef __MRC__
#pragma noinline_func GUSISetupConfig
#endif
extern "C" void GUSISetupConfig();
// <Inline member functions for class [[GUSIConfiguration]]>=
inline GUSIConfiguration * GUSIConfiguration::Instance()
{
if (!sInstance)
GUSISetupConfig();
if (!sInstance)
sInstance = new GUSIConfiguration();
return sInstance;
}
inline GUSIConfiguration * GUSIConfiguration::CreateInstance(short resourceID)
{
if (!sInstance)
sInstance = new GUSIConfiguration(resourceID);
return sInstance;
}
// <Inline member functions for class [[GUSIConfiguration]]>=
inline void GUSIConfiguration::ConfigureDefaultTypeCreator(OSType defaultType, OSType defaultCreator)
{
fDefaultType = defaultType;
fDefaultCreator = defaultCreator;
}
// <Inline member functions for class [[GUSIConfiguration]]>=
inline void GUSIConfiguration::ConfigureAutoSpin(bool autoSpin)
{
fAutoSpin = autoSpin;
}
// <Inline member functions for class [[GUSIConfiguration]]>=
inline void GUSIConfiguration::AutoSpin() const
{
if (fAutoSpin)
DoAutoSpin();
}
// <Inline member functions for class [[GUSIConfiguration]]>=
inline void GUSIConfiguration::ConfigureAutoInitGraf(bool autoInitGraf)
{
fAutoInitGraf = autoInitGraf;
}
// <Inline member functions for class [[GUSIConfiguration]]>=
inline void GUSIConfiguration::AutoInitGraf()
{
if (fAutoInitGraf)
DoAutoInitGraf();
}
// <Inline member functions for class [[GUSIConfiguration]]>=
inline void GUSIConfiguration::ConfigureSigPipe(bool sigPipe)
{
fSigPipe = sigPipe;
}
// <Inline member functions for class [[GUSIConfiguration]]>=
inline void GUSIConfiguration::ConfigureSigInt(bool sigInt)
{
fSigInt = sigInt;
}
// <Inline member functions for class [[GUSIConfiguration]]>=
inline void GUSIConfiguration::ConfigureAccurateStat(bool accurateStat)
{
fAccurateStat = accurateStat;
}
inline void GUSIConfiguration::ConfigureSharedOpen(bool sharedOpen)
{
fSharedOpen = sharedOpen;
}
#endif /* GUSI_SOURCE */
#endif /* _GUSIConfig_ */

497
GUSI/include/GUSIContext.h Executable file
View File

@ -0,0 +1,497 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIContext.nw - Thread and Process structures
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
// % Initial import
// %
// % Revision 1.22 2001/01/22 04:31:11 neeri
// % Last minute changes for 2.1.5
// %
// % Revision 1.21 2001/01/17 08:43:42 neeri
// % Tweak scheduling
// %
// % Revision 1.20 2000/12/23 06:09:21 neeri
// % May need to create context for IO completions
// %
// % Revision 1.19 2000/10/16 04:34:22 neeri
// % Releasing 2.1.2
// %
// % Revision 1.18 2000/06/01 06:31:09 neeri
// % Delete SigContext
// %
// % Revision 1.17 2000/05/23 06:56:19 neeri
// % Improve formatting, add socket closing queue, tune scheduling
// %
// % Revision 1.16 2000/03/15 07:11:50 neeri
// % Fix detached delete (again), switcher restore
// %
// % Revision 1.15 2000/03/06 08:10:09 neeri
// % Fix sleep in main thread
// %
// % Revision 1.14 2000/03/06 06:13:46 neeri
// % Speed up thread/process switching through minimal quotas
// %
// % Revision 1.13 1999/12/13 02:40:50 neeri
// % GUSISetThreadSwitcher had Boolean <-> bool inconsistency
// %
// % Revision 1.12 1999/11/15 07:25:32 neeri
// % Safe context setup. Check interrupts only in foreground.
// %
// % Revision 1.11 1999/09/09 07:18:06 neeri
// % Added support for foreign threads
// %
// % Revision 1.10 1999/08/26 05:44:59 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.9 1999/06/28 05:59:02 neeri
// % Add signal handling support
// %
// % Revision 1.8 1999/05/30 03:09:29 neeri
// % Added support for MPW compilers
// %
// % Revision 1.7 1999/03/17 09:05:05 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.6 1999/02/25 03:34:24 neeri
// % Introduced GUSIContextFactory, simplified wakeup
// %
// % Revision 1.5 1998/11/22 23:06:51 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.4 1998/10/11 16:45:11 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.3 1998/08/01 21:26:18 neeri
// % Switch dynamically to threading model
// %
// % Revision 1.2 1998/02/11 12:57:11 neeri
// % PowerPC Build
// %
// % Revision 1.1 1998/01/25 21:02:41 neeri
// % Engine implemented, except for signals & scheduling
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Thread and Process structures}
//
// This section defines the process and thread switching engine of GUSI.
//
// In some execution environments, completion routines execute at interrupt level.
// GUSI therefore is designed so all information needed to operate from interrupt
// level is accessible from a [[GUSISocket]]. This information is separated into
// per-process data, collected in [[GUSIProcess]], and per-thread data, collected
// in [[GUSIContext]]. [[GUSIProcess]] is always a singleton, while [[GUSIContext]]
// is a singleton if threading is disabled, and has multiple instances if threading
// is enabled. By delegating the [[GUSIContext]] creation process to an instance
// of a [[GUSIContextFactory]], we gain some extra flexibility.
//
// As soon as GUSI has started an asynchronous call, it calls the [[Wait]] member
// function of its context. [[msec]] will set a time limit after which the call will
// return in any case. Exceptional events may also cause [[GUSIWait]] to return, so
// it is not safe to assume that the call will have completed upon return.
//
//
// <GUSIContext.h>=
#ifndef _GUSIContext_
#define _GUSIContext_
#include <errno.h>
#include <sys/cdefs.h>
#include <sys/signal.h>
#include <MacTypes.h>
#include <Threads.h>
__BEGIN_DECLS
// To maintain correct state, we have to remain informed which thread is active, so
// we install all sorts of hooks. Clients have to use the C++ interface or call
// [[GUSINewThread]], [[GUSISetThreadSwitcher]], and [[GUSISetThreadTerminator]].
// instead of the thread manager routines.
//
// <Definition of thread manager hooks>=
OSErr GUSINewThread(
ThreadStyle threadStyle, ThreadEntryProcPtr threadEntry, void *threadParam,
Size stackSize, ThreadOptions options,
void **threadResult, ThreadID *threadMade);
OSErr GUSISetThreadSwitcher(ThreadID thread,
ThreadSwitchProcPtr threadSwitcher, void *switchProcParam, Boolean inOrOut);
OSErr GUSISetThreadTerminator(ThreadID thread,
ThreadTerminationProcPtr threadTerminator, void *terminationProcParam);
__END_DECLS
#ifndef GUSI_SOURCE
typedef struct GUSIContext GUSIContext;
#else
#include "GUSISpecific.h"
#include "GUSIBasics.h"
#include "GUSIContextQueue.h"
#include <Files.h>
#include <Processes.h>
#include <OSUtils.h>
// \section{Definition of completion handling}
//
// {\tt GUSIContext} is heavily circular both with classes declared herein and
// in other files. Therefore, we start by declaring a few class names.
//
// <Name dropping for file GUSIContext>=
class GUSISocket;
class GUSIContext;
class GUSIProcess;
class GUSISigProcess;
class GUSISigContext;
class GUSITimer;
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// Ultimately, we will call through to the thread manager, but if an application uses foreign
// sources of threads, we might have to go through indirections.
//
// <Definition of class [[GUSIThreadManagerProxy]]>=
class GUSIThreadManagerProxy {
public:
virtual OSErr NewThread(
ThreadStyle threadStyle, ThreadEntryProcPtr threadEntry, void *threadParam,
Size stackSize, ThreadOptions options, void **threadResult, ThreadID *threadMade);
virtual OSErr SetThreadSwitcher(
ThreadID thread, ThreadSwitchProcPtr threadSwitcher, void *switchProcParam,
Boolean inOrOut);
virtual OSErr SetThreadTerminator(
ThreadID thread, ThreadTerminationProcPtr threadTerminator, void *terminatorParam);
virtual ~GUSIThreadManagerProxy() {}
static GUSIThreadManagerProxy * Instance();
protected:
GUSIThreadManagerProxy() {}
static GUSIThreadManagerProxy * MakeInstance();
};
// A [[GUSIProcess]] contains all the data needed to wake up a process:
//
// \begin{itemize}
// \item The [[ProcessSerialNumber]] of the process.
// \item The [[ThreadTaskRef]] if threads are enabled.
// \item The contents of the A5 register.
// \end{itemize}
//
// The sole instance of [[GUSIProcess]] is obtained by calling the [[GUSIProcess::Instance]] static member
// function, which will create the instance if necessary. Interrupt level prcedures may access the application's
// A5 register either manually by calling [[GetA5]] or simply by declaring a [[GUSIProcess::A5Saver]] in a scope.
//
// <Definition of class [[GUSIProcess]]>=
enum GUSIYieldMode {
kGUSIPoll, // Busy wait for some unblockable condition
kGUSIBlock, // Wait for some blockable condition
kGUSIYield // Yield to some other eligible thread
};
class GUSIProcess {
public:
static GUSIProcess * Instance();
static void DeleteInstance();
void GetPSN(ProcessSerialNumber * psn);
void AcquireTaskRef();
ThreadTaskRef GetTaskRef();
long GetA5();
bool Threading();
void Yield(GUSIYieldMode wait);
void Wakeup();
GUSISigProcess * SigProcess() { return fSigProcess; }
void QueueForClose(GUSISocket * sock);
// A [[GUSIProcess::A5Saver]] is a class designed to restore the process A5
// register for the scope of its declaration.
//
// <Definition of class [[GUSIProcess::A5Saver]]>=
class A5Saver {
public:
A5Saver(long processA5);
A5Saver(GUSIContext * context);
A5Saver(GUSIProcess * process);
~A5Saver();
private:
long fSavedA5;
};
protected:
friend class GUSIContext;
GUSIProcess(bool threading);
~GUSIProcess();
int fReadyThreads;
int fExistingThreads;
GUSISigProcess * fSigProcess;
private:
// \section{Implementation of completion handling}
//
// [[Instance]] returns the sole instance of [[GUSIProcess]], creating it if
// necessary.
//
// <Privatissima of [[GUSIProcess]]>=
static GUSIProcess * sInstance;
// Much of the information stored in a [[GUSIProcess]] is static and read-only.
//
// <Privatissima of [[GUSIProcess]]>=
ProcessSerialNumber fProcess;
ThreadTaskRef fTaskRef;
long fA5;
// The exception is the [[fClosing]] socket queue and some yielding related flags.
//
// <Privatissima of [[GUSIProcess]]>=
GUSISocket * fClosing;
UInt32 fResumeTicks;
bool fWillSleep;
bool fDontSleep;
};
// A [[GUSIContext]] gathers thread related data. The central operation on a
// [[GUSIContext]] is [[Wakeup]]. If the process is not asleep when [[Wakeup]]
// is called, it is marked for deferred wakeup.
//
// A [[GUSIContext]] can either be created from an existing thread manager
// [[ThreadID]] or by specifying the parameters for a [[NewThread]] call.
//
// [[Current]] returns the current [[GUSIContext]]. [[Setup]] initializes the
// default context for either the threading or the non-threading model.
//
// [[Yield]] suspends the current process or thread until something interesting
// happens if [[wait]] is [[kGUSIBlock]. Otherwise, [[Yield]] switches,
// but does not suspend. For an ordinary thread context, [[Yield]] simply yields
// the thread. For the context in a non-threading application, [[Yield]] does a
// [[WaitNextEvent]]. For the main thread context, [[Yield]] does both.
//
// [[Done]] tests whether the thread has terminated yet. If [[join]] is set,
// the caller is willing to wait. [[Result]] returns the default location to store
// the thread result if no other is specified.
//
// By default, a context is joinable. Calling [[Detach]] will cause the context to
// be destroyed automatically upon thread termination, and joins are no longer allowed.
// A joinable context will not be destroyed automatically before the end of the
// program, so you will have to call [[Liquidate]] to do that.
//
// [[SetSwitchIn]], [[SetSwitchOut]], and [[SetTerminator]] set per-thread user
// switch and termination procedures. [[SwitchIn]], [[SwitchOut]], and [[Terminate]]
// call the user defined procedures then perform their own actions.
//
// <Definition of class [[GUSIContext]]>=
class GUSIContext : public GUSISpecificTable {
public:
friend class GUSIProcess;
friend class GUSIContextFactory;
ThreadID ID() { return fThreadID; }
virtual void Wakeup();
void ClearWakeups() { fWakeup = false; }
GUSIProcess * Process() { return fProcess; }
void Detach() { fFlags |= detached; }
void Liquidate();
OSErr Error() { return sError; }
bool Done(bool join);
void * Result() { return fResult; }
GUSISigContext * SigContext() { return fSigContext; }
static GUSIContext * Current() { return sCurrentContext; }
static GUSIContext * CreateCurrent(bool threading = false)
{ if (!sCurrentContext) Setup(threading); return sCurrentContext; }
static GUSIContext * Lookup(ThreadID id);
static void Setup(bool threading);
static bool Yield(GUSIYieldMode wait);
static void SigWait(sigset_t sigs);
static void SigSuspend();
static bool Raise(bool allSigs = false);
static sigset_t Pending();
static sigset_t Blocked();
void SetSwitchIn(ThreadSwitchProcPtr switcher, void *switchParam);
void SetSwitchOut(ThreadSwitchProcPtr switcher, void *switchParam);
void SetTerminator(ThreadTerminationProcPtr terminator, void *terminationParam);
static GUSIContextQueue::iterator begin() { return sContexts.begin(); }
static GUSIContextQueue::iterator end() { return sContexts.end(); }
static void LiquidateAll() { sContexts.LiquidateAll(); }
protected:
// <Friends of [[GUSIContext]]>=
friend class GUSIContextFactory;
// The thread switcher updates the pointer to the current context and switches
// the global error variables.
//
// <Friends of [[GUSIContext]]>=
friend pascal void GUSIThreadSwitchIn(ThreadID thread, GUSIContext * context);
friend pascal void GUSIThreadSwitchOut(ThreadID thread, GUSIContext * context);
// The terminator wakes up the joining thread if a join is pending.
//
// <Friends of [[GUSIContext]]>=
friend pascal void GUSIThreadTerminator(ThreadID thread, GUSIContext * context);
GUSIContext(ThreadID id);
GUSIContext(
ThreadEntryProcPtr threadEntry, void *threadParam,
Size stackSize, ThreadOptions options = kCreateIfNeeded,
void **threadResult = nil, ThreadID *threadMade = nil);
virtual void SwitchIn();
virtual void SwitchOut();
virtual void Terminate();
// At this point, we need to introduce all the private data of a [[GUSIContext]].
//
// \begin{itemize}
// \item [[fThreadID]] stores the thread manager thread ID.
// \item [[fProcess]] keeps a pointer to the process structure, so completion
// routines can get at it.
// \item [[sCurrentContext]] always points at the current context.
// \item [[sContexts]] contains a queue of all contexts.
// \item [[sHasThreads]] reminds us whether we are threading or not.
// \item We define our own switch-in and termination procedures. If the user specifies procedures
// we store them in [[fSwitchInProc]], [[fSwitchOutProc]], and [[fTerminateProc]] and their parameters
// in [[fSwitchInParam]], [[fSwitchOutParam]], and [[fTerminateParam]] so we can call through to them
// from our procedures.
// \item [[fJoin]] contains the context waiting for us to die;
// \item [[done]] reminds us if the thread is still alive. [[detached]] guarantees
// that we will never wait for that thread anymore.
// \item Last of all, we keep the global error variables [[errno]] and [[h_errno]]
// for each context in the [[fErrno]] and [[fHostErrno]] fields.
// \end{itemize}
//
//
// <Privatissima of [[GUSIContext]]>=
ThreadID fThreadID;
GUSIProcess * fProcess;
GUSIContext * fNext;
GUSISigContext * fSigContext;
ThreadSwitchProcPtr fSwitchInProc;
ThreadSwitchProcPtr fSwitchOutProc;
ThreadTerminationProcPtr fTerminateProc;
void * fSwitchInParam;
void * fSwitchOutParam;
void * fTerminateParam;
void * fResult;
GUSIContext * fJoin;
enum {
done = 1 << 0,
detached= 1 << 1,
asleep = 1 << 2
};
char fFlags;
bool fWakeup;
UInt32 fEntryTicks;
int fErrno;
int fHostErrno;
class Queue : public GUSIContextQueue {
public:
void LiquidateAll();
~Queue() { LiquidateAll(); }
};
static Queue sContexts;
static GUSIContext * sCurrentContext;
static bool sHasThreading;
static OSErr sError;
// The [[GUSIContext]] constructor links the context into the queue of existing
// contexts and installs the appropriate thread hooks. We split this into two
// routines: [[StartSetup]] does static setup before the thread id is determined,
// [[FinishSetup]] does the queueing.
//
// <Privatissima of [[GUSIContext]]>=
void StartSetup();
void FinishSetup();
// Destruction of a [[GUSIContext]] requires some cleanup.
//
// <Privatissima of [[GUSIContext]]>=
~GUSIContext();
};
// [[GUSIContext]] instances are created by instances of [[GUSIContextFactory]].
//
// <Definition of class [[GUSIContextFactory]]>=
class GUSIContextFactory {
public:
static GUSIContextFactory * Instance();
static void SetInstance(GUSIContextFactory * instance);
virtual GUSIContext * CreateContext(ThreadID id);
virtual GUSIContext * CreateContext(
ThreadEntryProcPtr threadEntry, void *threadParam,
Size stackSize, ThreadOptions options = kCreateIfNeeded,
void **threadResult = nil, ThreadID *threadMade = nil);
virtual ~GUSIContextFactory();
protected:
GUSIContextFactory();
};
// Many asynchronous calls take the same style of I/O parameter block and thus
// can be handled by the same completion procedure. [[StartIO]] prepares
// a parameter block for asynchronous I/O; [[FinishIO]] waits for the I/O
// to complete. The parameter block has to be wrapped in a [[GUSIIOPBWrapper]].
//
// <Definition of IO wrappers>=
void GUSIStartIO(IOParam * pb);
OSErr GUSIFinishIO(IOParam * pb);
OSErr GUSIControl(IOParam * pb);
template <class PB> struct GUSIIOPBWrapper {
GUSIContext * fContext;
PB fPB;
GUSIIOPBWrapper() {}
GUSIIOPBWrapper(const PB & pb) { memcpy(&fPB, &pb, sizeof(PB)); }
PB * operator->(){ return &fPB; }
void StartIO() { GUSIStartIO(reinterpret_cast<IOParam *>(&fPB)); }
OSErr FinishIO() { return GUSIFinishIO(reinterpret_cast<IOParam *>(&fPB)); }
OSErr Control() { return GUSIControl(reinterpret_cast<IOParam *>(&fPB)); }
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// <Inline member functions for file GUSIContext>=
inline GUSIProcess * GUSIProcess::Instance()
{
if (!sInstance)
sInstance = new GUSIProcess(GUSIContext::sHasThreading);
return sInstance;
}
inline void GUSIProcess::DeleteInstance()
{
delete sInstance;
sInstance = 0;
}
// <Inline member functions for file GUSIContext>=
inline void GUSIProcess::GetPSN(ProcessSerialNumber * psn)
{ *psn = fProcess; }
inline void GUSIProcess::AcquireTaskRef()
{ GetThreadCurrentTaskRef(&fTaskRef); }
inline ThreadTaskRef GUSIProcess::GetTaskRef()
{ return fTaskRef; }
inline long GUSIProcess::GetA5()
{ return fA5; }
inline bool GUSIProcess::Threading()
{ return fTaskRef!=0;}
// An [[A5Saver]] is trivially implemented but it simplifies bookkeeping.
//
// <Inline member functions for file GUSIContext>=
inline GUSIProcess::A5Saver::A5Saver(long processA5)
{ fSavedA5 = SetA5(processA5); }
inline GUSIProcess::A5Saver::A5Saver(GUSIProcess * process)
{ fSavedA5 = SetA5(process->GetA5()); }
inline GUSIProcess::A5Saver::A5Saver(GUSIContext * context)
{ fSavedA5 = SetA5(context->Process()->GetA5()); }
inline GUSIProcess::A5Saver::~A5Saver()
{ SetA5(fSavedA5); }
#endif /* GUSI_SOURCE */
#endif /* _GUSIContext_ */

237
GUSI/include/GUSIContextQueue.h Executable file
View File

@ -0,0 +1,237 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIContext.nw - Thread and Process structures
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
// % Initial import
// %
// % Revision 1.9 2001/01/17 08:45:13 neeri
// % Improve memory allocation safety somewhat
// %
// % Revision 1.8 2000/05/23 06:58:03 neeri
// % Improve formatting
// %
// % Revision 1.7 2000/03/15 07:22:06 neeri
// % Enforce alignment choices
// %
// % Revision 1.6 1999/08/26 05:45:00 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.5 1999/05/30 03:09:29 neeri
// % Added support for MPW compilers
// %
// % Revision 1.4 1999/03/17 09:05:06 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.3 1998/08/02 11:20:07 neeri
// % Fixed some typos
// %
// % Revision 1.2 1998/08/01 21:32:02 neeri
// % About ready for 2.0a1
// %
// % Revision 1.1 1998/01/25 21:02:43 neeri
// % Engine implemented, except for signals & scheduling
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Context Queues}
//
// At all times through its existence, a [[GUSIContext]] will exist in various
// queues: A queue of all contexts, queues of contexts waiting on a socket
// event, a mutex, or a condition variable, and so on. Since a context is often
// in several queues simultaneously, it's better to define queues non-intrusively.
//
// <GUSIContextQueue.h>=
#ifndef _GUSIContextQueue_
#define _GUSIContextQueue_
#ifndef GUSI_SOURCE
typedef struct GUSIContextQueue GUSIContextQueue;
#else
#include <stdlib.h>
// \section{Definition of context queues}
//
// We'd like to avoid having to include \texttt{GUSIContext} here, for reasons that
// should be rather obvious.
//
// <Name dropping for file GUSIContextQueue>=
class GUSIContext;
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// The class [[GUSIContextQueue]] tries to present an interface that is a subset of
// what C++ standard library list template classes offer.
//
// <Definition of class [[GUSIContextQueue]]>=
class GUSIContextQueue {
public:
GUSIContextQueue();
~GUSIContextQueue();
bool empty();
GUSIContext * front() const;
GUSIContext * back() const;
void push_front(GUSIContext * context);
void push_back(GUSIContext * context);
void push(GUSIContext * context) { push_back(context); }
void pop_front();
void pop() { pop_front(); }
void remove(GUSIContext * context);
void Wakeup();
// We define a forward iterator, but no reverse iterator.
//
// <Define [[iterator]] for [[GUSIContextQueue]]>=
struct element;
class iterator {
friend class GUSIContextQueue;
public:
iterator & operator++();
iterator operator++(int);
bool operator==(const iterator other) const;
GUSIContext * operator*();
GUSIContext * operator->();
private:
// A [[GUSIContextQueue::iterator]] is just a wrapper for a
// [[GUSIContextQueue::element]].
//
// <Privatissima of [[GUSIContextQueue::iterator]]>=
element * fCurrent;
iterator(element * elt) : fCurrent(elt) {}
iterator() : fCurrent(0) {}
};
iterator begin();
iterator end();
private:
// \section{Implementation of context queues}
//
// Efficiency of context queues is quite important, so we provide a custom
// allocator for queue elements.
//
// <Privatissima of [[GUSIContextQueue]]>=
struct element {
GUSIContext * fContext;
element * fNext;
element(GUSIContext * context, element * next = 0)
: fContext(context), fNext(next) {}
void * operator new(size_t);
void operator delete(void *, size_t);
private:
// Elements are allocated in blocks of increasing size.
//
// <Privatissima of [[GUSIContextQueue::element]]>=
struct header {
short fFree;
short fMax;
header *fNext;
};
static header * sBlocks;
};
// A [[GUSIContextQueue]] is a single linked list with a separate back pointer.
//
// <Privatissima of [[GUSIContextQueue]]>=
element * fFirst;
element * fLast;
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// <Inline member functions for class [[GUSIContextQueue]]>=
inline GUSIContextQueue::GUSIContextQueue()
: fFirst(0), fLast(0)
{
}
// None of the member functions are very large, so we'll inline them.
//
// <Inline member functions for class [[GUSIContextQueue]]>=
inline bool GUSIContextQueue::empty()
{
return !fFirst;
}
inline GUSIContext * GUSIContextQueue::front() const
{
return fFirst ? fFirst->fContext : reinterpret_cast<GUSIContext *>(0);
}
inline GUSIContext * GUSIContextQueue::back() const
{
return fLast ? fLast->fContext : reinterpret_cast<GUSIContext *>(0);
}
inline void GUSIContextQueue::push_front(GUSIContext * context)
{
fFirst = new element(context, fFirst);
if (!fLast)
fLast = fFirst;
}
inline void GUSIContextQueue::pop_front()
{
if (element * e = fFirst) {
if (!(fFirst = fFirst->fNext))
fLast = 0;
delete e;
}
}
// The constructors are not public, so only [[begin]] and [[end]] call them.
//
// <Inline member functions for class [[GUSIContextQueue]]>=
inline GUSIContextQueue::iterator GUSIContextQueue::begin()
{
return iterator(fFirst);
}
inline GUSIContextQueue::iterator GUSIContextQueue::end()
{
return iterator();
}
// <Inline member functions for class [[GUSIContextQueue]]>=
inline GUSIContextQueue::iterator & GUSIContextQueue::iterator::operator++()
{
fCurrent = fCurrent->fNext;
return *this;
}
inline GUSIContextQueue::iterator GUSIContextQueue::iterator::operator++(int)
{
GUSIContextQueue::iterator it(*this);
fCurrent = fCurrent->fNext;
return it;
}
inline bool GUSIContextQueue::iterator::operator==(const iterator other) const
{
return fCurrent == other.fCurrent;
}
inline GUSIContext * GUSIContextQueue::iterator::operator*()
{
return fCurrent->fContext;
}
inline GUSIContext * GUSIContextQueue::iterator::operator->()
{
return fCurrent->fContext;
}
#endif /* GUSI_SOURCE */
#endif /* _GUSIContextQueue_ */

69
GUSI/include/GUSIDCon.h Executable file
View File

@ -0,0 +1,69 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIDCon.nw - DCon interface
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
// % Initial import
// %
// % Revision 1.4 2000/03/06 06:03:30 neeri
// % Check device families for file paths
// %
// % Revision 1.3 1999/08/26 05:45:00 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.2 1999/05/29 06:26:41 neeri
// % Fixed header guards
// %
// % Revision 1.1 1999/03/17 09:05:06 neeri
// % Added GUSITimer, expanded docs
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{DCon interface}
//
// A [[GUSIDConSocket]] implements an interface to DCon, Cache Computing's
// debugging console. For more information about DCon, see
// \href{http://www.cache-computing.com/products/dcon/}{Cache Computing's site}
// at \verb|http://www.cache-computing.com/products/dcon/|.
//
// All instances of [[GUSIDConSocket]] are created by the [[GUSIDConDevice]]
// singleton, so
// there is no point in exporting the class itself.
//
// <GUSIDCon.h>=
#ifndef _GUSIDCon_
#define _GUSIDCon_
#ifdef GUSI_INTERNAL
#include "GUSIDevice.h"
// \section{Definition of [[GUSIDConDevice]]}
//
// [[GUSIDConDevice]] is a singleton subclass of [[GUSIDevice]].
//
// <Definition of class [[GUSIDConDevice]]>=
class GUSIDConDevice : public GUSIDevice {
public:
static GUSIDConDevice * Instance();
virtual bool Want(GUSIFileToken & file);
virtual GUSISocket * open(GUSIFileToken & file, int flags);
protected:
GUSIDConDevice() {}
static GUSIDConDevice * sInstance;
};
// <Inline member functions for class [[GUSIDConDevice]]>=
inline GUSIDConDevice * GUSIDConDevice::Instance()
{
if (!sInstance)
sInstance = new GUSIDConDevice;
return sInstance;
}
#endif /* GUSI_INTERNAL */
#endif /* _GUSIDCon_ */

209
GUSI/include/GUSIDescriptor.h Executable file
View File

@ -0,0 +1,209 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIDescriptor.nw - Descriptor Table
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
// % Initial import
// %
// % Revision 1.15 2001/01/22 04:31:11 neeri
// % Last minute changes for 2.1.5
// %
// % Revision 1.14 2001/01/17 08:40:17 neeri
// % Prevent inlining of overridable functions
// %
// % Revision 1.13 2000/06/12 04:23:43 neeri
// % Return values, not references; Introduce support for multiple descriptor tables
// %
// % Revision 1.12 2000/05/23 06:58:03 neeri
// % Improve formatting
// %
// % Revision 1.11 2000/03/15 07:14:26 neeri
// % Prevent double destruction of descriptor table
// %
// % Revision 1.10 2000/03/06 06:26:57 neeri
// % Introduce (and call) CloseAllDescriptors()
// %
// % Revision 1.9 1999/08/26 05:45:01 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.8 1999/08/02 07:02:43 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.7 1999/06/30 07:42:05 neeri
// % Getting ready to release 2.0b3
// %
// % Revision 1.6 1999/05/29 06:26:42 neeri
// % Fixed header guards
// %
// % Revision 1.5 1999/04/29 05:00:48 neeri
// % Fix bug with bizarre uses of dup2
// %
// % Revision 1.4 1999/03/17 09:05:06 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.3 1998/10/11 16:45:12 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.2 1998/08/01 21:32:03 neeri
// % About ready for 2.0a1
// %
// % Revision 1.1 1998/01/25 21:02:44 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.1 1996/12/16 02:12:40 neeri
// % TCP Sockets sort of work
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Mapping descriptors to sockets}
//
// POSIX routines do not, of course, operate on [[GUSISockets]] but on
// numerical descriptors. The [[GUSIDescriptorTable]] singleton maps between
// descriptors and their [[GUSISockets]].
//
// <GUSIDescriptor.h>=
#ifndef _GUSIDescriptor_
#define _GUSIDescriptor_
#ifdef GUSI_SOURCE
#include "GUSISocket.h"
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of [[GUSIDescriptorTable]]}
//
// A [[GUSIDescriptorTable]] is another singleton class, behaving in many aspects
// like an array of [[GUSISocket]] pointers. [[InstallSocket]] installs a new socket
// into the table, picking the first available slot with a descriptor greater than
// or equal to [[start]]. [[RemoveSocket]] empties one slot.
// [[GUSIDescriptorTable::LookupSocket]] is a shorthand for
// [[ (*GUSIDescriptorTable::Instance())[fd] ]].
//
// To allow for light-weight processes, we provide a copy constructor and
// the [[SetInstance]] member.
//
// <Definition of class [[GUSIDescriptorTable]]>=
class GUSIDescriptorTable {
public:
enum { SIZE = 64 };
static GUSIDescriptorTable * Instance();
int InstallSocket(GUSISocket * sock, int start = 0);
int RemoveSocket(int fd);
GUSISocket * operator[](int fd);
static GUSISocket * LookupSocket(int fd);
class iterator;
friend class iterator;
iterator begin();
iterator end();
~GUSIDescriptorTable();
static void CloseAllDescriptors();
static void SetInstance(GUSIDescriptorTable * table);
GUSIDescriptorTable(const GUSIDescriptorTable & parent);
private:
// \section{Implementation of [[GUSIDescriptorTable]]}
//
// On creation, a [[GUSIDescriptorTable]] clears all descriptors.
//
// <Privatissima of [[GUSIDescriptorTable]]>=
GUSISocket * fSocket[SIZE];
int fInvalidDescriptor;
GUSIDescriptorTable();
// <Privatissima of [[GUSIDescriptorTable]]>=
static GUSIDescriptorTable * sGUSIDescriptorTable;
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// If no instance exists yet, [[GUSIDescriptorTable::Instance]] creates one and
// calls [[GUSISetupConsole]] if the [[setupConsole]] parameter is true.
// [[GUSISetupConsole]] calls [[GUSIDefaultSetupConsole]], which first calls
// [[GUSISetupConsoleDescriptors]] to set up file descriptors 0, 1, and 2, and
// then calls [[GUSISetupConsoleStdio]] to deal with the necessary initializations
// on the stdio level.
//
// <Hooks for ANSI library interfaces>=
extern "C" {
void GUSISetupConsole();
void GUSIDefaultSetupConsole();
void GUSISetupConsoleDescriptors();
void GUSISetupConsoleStdio();
}
// Destructing a [[GUSIDescriptorTable]] may be a bit problematic, as this
// may have effects reaching up into the stdio layer. We therefore factor
// out the stdio aspects into the procedures [[StdioClose]] and [[StdioFlush]]
// which we then can redefine in other, stdio library specific, libraries.
//
// <Hooks for ANSI library interfaces>=
extern "C" {
void GUSIStdioClose();
void GUSIStdioFlush();
}
// <Inline member functions for class [[GUSIDescriptorTable]]>=
class GUSIDescriptorTable::iterator {
public:
iterator(GUSIDescriptorTable * table, int fd = 0) : fTable(table), fFd(fd) {}
GUSIDescriptorTable::iterator & operator++();
GUSIDescriptorTable::iterator operator++(int);
int operator*() { return fFd; }
bool operator==(const GUSIDescriptorTable::iterator & other) const;
private:
GUSIDescriptorTable * fTable;
int fFd;
};
inline GUSIDescriptorTable::iterator & GUSIDescriptorTable::iterator::operator++()
{
while (++fFd < fTable->fInvalidDescriptor && !fTable->fSocket[fFd])
;
return *this;
}
inline GUSIDescriptorTable::iterator GUSIDescriptorTable::iterator::operator++(int)
{
int oldFD = fFd;
while (++fFd < fTable->fInvalidDescriptor && !fTable->fSocket[fFd])
;
return GUSIDescriptorTable::iterator(fTable, oldFD);
}
inline bool GUSIDescriptorTable::iterator::operator==(
const GUSIDescriptorTable::iterator & other) const
{
return fFd == other.fFd;
}
inline GUSIDescriptorTable::iterator GUSIDescriptorTable::begin()
{
return iterator(this);
}
inline GUSIDescriptorTable::iterator GUSIDescriptorTable::end()
{
return iterator(this, fInvalidDescriptor);
}
#endif /* GUSI_SOURCE */
#endif /* _GUSIDescriptor_ */

381
GUSI/include/GUSIDevice.h Executable file
View File

@ -0,0 +1,381 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIDevice.nw - Devices
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
// % Initial import
// %
// % Revision 1.13 2000/06/12 04:22:30 neeri
// % Return values, not references
// %
// % Revision 1.12 2000/05/23 06:58:03 neeri
// % Improve formatting
// %
// % Revision 1.11 2000/03/15 07:22:06 neeri
// % Enforce alignment choices
// %
// % Revision 1.10 2000/03/06 06:30:30 neeri
// % Check for nonexistent device
// %
// % Revision 1.9 1999/08/26 05:45:01 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.8 1999/07/19 06:21:02 neeri
// % Add mkdir/rmdir, fix various file manager related bugs
// %
// % Revision 1.7 1999/05/29 06:26:42 neeri
// % Fixed header guards
// %
// % Revision 1.6 1999/03/17 09:05:07 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.5 1998/11/22 23:06:52 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.4 1998/10/25 11:37:38 neeri
// % More configuration hooks
// %
// % Revision 1.3 1998/10/11 16:45:13 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.2 1998/08/01 21:28:57 neeri
// % Add directory operations
// %
// % Revision 1.1 1998/01/25 21:02:45 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.1 1996/12/16 02:12:40 neeri
// % TCP Sockets sort of work
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Devices}
//
// Similar to the creation of sockets, operations on files like opening or
// renaming them need to be dispatched to a variety of special cases (Most of
// them of the form "Dev:" preceded by a device name). Analogous to the
// [[GUSISocketFactory]] subclasses registered in a [[GUSISocketDomainRegistry]],
// we therefore have subclasses of [[GUSIDevice]] registered in a
// [[GUSIDeviceRegistry]], although the details of the two registries are
// quite different.
//
// During resolution of a file name, the name and information about it is passed
// around in a [[GUSIFileToken]].
//
// <GUSIDevice.h>=
#ifndef _GUSIDevice_
#define _GUSIDevice_
#ifdef GUSI_SOURCE
#include "GUSISocket.h"
#include "GUSIFileSpec.h"
#include <dirent.h>
#include <utime.h>
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of [[GUSIFileToken]]}
//
// A [[GUSIFileToken]] consists of a pointer to the name as a C string, of a pointer
// to the [[GUSIDevice]] the token resolves to, and, if the token refers to a
// file name rather than a device name, a pointer to a [[GUSIFileSpec]]. Since
// depending on the call, different [[GUSIDevice]] subclasses may handle it, a
// request code has to be passed to the constructor, too.
//
// <Definition of class [[GUSIFileToken]]>=
class GUSIDevice;
class GUSIFileToken : public GUSIFileSpec {
public:
enum Request {
// \section{Operations on Devices}
//
// The [[open]] operation creates a new socket for the specified path or file
// specification.
//
// <Requests for [[GUSIFileToken]]>=
kWillOpen,
// [[remove]] deletes a path or file specification.
//
// <Requests for [[GUSIFileToken]]>=
kWillRemove,
// [[rename]] renames a path or file specification.
//
// <Requests for [[GUSIFileToken]]>=
kWillRename,
// [[stat]] gathers statistical data about a file or directory.
//
// <Requests for [[GUSIFileToken]]>=
kWillStat,
// [[chmod]] changes file modes, to the extent that this is meaningful on MacOS.
//
// <Requests for [[GUSIFileToken]]>=
kWillChmod,
// [[utime]] bumps a file's modification time.
//
// <Requests for [[GUSIFileToken]]>=
kWillUtime,
// [[access]] checks access permissions for a file.
//
// <Requests for [[GUSIFileToken]]>=
kWillAccess,
// [[mkdir]] creates a directory.
//
// <Requests for [[GUSIFileToken]]>=
kWillMkdir,
// [[rmdir]] deletes a directory.
//
// <Requests for [[GUSIFileToken]]>=
kWillRmdir,
// [[opendir]] opens a directory handle on the given directory.
//
// <Requests for [[GUSIFileToken]]>=
kWillOpendir,
// [[symlink]] creates a symbolic link to a file.
//
// <Requests for [[GUSIFileToken]]>=
kWillSymlink,
// [[readlink]] reads the contents of a symbolic link.
//
// <Requests for [[GUSIFileToken]]>=
kWillReadlink,
// [[fgetfileinfo]] and [[fsetfileinfo]] reads and set the type and creator
// code of a file.
//
// <Requests for [[GUSIFileToken]]>=
kWillGetfileinfo,
kWillSetfileinfo,
// [[faccess]] manipulates MPW properties of files.
//
// <Requests for [[GUSIFileToken]]>=
kWillFaccess,
kNoRequest
};
GUSIFileToken(const char * path, Request request, bool useAlias = false);
GUSIFileToken(const GUSIFileSpec & spec, Request request);
GUSIFileToken(short fRefNum, Request request);
bool IsFile() const { return fIsFile; }
bool IsDevice() const { return !fIsFile; }
Request WhichRequest() const { return fRequest; }
GUSIDevice * Device() const { return fDevice; }
const char * Path() const { return fPath; }
static bool StrFragEqual(const char * name, const char * frag);
enum StdStream {
kStdin,
kStdout,
kStderr,
kConsole,
kNoStdStream = -2
};
static StdStream StrStdStream(const char * name);
private:
GUSIDevice * fDevice;
const char * fPath;
bool fIsFile;
Request fRequest;
};
// \section{Definition of [[GUSIDirectory]]}
//
// [[GUSIDirectory]] is a directory handle to iterate over all entries in a
// directory.
//
// <Definition of class [[GUSIDirectory]]>=
class GUSIDirectory {
public:
virtual ~GUSIDirectory() {}
virtual dirent * readdir() = 0;
virtual long telldir() = 0;
virtual void seekdir(long pos) = 0;
virtual void rewinddir() = 0;
protected:
friend class GUSIDevice;
GUSIDirectory() {}
};
// \section{Definition of [[GUSIDeviceRegistry]]}
//
// The [[GUSIDeviceRegistry]] is a singleton class registering all socket
// domains.
//
// <Definition of class [[GUSIDeviceRegistry]]>=
class GUSIDeviceRegistry {
public:
// The only instance of [[GUSIDeviceRegistry]] is, as usual, obtained by calling
// [[Instance]].
//
// <Creation of [[GUSIDeviceRegistry]]>=
static GUSIDeviceRegistry * Instance();
// <Operations for [[GUSIDeviceRegistry]]>=
GUSISocket * open(const char * path, int flags);
// <Operations for [[GUSIDeviceRegistry]]>=
int remove(const char * path);
// <Operations for [[GUSIDeviceRegistry]]>=
int rename(const char * oldname, const char * newname);
// <Operations for [[GUSIDeviceRegistry]]>=
int stat(const char * path, struct stat * buf, bool useAlias);
// <Operations for [[GUSIDeviceRegistry]]>=
int chmod(const char * path, mode_t mode);
// <Operations for [[GUSIDeviceRegistry]]>=
int utime(const char * path, const utimbuf * times);
// <Operations for [[GUSIDeviceRegistry]]>=
int access(const char * path, int mode);
// <Operations for [[GUSIDeviceRegistry]]>=
int mkdir(const char * path);
// <Operations for [[GUSIDeviceRegistry]]>=
int rmdir(const char * path);
// <Operations for [[GUSIDeviceRegistry]]>=
GUSIDirectory * opendir(const char * path);
// <Operations for [[GUSIDeviceRegistry]]>=
int symlink(const char * target, const char * newlink);
// <Operations for [[GUSIDeviceRegistry]]>=
int readlink(const char * path, char * buf, int bufsize);
// <Operations for [[GUSIDeviceRegistry]]>=
int fgetfileinfo(const char * path, OSType * creator, OSType * type);
int fsetfileinfo(const char * path, OSType creator, OSType type);
// <Operations for [[GUSIDeviceRegistry]]>=
int faccess(const char * path, unsigned * cmd, void * arg);
// [[AddDevice]] and [[RemoveDevice]] add and remove a [[GUSIDevice]].
//
// <Registration interface of [[GUSIDeviceRegistry]]>=
void AddDevice(GUSIDevice * device);
void RemoveDevice(GUSIDevice * device);
// It is convenient to define iterators to iterate across all devices.
//
// <Iterator on [[GUSIDeviceRegistry]]>=
class iterator;
iterator begin();
iterator end();
protected:
// On construction, a [[GUSIFileToken]] looks up the appropriate device in the
// [[GUSIDeviceRegistry]].
//
// <Looking up a device in the [[GUSIDeviceRegistry]]>=
friend class GUSIFileToken;
GUSIDevice * Lookup(GUSIFileToken & file);
private:
// <Privatissima of [[GUSIDeviceRegistry]]>=
static GUSIDeviceRegistry * sInstance;
// Devices are stored in a linked list. On creation of the registry, it immediately
// registers the instance for plain Macintosh file sockets, to which pretty much all
// operations default. This device will never refuse any request.
//
// <Privatissima of [[GUSIDeviceRegistry]]>=
GUSIDevice * fFirstDevice;
GUSIDeviceRegistry();
};
// \section{Definition of [[GUSIDevice]]}
//
// [[GUSIDevice]] consists of a few maintenance functions and the
// device operations. The request dispatcher first calls [[Want]] for
// each candidate device and as soon as it's successful, calls the specific
// operation. Devices are kept in a linked list by the [[GUSIDeviceRegistry]].
//
// <Definition of class [[GUSIDevice]]>=
class GUSIDevice {
public:
virtual bool Want(GUSIFileToken & file);
// <Operations for [[GUSIDevice]]>=
virtual GUSISocket * open(GUSIFileToken & file, int flags);
// <Operations for [[GUSIDevice]]>=
virtual int remove(GUSIFileToken & file);
// <Operations for [[GUSIDevice]]>=
virtual int rename(GUSIFileToken & from, const char * newname);
// <Operations for [[GUSIDevice]]>=
virtual int stat(GUSIFileToken & file, struct stat * buf);
// <Operations for [[GUSIDevice]]>=
virtual int chmod(GUSIFileToken & file, mode_t mode);
// <Operations for [[GUSIDevice]]>=
virtual int utime(GUSIFileToken & file, const utimbuf * times);
// <Operations for [[GUSIDevice]]>=
virtual int access(GUSIFileToken & file, int mode);
// <Operations for [[GUSIDevice]]>=
virtual int mkdir(GUSIFileToken & file);
// <Operations for [[GUSIDevice]]>=
virtual int rmdir(GUSIFileToken & file);
// <Operations for [[GUSIDevice]]>=
virtual GUSIDirectory * opendir(GUSIFileToken & file);
// <Operations for [[GUSIDevice]]>=
virtual int symlink(GUSIFileToken & to, const char * newlink);
// <Operations for [[GUSIDevice]]>=
virtual int readlink(GUSIFileToken & link, char * buf, int bufsize);
// <Operations for [[GUSIDevice]]>=
virtual int fgetfileinfo(GUSIFileToken & file, OSType * creator, OSType * type);
virtual int fsetfileinfo(GUSIFileToken & file, OSType creator, OSType type);
// <Operations for [[GUSIDevice]]>=
virtual int faccess(GUSIFileToken & file, unsigned * cmd, void * arg);
protected:
friend class GUSIDeviceRegistry;
friend class GUSIDeviceRegistry::iterator;
GUSIDevice() : fNextDevice(nil) {}
virtual ~GUSIDevice() {}
GUSIDevice * fNextDevice;
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// \section{Implementation of [[GUSIDeviceRegistry]]}
//
//
// <Definition of [[GUSISetupDevices]] hook>=
extern "C" void GUSISetupDevices();
// <Inline member functions for class [[GUSIDeviceRegistry]]>=
inline GUSIDeviceRegistry * GUSIDeviceRegistry::Instance()
{
if (!sInstance) {
sInstance = new GUSIDeviceRegistry();
GUSISetupDevices();
}
return sInstance;
}
// The [[GUSIDeviceRegistry]] forward iterator is simple.
//
// <Inline member functions for class [[GUSIDeviceRegistry]]>=
class GUSIDeviceRegistry::iterator {
public:
iterator(GUSIDevice * device = 0) : fDevice(device) {}
GUSIDeviceRegistry::iterator & operator++()
{ fDevice = fDevice->fNextDevice; return *this; }
GUSIDeviceRegistry::iterator operator++(int)
{ GUSIDeviceRegistry::iterator old(*this); fDevice = fDevice->fNextDevice; return old; }
bool operator==(const GUSIDeviceRegistry::iterator other) const
{ return fDevice==other.fDevice; }
GUSIDevice & operator*() { return *fDevice; }
GUSIDevice * operator->() { return fDevice; }
private:
GUSIDevice * fDevice;
};
inline GUSIDeviceRegistry::iterator GUSIDeviceRegistry::begin()
{
return GUSIDeviceRegistry::iterator(fFirstDevice);
}
inline GUSIDeviceRegistry::iterator GUSIDeviceRegistry::end()
{
return GUSIDeviceRegistry::iterator();
}
#endif /* GUSI_SOURCE */
#endif /* _GUSIDevice_ */

222
GUSI/include/GUSIDiag.h Executable file
View File

@ -0,0 +1,222 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIDiag.nw - Assertions and diagnostics
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
// % Initial import
// %
// % Revision 1.12 2000/06/12 04:20:58 neeri
// % Introduce GUSI_*printf
// %
// % Revision 1.11 2000/05/23 06:58:04 neeri
// % Improve formatting
// %
// % Revision 1.10 1999/08/26 05:45:01 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.9 1999/08/02 07:02:43 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.8 1999/05/29 06:26:42 neeri
// % Fixed header guards
// %
// % Revision 1.7 1999/04/10 04:45:47 neeri
// % Add DCon stubs
// %
// % Revision 1.6 1999/03/17 09:05:07 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.5 1999/02/25 03:49:00 neeri
// % Switched to DCon for logging
// %
// % Revision 1.4 1998/01/25 20:53:53 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.3 1996/12/16 02:17:20 neeri
// % Tune messages
// %
// % Revision 1.2 1996/11/24 12:52:07 neeri
// % Added GUSIPipeSockets
// %
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
// % Imported into CVS
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Assertions and diagnostic messages}
//
// GUSI reports on three kinds of error conditions:
//
// \begin{itemize}
// \item {\bf Internal} errors are usually caused by bugs in GUSI. They should be
// considered fatal.
// \item {\bf Client} errors are caused by calling GUSI routines with bad
// parameters. They are typically handled by returning an appropriate error
// code.
// \item {\bf External} errors are caused by various OS and Network related
// problems. Typically, they are also handled by returning an appropriate
// error code.
// \end{itemize}
//
// If you feel lucky, you can turn off the checking for internal and client errors,
// but external errors will always be checked.
//
// <GUSIDiag.h>=
#ifndef _GUSIDiag_
#define _GUSIDiag_
#include <sys/cdefs.h>
#include <stdarg.h>
#include <string.h>
#include <MacTypes.h>
__BEGIN_DECLS
// \section{Definition of diagnostics}
//
// Depending on the diagnostic level, messages get printed to the DCon console.
//
// <Definition of diagnostic logfile>=
extern char * GUSI_diag_log;
// Printing is done by passing an argument list to [[GUSI_log]]. To simplify the job
// for the diagnostic macros, [[GUSI_log]] returns a [[bool]] value which is
// always [[false]]. [[GUSI_break]] stops with a [[DebugStr]] call. [[GUSI_pos]]
// establishes the source code position for diagnostic messages.
// instead of logging.
//
// <Definition of diagnostic logfile>=
bool GUSI_pos(const char * file, int line);
bool GUSI_log(const char * format, ...);
bool GUSI_break(const char * format, ...);
// There are four levels of diagnostic handling:
// \begin{itemize}
// \item [[GUSI_DIAG_RECKLESS]] totally ignores all internal and client errors. This
// setting is not recommended.
// \item [[GUSI_DIAG_RELAXED]] ignores internal errors, but checks client errors. This
// setting is probably the best for production code.
// \item [[GUSI_DIAG_CAUTIOUS]] checks and logs internal and client errors. This
// setting is best for GUSI client development.
// \item [[GUSI_DIAG_PARANOID]] immediately stops at internal errors, checks and
// logs client and external errors. This is the preferred setting for GUSI
// internal development.
// \end{itemize}
//
//
// <Definition of diagnostic levels>=
#define GUSI_DIAG_RECKLESS 0
#define GUSI_DIAG_RELAXED 1
#define GUSI_DIAG_CAUTIOUS 2
#define GUSI_DIAG_PARANOID 3
// [[GUSI_DIAG]] is defined to the diagnostic level. It can be overridden on a
// module by module basis, or by changing the default setting here.
// [[GUSI_MESSAGE_LEVEL]] determines how important a message has to be to print it.
// [[GUSI_LOG_POS]] determines whether we want to log the code position.
//
// <Definition of diagnostic levels>=
#ifndef GUSI_DIAG
#define GUSI_DIAG GUSI_DIAG_PARANOID
#endif
#ifndef GUSI_LOG_POS
#define GUSI_LOG_POS 0
#endif
#ifndef GUSI_MESSAGE_LEVEL
#define GUSI_MESSAGE_LEVEL 3
#endif
// <Definition of diagnostics>=
#if GUSI_LOG_POS
#define GUSI_POS GUSI_pos(__FILE__, __LINE__)
#define GUSI_LOG GUSI_POS || GUSI_log
#else
#define GUSI_LOG GUSI_log
#endif
#define GUSI_BREAK GUSI_break
// <Definition of diagnostics>=
#if GUSI_DIAG == GUSI_DIAG_RECKLESS
// [[GUSI_DIAG_RECKLESS]] only checks for external errors.
//
// <Diagnostics for [[GUSI_DIAG_RECKLESS]]>=
#define GUSI_ASSERT_INTERNAL(COND, ARGLIST) true
#define GUSI_ASSERT_CLIENT(COND, ARGLIST) true
#define GUSI_ASSERT_EXTERNAL(COND, ARGLIST) (COND)
#define GUSI_SASSERT_INTERNAL(COND, MSG) true
#define GUSI_SASSERT_CLIENT(COND, MSG) true
#define GUSI_SASSERT_EXTERNAL(COND, MSG) (COND)
#elif GUSI_DIAG == GUSI_DIAG_RELAXED
// [[GUSI_DIAG_RELAXED]] ignores internal errors, but checks client errors.
//
// <Diagnostics for [[GUSI_DIAG_RELAXED]]>=
#define GUSI_ASSERT_INTERNAL(COND, ARGLIST) true
#define GUSI_ASSERT_CLIENT(COND, ARGLIST) (COND)
#define GUSI_ASSERT_EXTERNAL(COND, ARGLIST) (COND)
#define GUSI_SASSERT_INTERNAL(COND, MSG) true
#define GUSI_SASSERT_CLIENT(COND, MSG) (COND)
#define GUSI_SASSERT_EXTERNAL(COND, MSG) (COND)
#elif GUSI_DIAG == GUSI_DIAG_CAUTIOUS
// [[GUSI_DIAG_CAUTIOUS]] checks and logs internal and client errors.
//
// <Diagnostics for [[GUSI_DIAG_CAUTIOUS]]>=
#define GUSI_ASSERT_INTERNAL(COND, ARGLIST) ((COND) || GUSI_LOG ARGLIST)
#define GUSI_ASSERT_CLIENT(COND, ARGLIST) ((COND) || GUSI_LOG ARGLIST)
#define GUSI_ASSERT_EXTERNAL(COND, ARGLIST) (COND)
#define GUSI_SASSERT_INTERNAL(COND, MSG) ((COND) || GUSI_LOG ("%s", MSG))
#define GUSI_SASSERT_CLIENT(COND, MSG) ((COND) || GUSI_LOG ("%s", MSG))
#define GUSI_SASSERT_EXTERNAL(COND, MSG) (COND)
#elif GUSI_DIAG == GUSI_DIAG_PARANOID
// [[GUSI_DIAG_PARANOID]] immediately stops at internal errors, checks and
// logs client and external errors.
//
// <Diagnostics for [[GUSI_DIAG_PARANOID]]>=
#define GUSI_ASSERT_INTERNAL(COND, ARGLIST) ((COND) || GUSI_BREAK ARGLIST)
#define GUSI_ASSERT_CLIENT(COND, ARGLIST) ((COND) || GUSI_LOG ARGLIST)
#define GUSI_ASSERT_EXTERNAL(COND, ARGLIST) ((COND) || GUSI_LOG ARGLIST)
#define GUSI_SASSERT_INTERNAL(COND, MSG) ((COND) || GUSI_BREAK ("%s", (MSG)))
#define GUSI_SASSERT_CLIENT(COND, MSG) ((COND) || GUSI_LOG ("%s", MSG))
#define GUSI_SASSERT_EXTERNAL(COND, MSG) ((COND) || GUSI_LOG ("%s", MSG))
#else
#error "GUSI_DIAG defined to illegal value: " GUSI_DIAG
#endif
// There are 11 different diagnostic macros. [[GUSI_ASSERT_INTERNAL]],
// [[GUSI_ASSERT_CLIENT]] and [[GUSI_ASSERT_EXTERNAL]] check for internal,
// client, and external errors, respectively. Their first argument is a
// conditional expression which when [[false]] indicates that an error
// happened. [[GUSI_MESSAGE]] has the same logging status as
// [[GUSI_ASSERT_EXTERNAL]], but does not check any conditions. The [[SASSERT]]
// and [[SMESSAGE]] variants do the same checking, but only take a simple
// message instead of an argument list. The [[CASSERT]] variants simply output
// the condition as the message.
//
// <Definition of diagnostics>=
#define GUSI_CASSERT_INTERNAL(COND) \
GUSI_SASSERT_INTERNAL(COND, "(" #COND ") -- assertion failed.\n" )
#define GUSI_CASSERT_CLIENT(COND) \
GUSI_SASSERT_CLIENT(COND, "(" #COND ") -- assertion failed.\n" )
#define GUSI_CASSERT_EXTERNAL(COND) \
GUSI_SASSERT_EXTERNAL(COND, "(" #COND ") -- assertion failed.\n" )
#define GUSI_MESSAGE1(ARGLIST) \
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>1, ARGLIST)
#define GUSI_SMESSAGE1(MSG) \
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>1, MSG)
#define GUSI_MESSAGE2(ARGLIST) \
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>2, ARGLIST)
#define GUSI_SMESSAGE2(MSG) \
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>2, MSG)
#define GUSI_MESSAGE3(ARGLIST) \
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>3, ARGLIST)
#define GUSI_SMESSAGE3(MSG) \
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>3, MSG)
#define GUSI_MESSAGE4(ARGLIST) \
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>4, ARGLIST)
#define GUSI_SMESSAGE4(MSG) \
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>4, MSG)
#define GUSI_MESSAGE5(ARGLIST) \
GUSI_ASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>5, ARGLIST)
#define GUSI_SMESSAGE5(MSG) \
GUSI_SASSERT_EXTERNAL(GUSI_MESSAGE_LEVEL>5, MSG)
#define GUSI_MESSAGE(ARGLIST) GUSI_MESSAGE3(ARGLIST)
#define GUSI_SMESSAGE(MSG) GUSI_SMESSAGE3(MSG)
__END_DECLS
#endif /* _GUSIDiag_ */

107
GUSI/include/GUSIFSWrappers.h Executable file
View File

@ -0,0 +1,107 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIFSWrappers.nw - Pseudo-synchronous file calls
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:11 chombier
// % Initial import
// %
// % Revision 1.7 2001/01/17 08:45:49 neeri
// % Make open calls synchronous
// %
// % Revision 1.6 2000/05/23 06:58:04 neeri
// % Improve formatting
// %
// % Revision 1.5 2000/01/17 01:41:52 neeri
// % Handle special cases in FSMoveRename
// %
// % Revision 1.4 1999/08/26 05:45:01 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.3 1999/07/19 06:21:02 neeri
// % Add mkdir/rmdir, fix various file manager related bugs
// %
// % Revision 1.2 1999/05/30 02:16:54 neeri
// % Cleaner definition of GUSICatInfo
// %
// % Revision 1.1 1998/10/11 16:45:14 neeri
// % Ready to release 2.0a2
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Pseudo-synchronous File System Calls}
//
// MacOS offers a wide variety of file system APIs, but the most convenient
// of them--the [[FSpXXX]] calls only works synchronously. The routines defined
// here offer a version of these calls, executed asynchronously and embedded
// into the [[GUSIContext]] switching model.
//
// <GUSIFSWrappers.h>=
#ifndef _GUSIFSWrappers_
#define _GUSIFSWrappers_
#ifdef GUSI_SOURCE
#include <Files.h>
#include <sys/cdefs.h>
#include "GUSIFileSpec.h"
__BEGIN_DECLS
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSOpenDriver(StringPtr name, short * refNum);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSGetFInfo(const FSSpec * spec, FInfo * info);
OSErr GUSIFSSetFInfo(const FSSpec * spec, const FInfo * info);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSOpenDF(const FSSpec * spec, char permission, short * refNum);
OSErr GUSIFSOpenRF(const FSSpec * spec, char permission, short * refNum);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSGetVolParms(short vRefNum, GetVolParmsInfoBuffer * volParms);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSCreate(const FSSpec * spec, OSType creator, OSType type, ScriptCode script);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSDelete(const FSSpec * spec);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSDirCreate(const FSSpec * spec);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSSetFLock(const FSSpec * spec);
OSErr GUSIFSRstFLock(const FSSpec * spec);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSRename(const FSSpec * spec, ConstStr255Param newname);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSCatMove(const FSSpec * spec, const FSSpec * dest);
// <Declarations of C [[GUSIFSWrappers]]>=
OSErr GUSIFSMoveRename(const FSSpec * spec, const FSSpec * dest);
__END_DECLS
#ifdef __cplusplus
// <Declarations of C++ [[GUSIFSWrappers]]>=
OSErr GUSIFSGetCatInfo(GUSIIOPBWrapper<GUSICatInfo> * info);
OSErr GUSIFSSetCatInfo(GUSIIOPBWrapper<GUSICatInfo> * info);
// <Declarations of C++ [[GUSIFSWrappers]]>=
OSErr GUSIFSGetFCBInfo(GUSIIOPBWrapper<FCBPBRec> * fcb);
// <Declarations of C++ [[GUSIFSWrappers]]>=
OSErr GUSIFSGetVInfo(GUSIIOPBWrapper<ParamBlockRec> * pb);
OSErr GUSIFSHGetVInfo(GUSIIOPBWrapper<HParamBlockRec> * pb);
// According to Andreas Grosam, [[PBOpenAsync]] may cause the file not to be closed properly when the
// process quits, so we call that call synchronously.
//
// <Declarations of C++ [[GUSIFSWrappers]]>=
OSErr GUSIFSOpen(GUSIIOPBWrapper<ParamBlockRec> * pb);
// <Declarations of C++ [[GUSIFSWrappers]]>=
OSErr GUSIFSHGetFInfo(GUSIIOPBWrapper<HParamBlockRec> * pb);
OSErr GUSIFSHSetFInfo(GUSIIOPBWrapper<HParamBlockRec> * pb);
// <Declarations of C++ [[GUSIFSWrappers]]>=
OSErr GUSIFSHGetVolParms(GUSIIOPBWrapper<HParamBlockRec> * pb);
// <Declarations of C++ [[GUSIFSWrappers]]>=
OSErr GUSIFSCreate(const FSSpec * spec);
// <Declarations of C++ [[GUSIFSWrappers]]>=
OSErr GUSIFSCatMove(const FSSpec * spec, long dest);
#endif
#endif /* GUSI_SOURCE */
#endif /* GUSIFSWrappers */

203
GUSI/include/GUSIFactory.h Executable file
View File

@ -0,0 +1,203 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIFactory.nw - Socket factories
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:10 chombier
// % Initial import
// %
// % Revision 1.10 2000/05/23 07:00:00 neeri
// % Improve formatting
// %
// % Revision 1.9 2000/03/15 07:22:07 neeri
// % Enforce alignment choices
// %
// % Revision 1.8 1999/11/15 07:27:18 neeri
// % Getting ready for GUSI 2.0.1
// %
// % Revision 1.7 1999/08/26 05:45:02 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.6 1999/05/29 06:26:43 neeri
// % Fixed header guards
// %
// % Revision 1.5 1998/11/22 23:06:53 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.4 1998/10/25 11:37:37 neeri
// % More configuration hooks
// %
// % Revision 1.3 1998/08/02 11:20:08 neeri
// % Fixed some typos
// %
// % Revision 1.2 1998/01/25 20:53:54 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.1 1996/12/16 02:12:40 neeri
// % TCP Sockets sort of work
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Socket Factories}
//
// Instead of creating sockets of some specific subtype of [[GUSISocket]],
// directly, we choose the more flexible approach of creating them in
// some instance of a subtype of the abstract factory class [[GUSISocketFactory]].
// For even more flexibility and a direct mapping to BSD socket domains,
// [[GUSISocketFactory]] instances are collected in a [[GUSISocketDomainRegistry]].
// If several types and or protocols in a domain are implemented, they are collected
// in a [[GUSISocketTypeRegistry]].
//
// <GUSIFactory.h>=
#ifndef _GUSIFactory_
#define _GUSIFactory_
#ifdef GUSI_SOURCE
#include "GUSISocket.h"
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of [[GUSISocketFactory]]}
//
// [[GUSISocketFactory]] consists of a few maintenance functions and the socket
// operations.
//
// <Definition of class [[GUSISocketFactory]]>=
class GUSISocketFactory {
public:
virtual int socketpair(int domain, int type, int protocol, GUSISocket * s[2]);
virtual GUSISocket * socket(int domain, int type, int protocol) = 0;
protected:
GUSISocketFactory() {}
virtual ~GUSISocketFactory() {}
};
// \section{Definition of [[GUSISocketDomainRegistry]]}
//
// The [[GUSISocketDomainRegistry]] is a singleton class registering all socket
// domains.
//
// <Definition of class [[GUSISocketDomainRegistry]]>=
class GUSISocketDomainRegistry : public GUSISocketFactory {
public:
// The only instance of [[GUSISocketDomainRegistry]] is, as usual, obtained by calling
// [[Instance]]. Calling [[socket]] on this instance will then create a socket.
//
// <Socket creation interface of [[GUSISocketDomainRegistry]]>=
virtual GUSISocket * socket(int domain, int type, int protocol);
virtual int socketpair(int domain, int type, int protocol, GUSISocket * s[2]);
static GUSISocketDomainRegistry * Instance();
// [[AddFactory]] and [[RemoveFactory]] add and remove a [[GUSISocketFactory]]
// for a given domain number. Both return the previous registrant.
//
// <Registration interface of [[GUSISocketDomainRegistry]]>=
GUSISocketFactory * AddFactory(int domain, GUSISocketFactory * factory);
GUSISocketFactory * RemoveFactory(int domain);
private:
// <Privatissima of [[GUSISocketDomainRegistry]]>=
static GUSISocketDomainRegistry * sInstance;
// We store domain factories in a table that is quite comfortably sized.
//
// <Privatissima of [[GUSISocketDomainRegistry]]>=
GUSISocketFactory * factory[AF_MAX];
GUSISocketDomainRegistry();
};
// \section{Definition of [[GUSISocketTypeRegistry]]}
//
// A [[GUSISocketTypeRegistry]] registers factories for some domain by type and
// protocol.
//
// <Definition of class [[GUSISocketTypeRegistry]]>=
class GUSISocketTypeRegistry : public GUSISocketFactory {
public:
// [[GUSISocketTypeRegistry]] is not a singleton, but each instance is somewhat
// singletonish in that it does some delayed initialization only when it's used
// and at that point registers itself with the [[GUSISocketDomainRegistry]].
// Calling [[socket]] on these instances will then create a socket.
//
// <Socket creation interface of [[GUSISocketTypeRegistry]]>=
GUSISocketTypeRegistry(int domain, int maxfactory);
virtual GUSISocket * socket(int domain, int type, int protocol);
virtual int socketpair(int domain, int type, int protocol, GUSISocket * s[2]);
// [[AddFactory]] and [[RemoveFactory]] add and remove a [[GUSISocketFactory]]
// for a given type and protocol (both of which can be specified as 0 to match any
// value). Both return the previous registrant.
//
// <Registration interface of [[GUSISocketTypeRegistry]]>=
GUSISocketFactory * AddFactory(int type, int protocol, GUSISocketFactory * factory);
GUSISocketFactory * RemoveFactory(int type, int protocol);
private:
// \section{Implementation of [[GUSISocketTypeRegistry]]}
//
// We store type factories in a fixed size table. This table is only
// initialized when any non-constructor public member is called.
//
// <Privatissima of [[GUSISocketTypeRegistry]]>=
struct Entry {
int type;
int protocol;
GUSISocketFactory * factory;
Entry() : type(0), protocol(0), factory(nil) {}
};
Entry * factory;
int domain;
int maxfactory;
// [[Initialize]] initializes the table and registers the object with the
// [[GUSISocketDomainRegistry]] the first time it's called.
//
// <Privatissima of [[GUSISocketTypeRegistry]]>=
void Initialize();
// Unlike for a [[GUSISocketDomainRegistry]], match identification for a
// [[GUSISocketTypeRegistry]] takes a linear search. [[Find]] stops
// when it has found either a match or an empty slot.
//
// <Privatissima of [[GUSISocketTypeRegistry]]>=
bool Find(int type, int protocol, bool exact, Entry *&found);
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// \section{Implementation of [[GUSISocketDomainRegistry]]}
//
// By now, you should know how singletons are created. Could it be that the
// combination of Design Patterns and Literate Programming leads to a
// proliferation of cliches?
//
// <Definition of [[GUSISetupFactories]] hook>=
extern "C" void GUSISetupFactories();
// <Inline member functions for class [[GUSISocketDomainRegistry]]>=
inline GUSISocketDomainRegistry * GUSISocketDomainRegistry::Instance()
{
if (!sInstance) {
sInstance = new GUSISocketDomainRegistry();
GUSISetupFactories();
}
return sInstance;
}
// [[RemoveFactory]] can actually be implemented in terms of [[AddFactory]] but
// that might confuse readers.
//
// <Inline member functions for class [[GUSISocketDomainRegistry]]>=
inline GUSISocketFactory * GUSISocketDomainRegistry::RemoveFactory(int domain)
{
return AddFactory(domain, nil);
}
// <Inline member functions for class [[GUSISocketTypeRegistry]]>=
inline GUSISocketTypeRegistry::GUSISocketTypeRegistry(int domain, int maxfactory)
: domain(domain), maxfactory(maxfactory), factory(nil)
{
}
#endif /* GUSI_SOURCE */
#endif /* _GUSIFactory_ */

587
GUSI/include/GUSIFileSpec.h Executable file
View File

@ -0,0 +1,587 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIFileSpec.nw - File specifications
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:11 chombier
// % Initial import
// %
// % Revision 1.15 2001/01/17 08:46:45 neeri
// % Get rid of excess directory seperators when name is empty
// %
// % Revision 1.14 2000/12/23 06:10:17 neeri
// % Add GUSIFSpTouchFolder, GUSIFSpGetCatInfo; copy error in copy constructor
// %
// % Revision 1.13 2000/10/16 03:59:36 neeri
// % Make FSSpec a member of GUSIFileSpec instead of a base class
// %
// % Revision 1.12 2000/06/12 04:20:58 neeri
// % Introduce GUSI_*printf
// %
// % Revision 1.11 2000/05/23 07:00:00 neeri
// % Improve formatting
// %
// % Revision 1.10 2000/03/15 07:16:08 neeri
// % Fix path construction, temp name bugs
// %
// % Revision 1.9 2000/03/06 06:34:11 neeri
// % Added C FSSpec convenience calls
// %
// % Revision 1.8 1999/08/26 05:45:02 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.7 1999/07/19 06:21:02 neeri
// % Add mkdir/rmdir, fix various file manager related bugs
// %
// % Revision 1.6 1999/06/28 06:00:53 neeri
// % add support for generating temp names from basename
// %
// % Revision 1.5 1999/05/30 02:16:53 neeri
// % Cleaner definition of GUSICatInfo
// %
// % Revision 1.4 1999/03/17 09:05:07 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.3 1998/10/11 16:45:15 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.2 1998/08/01 21:32:04 neeri
// % About ready for 2.0a1
// %
// % Revision 1.1 1998/01/25 21:02:46 neeri
// % Engine implemented, except for signals & scheduling
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{File specifications}
//
// While the Macintosh toolbox has a convenient type [[FSSpec]] to pass to
// file system routines, it lacks manipulation functions. We provide them here.
// This module has been known under a different name and with different data types
// in GUSI 1.
//
// <GUSIFileSpec.h>=
#ifndef _GUSIFileSpec_
#define _GUSIFileSpec_
#include <MacTypes.h>
#include <Files.h>
#include <Folders.h>
#include <string.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
// \section{C Interfaces to [[GUSIFileSpec]]}
//
// Many of the API routines defined here are useful to C code and not too hard to make accessible,
// even though I prefer the C++ versions. As opposed to GUSI 1, we stick to our namespace now.
//
// <Plain C interfaces to [[GUSIFileSpec]]>=
/*
* Construct a FSSpec from...
*/
/* ... the refNum of an open file. */
OSErr GUSIFRefNum2FSp(short fRefNum, FSSpec * desc);
/* ... a working directory & file name. */
OSErr GUSIWD2FSp(short wd, ConstStr31Param name, FSSpec * desc);
/* ... a path name. */
OSErr GUSIPath2FSp(const char * path, FSSpec * desc);
/* ... a special object. */
OSErr GUSISpecial2FSp(OSType object, short vol, FSSpec * desc);
/* ... a temporary file path. */
OSErr GUSIMakeTempFSp(short vol, long dirID, FSSpec * desc);
/*
* Convert a FSSpec into...
*/
/* ... a full path name. */
char * GUSIFSp2FullPath(const FSSpec * desc);
/* ... a relative path name if possible, full if not */
char * GUSIFSp2RelPath(const FSSpec * desc);
/* ... a path relative to the specified directory */
char * GUSIFSp2DirRelPath(const FSSpec * desc, const FSSpec * dir);
/* ... an GUSI-=specific ASCII encoding. */
char * GUSIFSp2Encoding(const FSSpec * desc);
/*
* Construct FSSpec of...
*/
/* ... (vRefNum, parID) */
OSErr GUSIFSpUp(FSSpec * desc);
/* ... file (name) in directory denoted by desc */
OSErr GUSIFSpDown(FSSpec * desc, ConstStr31Param name);
/* ... of nth file in directory denoted by (vRefNum, parID) */
OSErr GUSIFSpIndex(FSSpec * desc, short n);
/* Resolve if alias file */
OSErr GUSIFSpResolve(FSSpec * spec);
/* Touch folder containing the object */
OSErr GUSIFSpTouchFolder(const FSSpec * spec);
/* Get catalog information */
OSErr GUSIFSpGetCatInfo(const FSSpec * spec, CInfoPBRec * info);
__END_DECLS
#ifdef GUSI_SOURCE
#include "GUSIBasics.h"
#include "GUSIContext.h"
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of [[GUSICatInfo]]}
//
// [[GUSICatInfo]] is a wrapper for [[CInfoPBRec]]. Since the latter is a [[union]], we cannot
// inherit from it.
//
// <Definition of class [[GUSICatInfo]]>=
class GUSICatInfo {
CInfoPBRec fInfo;
public:
bool IsFile() const;
bool IsAlias() const;
bool DirIsExported() const;
bool DirIsMounted() const;
bool DirIsShared() const;
bool HasRdPerm() const;
bool HasWrPerm() const;
bool Locked() const;
CInfoPBRec & Info() { return fInfo; }
operator CInfoPBRec &() { return fInfo; }
struct HFileInfo & FileInfo() { return fInfo.hFileInfo; }
struct DirInfo & DirInfo() { return fInfo.dirInfo; }
struct FInfo & FInfo() { return fInfo.hFileInfo.ioFlFndrInfo; }
struct FXInfo & FXInfo() { return fInfo.hFileInfo.ioFlXFndrInfo; }
const CInfoPBRec & Info() const { return fInfo; }
operator const CInfoPBRec &() const { return fInfo; }
const struct HFileInfo & FileInfo() const{ return fInfo.hFileInfo; }
const struct DirInfo & DirInfo() const { return fInfo.dirInfo; }
const struct FInfo & FInfo() const { return fInfo.hFileInfo.ioFlFndrInfo; }
const struct FXInfo & FXInfo() const { return fInfo.hFileInfo.ioFlXFndrInfo; }
};
// \section{Definition of [[GUSIFileSpec]]}
//
// A [[GUSIFileSpec]] is a manipulation friendly version of an [[FSSpec]]. Due to
// conversion operators, a [[GUSIFileSpec]] can be used whereever a [[const FSSpec]]
// is specified. For any long term storage, [[FSSpec]] should be used rather than the
// much bulkier [[GUSIFileSpec]].
//
// <Definition of class [[GUSIFileSpec]]>=
class GUSIFileSpec {
public:
// A [[GUSIFileSpec]] can be constructed in lots of different ways. Most of the
// constructors have a final argument [[useAlias]] that, when [[true]], suppresses
// resolution of leaf aliases.
//
// First, two trivial cases: The default constructor and the copy constructor, which
// do exactly what you'd expect them to do.
//
// <Constructors for [[GUSIFileSpec]]>=
GUSIFileSpec() {}
GUSIFileSpec(const GUSIFileSpec & spec);
// The [[FSSpec]] conversion is almost a copy constructor, but by default resolves
// leaf aliases.
//
// <Constructors for [[GUSIFileSpec]]>=
GUSIFileSpec(const FSSpec & spec, bool useAlias = false);
// A number of convenience constructors let you construct a [[GUSIFileSpec]] from
// various components.
//
// <Constructors for [[GUSIFileSpec]]>=
// Construct from volume reference number, directory ID & file name
GUSIFileSpec(short vRefNum, long parID, ConstStr31Param name, bool useAlias = false);
// Construct from working directory & file name
GUSIFileSpec(short wd, ConstStr31Param name, bool useAlias = false);
// Construct from full or relative path
GUSIFileSpec(const char * path, bool useAlias = false);
// Construct from open file reference number
explicit GUSIFileSpec(short fRefNum);
// Finally, there is a constructor for constructing a [[GUSIFileSpec]] for one of
// the folders obtainable with [[FindFolder]].
//
// <Constructors for [[GUSIFileSpec]]>=
GUSIFileSpec(OSType object, short vol = kOnSystemDisk);
// All [[GUSIFileSpecs]] have an error variable from which the last error
// is available.
//
// <Error handling in [[GUSIFileSpec]]>=
OSErr Error() const;
operator void*() const;
bool operator!() const;
// While earlier versions of GUSI maintained a notion of "current directory" that
// was independent of the HFS default directory, there is no such distinction anymore
// in GUSI 2. [[SetDefaultDirectory]] sets the default directory to [[vRefNum, dirID]].
// [[GetDefaultDirectory]] sets [[vRefNum,dirID]] to the default directory. Neither
// routine affects the [[name]]. [[GetVolume]] gets the named or indexed volume.
//
// <Default directory handling in [[GUSIFileSpec]]>=
OSErr SetDefaultDirectory();
OSErr GetDefaultDirectory();
OSErr GetVolume(short index = -1);
// Conversions of [[GUSIFileSpec]] to [[FSSpec]] values and references is, of course,
// simple. Pointers are a bit trickier; we define an custom [[operator&]] and two
// smart pointer classes. [[operator->]], however, is simpler.
//
// <Converting a [[GUSIFileSpec]] to a [[FSSpec]]>=
operator const FSSpec &() const;
class pointer {
public:
pointer(GUSIFileSpec * ptr);
operator GUSIFileSpec *() const;
operator const FSSpec *() const;
private:
GUSIFileSpec * ptr;
};
pointer operator&();
class const_pointer {
public:
const_pointer(const GUSIFileSpec * ptr);
operator const GUSIFileSpec *() const;
operator const FSSpec *() const;
private:
const GUSIFileSpec * ptr;
};
const_pointer operator&() const;
const FSSpec * operator->() const;
friend class pointer;
friend class const_pointer;
// Each [[GUSIFileSpec]] has an implicit [[GUSICatInfo]] record associated with it.
// [[CatInfo]] calls [[GetCatInfo]] if the record is not already valid and
// returns a pointer to the record. [[DirInfo]] replaces the [[GUSIFileSpec]] by
// the specification of its parent directory and returns a pointer to information
// about the parent. Both calls return a [[nil]] pointer if the object does not exist.
// If all you are interested in is whether the object exists, call [[Exists]].
//
// <Getting the [[GUSICatInfo]] for a [[GUSIFileSpec]]>=
const GUSICatInfo * CatInfo(short index);
const GUSICatInfo * DirInfo();
const GUSICatInfo * CatInfo() const;
bool Exists() const;
// In many POSIXish contexts, it's necessary to specify path names with C string.
// Although this practice is dangerous on a Mac, we of course have to conform to
// it. The basic operations are getting a full path and getting a path relative to
// a directory (the current directory by default).
//
// <Getting path names from a [[GUSIFileSpec]]>=
char * FullPath() const;
char * RelativePath() const;
char * RelativePath(const FSSpec & dir) const;
// If the path ultimately is going to flow back into a GUSI routine again, it is
// possible to simply encode the [[GUSIFileSpec]] in ASCII. This is fast and reliable,
// but you should of course not employ it with any non-GUSI destination routine and
// should never store such a part across a reboot. The standard [[GUSIFileSpec]]
// constructors for paths will accept encoded paths.
//
// The encoding is defined as:
//
// \begin{itemize}
// \item 1 byte: DC1 (ASCII 0x11)
// \item 4 bytes: Volume reference number in zero-padded hex
// \item 8 bytes: Directory ID in zero-padded hex
// \item n bytes: Partial pathname, starting with ':'
// \end{itemize}
//
// <Getting path names from a [[GUSIFileSpec]]>=
char * EncodedPath() const;
// Most aliases are resolved implicitly, but occasionally you may want to do
// explicit resolution. [[Resolve]] resolves an alias. If [[gently]] is set,
// nonexistent target files of aliases don't cause an error to be returned.
//
// <Alias resolution for a [[GUSIFileSpec]]>=
OSErr Resolve(bool gently = true);
// [[AliasPath]] returns the path an alias points to without mounting any volumes.
//
// <Alias resolution for a [[GUSIFileSpec]]>=
char * AliasPath() const;
// A major feature of the [[GUSIFileSpec]] class is the set of operators for
// manipulating a file specification.
//
// [[operator--]] replaces a file specification with the directory specification of
// its parent.
//
// <Manipulating a [[GUSIFileSpec]]>=
GUSIFileSpec & operator--();
// [[operator++]] sets the [[dirID]] of a directory specification to the ID of the
// directory.
//
// <Manipulating a [[GUSIFileSpec]]>=
GUSIFileSpec & operator++();
// The two versions of [[operator+=]], which internally both call [[AddPathComponent]],
// replace a directory specification with the specification
//
// <Manipulating a [[GUSIFileSpec]]>=
GUSIFileSpec & AddPathComponent(const char * name, int length, bool fullSpec);
GUSIFileSpec & operator+=(ConstStr31Param name);
GUSIFileSpec & operator+=(const char * name);
// [[operator+]] provides a non-destructive variant of [[operator+=]].
//
// <Manipulating a [[GUSIFileSpec]]>=
friend GUSIFileSpec operator+(const FSSpec & spec, ConstStr31Param name);
friend GUSIFileSpec operator+(const FSSpec & spec, const char * name);
// Array access replaces the file specification with the [[index]]th object in the
// {\em parent directory} of the specification (allowing the same specification to
// be reused for reading a directory).
//
// <Manipulating a [[GUSIFileSpec]]>=
GUSIFileSpec & operator[](short index);
// To manipulate the fields of the file specification directly, there is a procedural
// interface.
//
// <Manipulating a [[GUSIFileSpec]]>=
void SetVRef(short vref);
void SetParID(long parid);
void SetName(ConstStr63Param nam);
void SetName(const char * nam);
// For some modifications to propagate quickly, the surrounding folder needs to
// have its date modified.
//
// <Manipulating a [[GUSIFileSpec]]>=
OSErr TouchFolder();
// Two [[GUSIFileSpecs]] can be compared for (in)equality.
//
// <Comparing two [[GUSIFileSpec]] objects>=
friend bool operator==(const GUSIFileSpec & one, const GUSIFileSpec & other);
// [[IsParentOf]] determines whether the object specifies a parent directory of
// [[other]].
//
// <Comparing two [[GUSIFileSpec]] objects>=
bool IsParentOf(const GUSIFileSpec & other) const;
protected:
// \section{Implementation of [[GUSIFileSpec]]}
//
// [[sError]] contains the error code for failed calls. [[Error]] returns the value.
//
// <Privatissima of [[GUSIFileSpec]]>=
mutable OSErr fError;
// For path name constructions, a sometimes large scratch area is needed which is
// maintained in [[sScratch]]. A scratch request preserves a preexisting scratch area
// at the {\em end} of the new area if [[extend]] is nonzero.
//
// <Privatissima of [[GUSIFileSpec]]>=
static char * sScratch;
static long sScratchSize;
static char * CScratch(bool extend = false);
static StringPtr PScratch();
// A [[GUSIFileSpec]] has a [[GUSICatInfo]] embedded and a flag [[fValidInfo]] indicating
// that it is valid.
//
// <Privatissima of [[GUSIFileSpec]]>=
FSSpec fSpec;
GUSIIOPBWrapper<GUSICatInfo> fInfo;
bool fValidInfo;
// For convenience, we define a fictivous parent directory of all volumes.
//
// <Privatissima of [[GUSIFileSpec]]>=
enum { ROOT_MAGIC_COOKIE = 666 };
// Each accumulation step is preformed in [[PrependPathComponent]].
//
// <Privatissima of [[GUSIFileSpec]]>=
OSErr PrependPathComponent(char *&path, ConstStr63Param component, bool colon) const;
};
// A [[GUSITempFileSpec]] is just a [[GUSIFileSpec]] with constructors to construct
// filenames for temporary files.
//
// <Definition of class [[GUSIFileSpec]]>=
class GUSITempFileSpec : public GUSIFileSpec {
public:
GUSITempFileSpec(short vRefNum = kOnSystemDisk);
GUSITempFileSpec(short vRefNum, long parID);
GUSITempFileSpec(ConstStr31Param basename);
GUSITempFileSpec(short vRefNum, ConstStr31Param basename);
GUSITempFileSpec(short vRefNum, long parID, ConstStr31Param basename);
private:
void TempName();
void TempName(ConstStr31Param basename);
static int sID;
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// \section{Implementation of [[GUSICatInfo]]}
//
// All of the member functions for [[GUSICatInfo]] are inline.
//
// <Inline member functions for class [[GUSICatInfo]]>=
inline bool GUSICatInfo::IsFile() const
{
return !(DirInfo().ioFlAttrib & 0x10);
}
inline bool GUSICatInfo::IsAlias() const
{
return
!(FileInfo().ioFlAttrib & 0x10) &&
(FInfo().fdFlags & (1 << 15));
}
inline bool GUSICatInfo::DirIsExported() const
{
return (FileInfo().ioFlAttrib & 0x20) != 0;
}
inline bool GUSICatInfo::DirIsMounted() const
{
return (FileInfo().ioFlAttrib & 0x08) != 0;
}
inline bool GUSICatInfo::DirIsShared() const
{
return (FileInfo().ioFlAttrib & 0x04) != 0;
}
inline bool GUSICatInfo::HasRdPerm() const
{
return !(DirInfo().ioACUser & 0x02) != 0;
}
inline bool GUSICatInfo::HasWrPerm() const
{
return !(DirInfo().ioACUser & 0x04) != 0;
}
inline bool GUSICatInfo::Locked() const
{
return (FileInfo().ioFlAttrib & 0x11) == 0x01;
}
// <Inline member functions for class [[GUSIFileSpec]]>=
inline OSErr GUSIFileSpec::Error() const
{
return fError;
}
inline GUSIFileSpec::operator void*() const
{
return (void *)!fError;
}
inline bool GUSIFileSpec::operator!() const
{
return fError!=0;
}
// <Inline member functions for class [[GUSIFileSpec]]>=
inline StringPtr GUSIFileSpec::PScratch()
{
return (StringPtr) CScratch();
}
// <Inline member functions for class [[GUSIFileSpec]]>=
inline OSErr GUSIFileSpec::SetDefaultDirectory()
{
return fError = HSetVol(nil, fSpec.vRefNum, fSpec.parID);
}
inline OSErr GUSIFileSpec::GetDefaultDirectory()
{
fSpec.name[0] = 0;
fValidInfo = false;
return fError = HGetVol(nil, &fSpec.vRefNum, &fSpec.parID);
}
// [[operator+=]] and [[operator+]] are merely wrappers around [[AddPathComponent]].
//
// <Inline member functions for class [[GUSIFileSpec]]>=
inline GUSIFileSpec & GUSIFileSpec::operator+=(ConstStr31Param name)
{
return AddPathComponent((char *) name+1, name[0], true);
}
inline GUSIFileSpec & GUSIFileSpec::operator+=(const char * name)
{
return AddPathComponent(name, strlen(name), true);
}
// The other variations of the call are simple.
//
// <Inline member functions for class [[GUSIFileSpec]]>=
inline const GUSICatInfo * GUSIFileSpec::CatInfo() const
{
return const_cast<GUSIFileSpec *>(this)->CatInfo(0);
}
inline const GUSICatInfo * GUSIFileSpec::DirInfo()
{
if (CatInfo(-1)) {
fSpec.parID = fInfo->DirInfo().ioDrParID;
fValidInfo = true;
return &fInfo.fPB;
} else
return nil;
}
inline bool GUSIFileSpec::Exists() const
{
return CatInfo() != nil;
}
// Reference conversion is straightforward, as is [[operator->]].
//
// <Inline member functions for class [[GUSIFileSpec]]>=
inline GUSIFileSpec::operator const FSSpec &() const
{
return fSpec;
}
inline const FSSpec * GUSIFileSpec::operator->() const
{
return &fSpec;
}
// Pointers, however, are a trickier issue, as they might be used either as a
// [[GUSIFileSpec *]] or as an [[FSSpec *]].
//
// <Inline member functions for class [[GUSIFileSpec]]>=
inline GUSIFileSpec::const_pointer::const_pointer(const GUSIFileSpec * ptr)
: ptr(ptr)
{
}
inline GUSIFileSpec::const_pointer::operator const GUSIFileSpec *() const
{
return ptr;
}
inline GUSIFileSpec::const_pointer::operator const FSSpec *() const
{
return &ptr->fSpec;
}
inline GUSIFileSpec::const_pointer GUSIFileSpec::operator&() const
{
return const_pointer(this);
}
// [[GUSIFileSpec::pointer]] is the non-constant equivalent to [[GUSIFileSpec::const_pointer]].
//
// <Inline member functions for class [[GUSIFileSpec]]>=
inline GUSIFileSpec::pointer::pointer(GUSIFileSpec * ptr)
: ptr(ptr)
{
}
inline GUSIFileSpec::pointer::operator GUSIFileSpec *() const
{
return ptr;
}
inline GUSIFileSpec::pointer::operator const FSSpec *() const
{
return &ptr->fSpec;
}
inline GUSIFileSpec::pointer GUSIFileSpec::operator&()
{
return pointer(this);
}
#endif /* GUSI_SOURCE */
#endif /* GUSIFileSpec */

View File

@ -0,0 +1,52 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIForeignThreads.nw - Foreign thread support
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:11 chombier
// % Initial import
// %
// % Revision 1.4 2000/12/23 06:10:48 neeri
// % Use kPowerPCCFragArch, NOT GetCurrentArchitecture()
// %
// % Revision 1.3 2000/05/23 07:00:00 neeri
// % Improve formatting
// %
// % Revision 1.2 2000/03/06 08:28:32 neeri
// % Releasing 2.0.5
// %
// % Revision 1.1 1999/09/09 07:18:06 neeri
// % Added support for foreign threads
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Supporting threads made outside of GUSI}
//
// As convenient as the pthreads interface is, some applications may link to other
// libraries which create thread manager threads directly, such as the PowerPlant
// thread classes.
//
// Unfortunately, there is no really elegant way to welcome these lost sheep into the
// pthread flock, since the thread manager offers no way to retrieve thread switching
// and termination procedures. We therefore have to resort to a violent technique used
// already successfully for MPW support: On CFM, we override the default entry point and
// use the CFM manager to find the real implementation.
//
// For non-CFM, we unfortunately don't have such an effective technique, since the
// thread manager is called through traps (and no, I'm not going to patch any traps
// for this). You will therefore have to recompile your foreign libraries with
// a precompiled header that includes \texttt{GUSIForeignThreads.h}.
//
// <GUSIForeignThreads.h>=
#ifndef _GUSIForeignThreads_
#define _GUSIForeignThreads_
#define NewThread(style, entry, param, stack, options, result, made) \
GUSINewThread((style), (entry), (param), (stack), (options), (result), (made))
#define SetThreadSwitcher(thread, switcher, param, inOrOut) \
GUSISetThreadSwitcher((thread), (switcher), (param), (inOrOut))
#define SetThreadTerminator(thread, threadTerminator, terminationProcParam) \
GUSISetThreadTerminator((thread), (threadTerminator), (terminationProcParam))
#endif /* _GUSIForeignThreads_ */

68
GUSI/include/GUSIInet.h Executable file
View File

@ -0,0 +1,68 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIMTInet.nw - Common routines for MacTCP
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:11 chombier
// % Initial import
// %
// % Revision 1.5 1999/08/26 05:45:02 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.4 1999/05/29 06:26:43 neeri
// % Fixed header guards
// %
// % Revision 1.3 1998/11/22 23:06:53 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.2 1998/10/25 11:57:34 neeri
// % Ready to release 2.0a3
// %
// % Revision 1.1 1998/08/01 21:32:05 neeri
// % About ready for 2.0a1
// %
// % Revision 1.4 1998/02/11 12:57:12 neeri
// % PowerPC Build
// %
// % Revision 1.3 1998/01/25 20:53:55 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.2 1996/12/22 19:57:56 neeri
// % TCP streams work
// %
// % Revision 1.1 1996/12/16 02:12:40 neeri
// % TCP Sockets sort of work
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{TCP/IP shared infrastructure}
//
// Both the MacTCP and the forthcoming open transport implementation of TCP/IP
// sockets share a common registry.
//
// <GUSIInet.h>=
#ifndef _GUSIInet_
#define _GUSIInet_
#ifdef GUSI_SOURCE
#include <sys/cdefs.h>
__BEGIN_DECLS
// <Definition of [[GUSIwithInetSockets]]>=
void GUSIwithInetSockets();
__END_DECLS
#ifdef GUSI_INTERNAL
#include "GUSIFactory.h"
extern GUSISocketTypeRegistry gGUSIInetFactories;
#endif /* GUSI_INTERNAL */
#endif /* GUSI_SOURCE */
#endif /* _GUSIInet_ */

104
GUSI/include/GUSIInternal.h Executable file
View File

@ -0,0 +1,104 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIBasics.nw - Common routines for GUSI
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.20 2001/01/17 08:32:30 neeri
// % Atomic locks turned out not to be necessary after all
// %
// % Revision 1.19 2001/01/17 08:31:10 neeri
// % Added PPC error codes, tweaked nullEvent handling, added atomic locks
// %
// % Revision 1.18 2000/10/16 04:34:22 neeri
// % Releasing 2.1.2
// %
// % Revision 1.17 2000/06/12 04:20:58 neeri
// % Introduce GUSI_*printf
// %
// % Revision 1.16 2000/05/23 06:51:55 neeri
// % Reorganize errors to improve formatting
// %
// % Revision 1.15 2000/03/15 07:22:05 neeri
// % Enforce alignment choices
// %
// % Revision 1.14 1999/08/26 05:44:58 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.13 1999/08/02 07:02:42 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.12 1999/06/28 05:56:01 neeri
// % Get rid of STL includes in header
// %
// % Revision 1.11 1999/06/08 04:31:29 neeri
// % Getting ready for 2.0b2
// %
// % Revision 1.10 1999/05/30 03:09:28 neeri
// % Added support for MPW compilers
// %
// % Revision 1.9 1999/04/10 04:45:05 neeri
// % Handle MacTCP errors correctly
// %
// % Revision 1.8 1999/03/17 09:05:04 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.7 1998/10/25 11:57:33 neeri
// % Ready to release 2.0a3
// %
// % Revision 1.6 1998/10/11 16:45:09 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.5 1998/01/25 20:53:50 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.4 1996/12/22 19:57:54 neeri
// % TCP streams work
// %
// % Revision 1.3 1996/11/24 12:52:04 neeri
// % Added GUSIPipeSockets
// %
// % Revision 1.2 1996/11/18 00:53:46 neeri
// % TestTimers (basic threading/timer test) works
// %
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
// % Imported into CVS
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Common routines for GUSI}
//
// This section defines various services used by all parts of GUSI:
//
// \begin{itemize}
// \item Various hooks to customize GUSI.
// \item The propagation of {\bf errors} to the [[errno]] and [[h_errno]]
// global variables.
// \item Waiting for completion of asynchronous calls.
// \item Event handling.
// \item Compiler features.
// \end{itemize}
//
// To protect our name space further, we maintain a strict C interface unless
// [[GUSI_SOURCE]] is defined, and may avoid defining some stuff unless
// [[GUSI_INTERNAL]] is defined. The following header is therefore included
// first by all GUSI source files.
//
// <GUSIInternal.h>=
#ifndef _GUSIInternal_
#define _GUSIInternal_
#include <ConditionalMacros.h>
#define GUSI_SOURCE
#define GUSI_INTERNAL
#if !TARGET_RT_MAC_CFM
#pragma segment GUSI
#endif
#endif /* _GUSIInternal_ */

65
GUSI/include/GUSIMPW.h Executable file
View File

@ -0,0 +1,65 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIMPW.nw - MPW Interface
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.13 2001/01/17 08:48:04 neeri
// % Introduce Expired(), Reset()
// %
// % Revision 1.12 2000/05/23 07:01:53 neeri
// % Improve formatting
// %
// % Revision 1.11 1999/08/26 05:45:03 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.10 1999/07/19 06:17:08 neeri
// % Add SIOW support
// %
// % Revision 1.9 1999/07/07 04:17:41 neeri
// % Final tweaks for 2.0b3
// %
// % Revision 1.8 1999/06/08 04:31:29 neeri
// % Getting ready for 2.0b2
// %
// % Revision 1.7 1999/05/29 06:26:43 neeri
// % Fixed header guards
// %
// % Revision 1.6 1999/04/29 05:33:20 neeri
// % Fix fcntl prototype
// %
// % Revision 1.5 1999/03/29 09:51:28 neeri
// % New configuration system with support for hardcoded configurations.
// %
// % Revision 1.4 1999/03/17 09:05:08 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.3 1998/11/22 23:06:54 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.2 1998/10/25 11:57:35 neeri
// % Ready to release 2.0a3
// %
// % Revision 1.1 1998/08/01 21:32:06 neeri
// % About ready for 2.0a1
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{MPW Support}
//
// In MPW tools, we have to direct some of the I/O operations to the standard
// library functions, which we otherwise try to avoid as much as possible.
// Getting at those library calls is a bit tricky: For 68K, we rename entries
// in the MPW glue library, while for PowerPC, we look up the symbols dynamically.
//
// MPW support is installed implicitly through [[GUSISetupConsoleDescriptors]]
//
// <GUSIMPW.h>=
#ifndef _GUSIMPW_
#define _GUSIMPW_
#endif /* _GUSIMPW_ */

56
GUSI/include/GUSIMSL.h Executable file
View File

@ -0,0 +1,56 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIMSL.nw - Interface to the MSL
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.8 2000/10/29 19:17:04 neeri
// % Accommodate MSL's non-compliant fopen signature
// %
// % Revision 1.7 2000/10/16 04:34:22 neeri
// % Releasing 2.1.2
// %
// % Revision 1.6 2000/05/23 07:03:25 neeri
// % Improve formatting
// %
// % Revision 1.5 1999/08/26 05:45:03 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.4 1999/08/02 07:02:43 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.3 1999/04/14 04:20:21 neeri
// % Override console hooks
// %
// % Revision 1.2 1999/04/10 04:53:58 neeri
// % Use simpler internal MSL routines
// %
// % Revision 1.1 1998/08/01 21:32:07 neeri
// % About ready for 2.0a1
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{The Interface to the MSL}
//
// This section interfaces GUSI to the Metrowerks Standard Library (MSL)
// by reimplementing various internal MSL routines. Consequently, some of
// the code used here is borrowed from the MSL code itself. The routines
// here are in three different categories:
//
// \begin{itemize}
// \item Overrides of MSL functions (all internal, as it happens).
// \item Implementations of ANSI library specific public GUSI functions like
// [[fdopen]].
// \item Implementations of ANSI library specific internal GUSI functions.
// \end{itemize}
//
//
// <GUSIMSL.h>=
#ifndef _GUSIMSL_
#define _GUSIMSL_
#endif /* _GUSIMSL_ */

194
GUSI/include/GUSIMTInet.h Executable file
View File

@ -0,0 +1,194 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIMTInet.nw - Common routines for MacTCP
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.14 2000/10/16 04:34:23 neeri
// % Releasing 2.1.2
// %
// % Revision 1.13 2000/05/23 07:03:25 neeri
// % Improve formatting
// %
// % Revision 1.12 1999/08/26 05:45:04 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.11 1999/08/02 07:02:43 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.10 1999/06/30 07:42:06 neeri
// % Getting ready to release 2.0b3
// %
// % Revision 1.9 1999/05/29 06:26:43 neeri
// % Fixed header guards
// %
// % Revision 1.8 1999/04/29 05:33:19 neeri
// % Fix fcntl prototype
// %
// % Revision 1.7 1999/03/17 09:05:08 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.6 1998/10/25 11:57:35 neeri
// % Ready to release 2.0a3
// %
// % Revision 1.5 1998/10/11 16:45:16 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.4 1998/02/11 12:57:12 neeri
// % PowerPC Build
// %
// % Revision 1.3 1998/01/25 20:53:55 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.2 1996/12/22 19:57:56 neeri
// % TCP streams work
// %
// % Revision 1.1 1996/12/16 02:12:40 neeri
// % TCP Sockets sort of work
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Basic MacTCP code}
//
// A [[GUSIMTInetSocket]] defines the infrastructure shared between
// MacTCP TCP and UDP sockets.
//
// <GUSIMTInet.h>=
#ifndef _GUSIMTInet_
#define _GUSIMTInet_
#ifdef GUSI_SOURCE
#include <sys/cdefs.h>
__BEGIN_DECLS
// <Definition of [[GUSIwithMTInetSockets]]>=
void GUSIwithMTInetSockets();
__END_DECLS
#ifdef GUSI_INTERNAL
#include "GUSISocket.h"
#include "GUSISocketMixins.h"
#include <netinet/in.h>
#include <MacTCP.h>
// \section{Definition of [[GUSIMTInetSocket]]}
//
// MacTCP related sockets are buffered, have a standard state model, and can be
// nonblocking.
//
// <Definition of class [[GUSIMTInetSocket]]>=
class GUSIMTInetSocket :
public GUSISocket,
protected GUSISMBlocking,
protected GUSISMState,
protected GUSISMInputBuffer,
protected GUSISMOutputBuffer,
protected GUSISMAsyncError
{
public:
GUSIMTInetSocket();
// [[bind]] for MacTCP sockets has the fatal flaw that it is totally unable to
// reserve a socket.
//
// <Overridden member functions for [[GUSIMTInetSocket]]>=
virtual int bind(void * addr, socklen_t namelen);
// [[getsockname]] and [[getpeername]] return the stored values.
//
// <Overridden member functions for [[GUSIMTInetSocket]]>=
virtual int getsockname(void * addr, socklen_t * namelen);
virtual int getpeername(void * addr, socklen_t * namelen);
// [[shutdown]] just delegates to [[GUSISMState]].
//
// <Overridden member functions for [[GUSIMTInetSocket]]>=
virtual int shutdown(int how);
// [[fcntl]] handles the blocking support.
//
// <Overridden member functions for [[GUSIMTInetSocket]]>=
virtual int fcntl(int cmd, va_list arg);
// [[ioctl]] deals with blocking support and with [[FIONREAD]].
//
// <Overridden member functions for [[GUSIMTInetSocket]]>=
virtual int ioctl(unsigned int request, va_list arg);
// [[getsockopt]] and [[setsockopt]] are available for setting buffer sizes and
// getting asynchronous errors.
//
// <Overridden member functions for [[GUSIMTInetSocket]]>=
virtual int getsockopt(int level, int optname, void *optval, socklen_t * optlen);
// <Overridden member functions for [[GUSIMTInetSocket]]>=
virtual int setsockopt(int level, int optname, void *optval, socklen_t optlen);
// MacTCP sockets implement socket style calls.
//
// <Overridden member functions for [[GUSIMTInetSocket]]>=
virtual bool Supports(ConfigOption config);
// MacTCP I/O calls communicate by means of read and write data structures,
// of which we need only the most primitive variants.
//
// <Definition of classes [[MiniWDS]] and [[MidiWDS]]>=
#if PRAGMA_STRUCT_ALIGN
#pragma options align=mac68k
#endif
class MiniWDS {
public:
u_short fLength;
char * fDataPtr;
u_short fZero;
MiniWDS() : fZero(0) {}
Ptr operator &() { return (Ptr)this; }
};
class MidiWDS {
public:
u_short fLength;
char * fDataPtr;
u_short fLength2;
char * fDataPtr2;
u_short fZero;
MidiWDS() : fZero(0) {}
Ptr operator &() { return (Ptr)this; }
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// The only other interesting bit in the interface is the driver management, which
// arranges to open the MacTCP driver and domain name resolver at most once,
// as late as possible in the program (If you open some SLIP or PPP drivers
// before the Toolbox is initialized, you'll wish you'd curled up by the fireside
// with a nice Lovecraft novel instead). [[Driver]] returns the driver reference
// number of the MacTCP driver. [[HostAddr]] returns our host's IP address.
//
// <MacTCP driver management>=
static short Driver();
static u_long HostAddr();
protected:
// All MacTCP related sockets need a [[StreamPtr]]; they store their own and
// their peer's address away, and the save errors reported at interrupt time
// in an [[fAsyncError]] field.
//
// <Data members for [[GUSIMTInetSocket]]>=
StreamPtr fStream;
sockaddr_in fSockAddr;
sockaddr_in fPeerAddr;
// \section{Implementation of [[GUSIMTInetSocket]]}
//
// [[Driver]] preserves error status in an [[OSErr]]
// variable, initially [[1]] to convey unresolvedness.
//
// <Data members for [[GUSIMTInetSocket]]>=
static short sDrvrRefNum;
static OSErr sDrvrState;
static u_long sHostAddress;
};
#endif /* GUSI_INTERNAL */
#endif /* GUSI_SOURCE */
#endif /* _GUSIMTInet_ */

69
GUSI/include/GUSIMTNetDB.h Executable file
View File

@ -0,0 +1,69 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSINetDB.nw - Convert between names and adresses
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.7 2000/06/12 04:20:59 neeri
// % Introduce GUSI_*printf
// %
// % Revision 1.6 2000/03/06 06:10:02 neeri
// % Reorganize Yield()
// %
// % Revision 1.5 1999/08/26 05:45:04 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.4 1999/05/30 03:09:30 neeri
// % Added support for MPW compilers
// %
// % Revision 1.3 1999/03/17 09:05:08 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.2 1998/10/25 11:57:36 neeri
// % Ready to release 2.0a3
// %
// % Revision 1.1 1998/10/11 16:45:17 neeri
// % Ready to release 2.0a2
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{IP Name Lookup in MacTCP}
//
//
// <GUSIMTNetDB.h>=
#ifndef _GUSIMTNetDB_
#define _GUSIMTNetDB_
#ifdef GUSI_INTERNAL
#include "GUSINetDB.h"
// \section{Definition of [[GUSIMTNetDB]]}
//
//
// <Definition of class [[GUSIMTNetDB]]>=
class GUSIMTNetDB : public GUSINetDB {
public:
static void Instantiate();
static bool Resolver();
// <Overridden member functions for [[GUSIMTNetDB]]>=
virtual hostent * gethostbyname(const char * name);
// <Overridden member functions for [[GUSIMTNetDB]]>=
virtual hostent * gethostbyaddr(const void * addr, size_t len, int type);
// <Overridden member functions for [[GUSIMTNetDB]]>=
virtual char * inet_ntoa(in_addr inaddr);
// <Overridden member functions for [[GUSIMTNetDB]]>=
virtual long gethostid();
private:
GUSIMTNetDB() {}
GUSISpecificData<GUSIhostent,GUSIKillHostEnt> fHost;
static OSErr sResolverState;
};
#endif /* GUSI_INTERNAL */
#endif /* _GUSIMTNetDB_ */

113
GUSI/include/GUSIMTTcp.h Executable file
View File

@ -0,0 +1,113 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIMTTcp.nw - TCP code for MacTCP
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.17 2000/10/16 04:01:59 neeri
// % Save A5 in completion routines
// %
// % Revision 1.16 2000/05/23 07:04:20 neeri
// % Improve formatting, fix hang on close
// %
// % Revision 1.15 2000/03/06 06:10:02 neeri
// % Reorganize Yield()
// %
// % Revision 1.14 1999/08/26 05:42:13 neeri
// % Fix nonblocking connects
// %
// % Revision 1.13 1999/08/02 07:02:44 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.12 1999/06/28 06:04:58 neeri
// % Support interrupted calls
// %
// % Revision 1.11 1999/06/08 04:31:29 neeri
// % Getting ready for 2.0b2
// %
// % Revision 1.10 1999/05/30 03:09:30 neeri
// % Added support for MPW compilers
// %
// % Revision 1.9 1999/03/17 09:05:08 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.8 1998/11/22 23:06:55 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.7 1998/10/25 11:31:42 neeri
// % Add MSG_PEEK support, make releases more orderly.
// %
// % Revision 1.6 1998/10/11 16:45:18 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.5 1998/08/01 21:32:07 neeri
// % About ready for 2.0a1
// %
// % Revision 1.4 1998/01/25 20:53:56 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.3 1997/11/13 21:12:11 neeri
// % Fall 1997
// %
// % Revision 1.2 1996/12/22 19:57:57 neeri
// % TCP streams work
// %
// % Revision 1.1 1996/12/16 02:12:41 neeri
// % TCP Sockets sort of work
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{MacTCP TCP sockets}
//
// A [[GUSIMTTcpSocket]] implements the TCP socket class for MacTCP. All instances
// of [[GUSIMTTcpSocket]] are created by the [[GUSIMTTcpFactory]] singleton, so
// there is no point in exporting the class itself.
//
// <GUSIMTTcp.h>=
#ifndef _GUSIMTTcp_
#define _GUSIMTTcp_
#ifdef GUSI_SOURCE
#include <sys/cdefs.h>
__BEGIN_DECLS
// \section{Definition of [[GUSIMTTcpFactory]]}
//
// [[GUSIMTTcpFactory]] is a singleton subclass of [[GUSISocketFactory]].
//
// <Definition of [[GUSIwithMTTcpSockets]]>=
void GUSIwithMTTcpSockets();
__END_DECLS
#ifdef GUSI_INTERNAL
#include "GUSIFactory.h"
// <Definition of class [[GUSIMTTcpFactory]]>=
class GUSIMTTcpFactory : public GUSISocketFactory {
public:
static GUSISocketFactory * Instance();
virtual GUSISocket * socket(int domain, int type, int protocol);
private:
GUSIMTTcpFactory() {}
static GUSISocketFactory * instance;
};
// <Inline member functions for class [[GUSIMTTcpFactory]]>=
inline GUSISocketFactory * GUSIMTTcpFactory::Instance()
{
if (!instance)
instance = new GUSIMTTcpFactory;
return instance;
}
#endif /* GUSI_INTERNAL */
#endif /* GUSI_SOURCE */
#endif /* _GUSIMTTcp_ */

95
GUSI/include/GUSIMTUdp.h Executable file
View File

@ -0,0 +1,95 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIMTUdp.nw - UDP code for MacTCP
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.11 2000/10/16 04:02:00 neeri
// % Save A5 in completion routines
// %
// % Revision 1.10 2000/05/23 07:05:16 neeri
// % Improve formatting
// %
// % Revision 1.9 2000/03/06 06:10:01 neeri
// % Reorganize Yield()
// %
// % Revision 1.8 1999/08/26 05:45:04 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.7 1999/08/02 07:02:44 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.6 1999/07/20 04:25:53 neeri
// % Fixed race condition in sendto()
// %
// % Revision 1.5 1999/06/28 06:04:59 neeri
// % Support interrupted calls
// %
// % Revision 1.4 1999/05/29 06:26:44 neeri
// % Fixed header guards
// %
// % Revision 1.3 1999/03/17 09:05:09 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.2 1998/11/22 23:06:57 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.1 1998/10/25 11:57:37 neeri
// % Ready to release 2.0a3
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{MacTCP UDP sockets}
//
// A [[GUSIMTUdpSocket]] implements the UDP socket class for MacTCP. All instances
// of [[GUSIMTUdpSocket]] are created by the [[GUSIMTUdpFactory]] singleton, so
// there is no point in exporting the class itself.
//
// <GUSIMTUdp.h>=
#ifndef _GUSIMTUdp_
#define _GUSIMTUdp_
#ifdef GUSI_SOURCE
#include <sys/cdefs.h>
__BEGIN_DECLS
// \section{Definition of [[GUSIMTUdpFactory]]}
//
// [[GUSIMTUdpFactory]] is a singleton subclass of [[GUSISocketFactory]].
//
// <Definition of [[GUSIwithMTUdpSockets]]>=
void GUSIwithMTUdpSockets();
__END_DECLS
#ifdef GUSI_INTERNAL
#include "GUSIFactory.h"
// <Definition of class [[GUSIMTUdpFactory]]>=
class GUSIMTUdpFactory : public GUSISocketFactory {
public:
static GUSISocketFactory * Instance();
virtual GUSISocket * socket(int domain, int type, int protocol);
private:
GUSIMTUdpFactory() {}
static GUSISocketFactory * instance;
};
// <Inline member functions for class [[GUSIMTUdpFactory]]>=
inline GUSISocketFactory * GUSIMTUdpFactory::Instance()
{
if (!instance)
instance = new GUSIMTUdpFactory;
return instance;
}
#endif /* GUSI_INTERNAL */
#endif /* GUSI_SOURCE */
#endif /* _GUSIMTUdp_ */

178
GUSI/include/GUSIMacFile.h Executable file
View File

@ -0,0 +1,178 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIMacFile.nw - Disk files
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.24 2001/01/17 08:58:06 neeri
// % Releasing 2.1.4
// %
// % Revision 1.23 2000/12/23 06:11:36 neeri
// % Move diagnostics to A5 safe time
// %
// % Revision 1.22 2000/10/16 04:02:00 neeri
// % Save A5 in completion routines
// %
// % Revision 1.21 2000/05/23 07:07:05 neeri
// % Improve formatting, fix lseek for readonly files
// %
// % Revision 1.20 2000/03/15 07:17:11 neeri
// % Fix rename for existing targets
// %
// % Revision 1.19 2000/03/06 08:12:27 neeri
// % New Yield system; fix readdir at end of directory
// %
// % Revision 1.18 1999/11/15 07:24:32 neeri
// % Return error for stat() of nonexistent files.
// %
// % Revision 1.17 1999/09/09 07:19:19 neeri
// % Fix read-ahead switch-off
// %
// % Revision 1.16 1999/08/26 05:45:05 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.15 1999/08/05 05:55:35 neeri
// % Updated for CW Pro 5
// %
// % Revision 1.14 1999/08/02 07:02:45 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.13 1999/07/19 06:21:03 neeri
// % Add mkdir/rmdir, fix various file manager related bugs
// %
// % Revision 1.12 1999/07/07 04:17:41 neeri
// % Final tweaks for 2.0b3
// %
// % Revision 1.11 1999/06/28 06:07:15 neeri
// % Support I/O alignment, more effective writeback strategy
// %
// % Revision 1.10 1999/05/30 02:18:05 neeri
// % Cleaner definition of GUSICatInfo
// %
// % Revision 1.9 1999/04/29 05:33:19 neeri
// % Fix fcntl prototype
// %
// % Revision 1.8 1999/04/10 04:54:39 neeri
// % stat() was broken for directories
// %
// % Revision 1.7 1999/03/29 09:51:28 neeri
// % New configuration system with support for hardcoded configurations.
// %
// % Revision 1.6 1999/03/17 09:05:09 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.5 1998/11/22 23:06:57 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.4 1998/10/11 16:45:19 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.3 1998/08/01 21:28:58 neeri
// % Add directory operations
// %
// % Revision 1.2 1998/02/11 12:57:14 neeri
// % PowerPC Build
// %
// % Revision 1.1 1998/01/25 21:02:48 neeri
// % Engine implemented, except for signals & scheduling
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Disk files}
//
// A [[GUSIMacFileSocket]] implements the operations on mac files. All instances
// of [[GUSIMacFileSocket]] are created by the [[GUSIMacFileDevice]] singleton, so
// there is no point in exporting the class itself.
//
// A [[GUSIMacDirectory]] implements directory handles on mac directories.
//
// <GUSIMacFile.h>=
#ifndef _GUSIMacFile_
#define _GUSIMacFile_
#ifdef GUSI_INTERNAL
#include "GUSIDevice.h"
// \section{Definition of [[GUSIMacFileDevice]]}
//
// [[GUSIMacFileDevice]] is a singleton subclass of [[GUSIDevice]].
//
// <Definition of class [[GUSIMacFileDevice]]>=
class GUSIMacFileDevice : public GUSIDevice {
public:
static GUSIMacFileDevice * Instance();
virtual bool Want(GUSIFileToken & file);
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual GUSISocket * open(GUSIFileToken & file, int flags);
// The normal case of [[remove]] is straightforward, but we also want to support
// the removing of open files, which is frequently used in POSIX code, as much
// as possible.
//
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int remove(GUSIFileToken & file);
// [[rename]] can be a surprisingly difficult operation.
//
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int rename(GUSIFileToken & file, const char * newname);
// [[stat]] is a rather intimidating function which needs to pull together
// information from various sources.
//
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int stat(GUSIFileToken & file, struct stat * buf);
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int chmod(GUSIFileToken & file, mode_t mode);
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int utime(GUSIFileToken & file, const utimbuf * times);
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int access(GUSIFileToken & file, int mode);
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int mkdir(GUSIFileToken & file);
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int rmdir(GUSIFileToken & file);
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual GUSIDirectory * opendir(GUSIFileToken & file);
// [[symlink]] has to reproduce the Finder's alias creation process, which is
// quite complex.
//
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int symlink(GUSIFileToken & to, const char * newlink);
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int readlink(GUSIFileToken & link, char * buf, int bufsize);
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int fgetfileinfo(GUSIFileToken & file, OSType * creator, OSType * type);
virtual int fsetfileinfo(GUSIFileToken & file, OSType creator, OSType type);
// [[faccess]] is a somewhat curious case in that [[GUSIMacFileDevice]]
// accepts responsibility for handling it, but then does not, in fact, handle
// it.
//
// <Overridden member functions for [[GUSIMacFileDevice]]>=
virtual int faccess(GUSIFileToken & file, unsigned * cmd, void * arg);
GUSISocket * open(short fileRef, int flags);
int MarkTemporary(const FSSpec & file);
void CleanupTemporaries(bool giveup);
~GUSIMacFileDevice();
protected:
GUSIMacFileDevice() : fTemporaries(0) {}
// [[MarkTemporary]] moves the file to the temporary folder and puts it on a list
// of death candidates.
//
// <Privatissima of [[GUSIMacFileDevice]]>=
struct TempQueue {
TempQueue * fNext;
FSSpec fSpec;
} * fTemporaries;
};
#endif /* GUSI_INTERNAL */
#endif /* _GUSIMacFile_ */

266
GUSI/include/GUSINetDB.h Executable file
View File

@ -0,0 +1,266 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSINetDB.nw - Convert between names and adresses
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.10 2000/12/23 06:11:55 neeri
// % Add SSH service
// %
// % Revision 1.9 2000/05/23 07:10:35 neeri
// % Improve formatting
// %
// % Revision 1.8 2000/03/15 07:18:43 neeri
// % Fix GUSIBuiltinServiceDB::sServices
// %
// % Revision 1.7 1999/11/15 07:23:23 neeri
// % Fix gethostname for non-TCP/IP case
// %
// % Revision 1.6 1999/08/26 05:45:05 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.5 1999/05/30 03:09:30 neeri
// % Added support for MPW compilers
// %
// % Revision 1.4 1999/03/17 09:05:10 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.3 1998/11/22 23:06:58 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.2 1998/10/25 11:33:38 neeri
// % Fixed disastrous bug in inet_addr, support alternative NL conventions
// %
// % Revision 1.1 1998/10/11 16:45:20 neeri
// % Ready to release 2.0a2
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Converting Between Names and IP Addresses}
//
// The [[GUSINetDB]] class coordinates access to the domain name server database.
//
// The [[GUSIServiceDB]] class is responsible for a database of TCP/IP service
// name to port number mappings.
//
// The [[hostent]] and [[servent]] classes are somewhat inconvenient to set up as
// they reference extra chunks of memory, so we define the wrapper classes
// [[GUSIhostent]] and [[GUSIservent]].
//
// <GUSINetDB.h>=
#ifndef _GUSINetDB_
#define _GUSINetDB_
#ifdef GUSI_SOURCE
#include "GUSISpecific.h"
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of [[GUSIhostent]] and [[GUSIservent]]}
//
// A [[GUSIhostent]] may need a lot of data, so we allocate the name data
// dynamically.
//
// <Definition of class [[GUSIhostent]]>=
class GUSIhostent : public hostent {
public:
GUSIhostent();
void Alloc(size_t size);
char * fAlias[16];
char * fAddressList[16];
char * fName;
size_t fAlloc;
char fAddrString[16];
};
extern "C" void GUSIKillHostEnt(void * hostent);
// A [[GUSIservent]] typically will remain more modest in its needs, so the
// data is allocated statically.
//
// <Definition of class [[GUSIservent]]>=
class GUSIservent : public servent {
public:
GUSIservent();
char * fAlias[8];
char fName[256];
};
// \section{Definition of [[GUSIServiceDB]]}
//
// [[GUSIServiceDB]] is a singleton, used as a primitive iterator. The semantics of
// these iterators conform only very superficially to real iterators:
//
// \begin{itemize}
// \item Only a single instance of the iterator is supported.
// \item Comparison operators all compare against [[end]], no matter what
// arguments are passed.
// \end{itemize}
//
// <Definition of class [[GUSIServiceDB]]>=
extern "C" void GUSIKillServiceDBData(void * entry);
class GUSIServiceDB {
public:
static GUSIServiceDB * Instance();
// Iterating is accomplished by a public interface conforming to STL iterator
// protocols.
//
// <Iterating over the [[GUSIServiceDB]]>=
class iterator {
public:
inline bool operator==(const iterator & other);
inline bool operator!=(const iterator & other);
inline iterator & operator++();
inline servent * operator*();
};
inline static iterator begin();
inline static iterator end();
protected:
static GUSIServiceDB * sInstance;
GUSIServiceDB() {}
virtual ~GUSIServiceDB() {}
friend void GUSIKillServiceDBData(void * entry);
// This interface does not access any data elements in the iterator, but directly
// calls through to a private interface in the [[GUSIServiceDB]], which explains
// the limitations in the iterator implementation.
//
// <Internal iterator protocol of [[GUSIServiceDB]]>=
friend class iterator;
class Data {
public:
Data() : fCurrent(0) {}
servent * fCurrent;
GUSIservent fServent;
};
typedef GUSISpecificData<Data, GUSIKillServiceDBData> SpecificData;
static SpecificData sData;
virtual void Reset() = 0;
virtual void Next() = 0;
};
// \section{Definition of [[GUSINetDB]]}
//
//
// <Definition of class [[GUSINetDB]]>=
class GUSINetDB {
public:
// [[GUSINetDB]] is a singleton, but usually instantiated by an instance of a
// derived class.
//
// <Constructing instances of [[GUSINetDB]]>=
static GUSINetDB * Instance();
// The public interface of [[GUSINetDB]] consists of three areas. The first set of
// calls is concerned with host names and IP numbers.
//
// <[[GUSINetDB]] host database>=
virtual hostent * gethostbyname(const char * name);
virtual hostent * gethostbyaddr(const void * addr, size_t len, int type);
virtual char * inet_ntoa(in_addr inaddr);
virtual in_addr_t inet_addr(const char *address);
virtual long gethostid();
virtual int gethostname(char *machname, int buflen);
// The next set of calls is concerned with TCP and UDP services.
//
// <[[GUSINetDB]] service database>=
virtual servent * getservbyname(const char * name, const char * proto);
virtual servent * getservbyport(int port, const char * proto);
virtual servent * getservent();
virtual void setservent(int stayopen);
virtual void endservent();
// Finally, there is a set of calls concerned with protocols.
//
// <[[GUSINetDB]] protocol database>=
virtual protoent * getprotobyname(const char * name);
virtual protoent * getprotobynumber(int proto);
virtual protoent * getprotoent();
virtual void setprotoent(int stayopen);
virtual void endprotoent();
protected:
GUSINetDB();
virtual ~GUSINetDB() {}
// \section{Implementation of [[GUSINetDB]]}
//
// [[GUSINetDB]] is a singleton, but typically implemented by an instance
// of a subclass (stored into [[fInstance]] by that subclass) rather than the
// base class.
//
// <Privatissima of [[GUSINetDB]]>=
static GUSINetDB * sInstance;
// The service database is implemented in terms of [[GUSIServiceDB]]. Only
// [[getservent]] and [[setservent]] accesse [[GUSIServiceDB]] directly, however.
//
// <Privatissima of [[GUSINetDB]]>=
bool fServiceOpen;
GUSIServiceDB::iterator fServiceIter;
// The protocol database is similar, in principle, to the service database, but it
// lends itself naturally to a much simpler implementation.
//
// <Privatissima of [[GUSINetDB]]>=
int fNextProtocol;
static protoent sProtocols[2];
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
#ifdef GUSI_INTERNAL
// Iterators can be defined without regard to the implementation of the
// [[GUSIServiceDB]] currently used.
//
// <Inline member functions for class [[GUSIServiceDB]]>=
GUSIServiceDB::iterator GUSIServiceDB::begin()
{
Instance()->Reset();
Instance()->Next();
return iterator();
}
GUSIServiceDB::iterator GUSIServiceDB::end()
{
return iterator();
}
bool GUSIServiceDB::iterator::operator==(const GUSIServiceDB::iterator &)
{
return !GUSIServiceDB::sData->fCurrent;
}
bool GUSIServiceDB::iterator::operator!=(const GUSIServiceDB::iterator &)
{
return GUSIServiceDB::sData->fCurrent
== static_cast<servent *>(nil);
}
GUSIServiceDB::iterator & GUSIServiceDB::iterator::operator++()
{
GUSIServiceDB::Instance()->Next();
return *this;
}
servent * GUSIServiceDB::iterator::operator*()
{
return GUSIServiceDB::sData->fCurrent;
}
#endif /* GUSI_INTERNAL */
#endif /* GUSI_SOURCE */
#endif /* _GUSINetDB_ */

75
GUSI/include/GUSINull.h Executable file
View File

@ -0,0 +1,75 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSINull.nw - Null device
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.7 2000/03/06 06:03:29 neeri
// % Check device families for file paths
// %
// % Revision 1.6 1999/08/26 05:45:05 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.5 1999/05/29 06:26:44 neeri
// % Fixed header guards
// %
// % Revision 1.4 1999/04/29 05:34:22 neeri
// % Support stat/fstat
// %
// % Revision 1.3 1999/03/17 09:05:10 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.2 1998/11/22 23:06:59 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.1 1998/08/01 21:32:09 neeri
// % About ready for 2.0a1
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Null device}
//
// A [[GUSINullSocket]] implements the null socket class for MacTCP. All instances
// of [[GUSINullSocket]] are created by the [[GUSINullDevice]] singleton, so
// there is no point in exporting the class itself.
//
// <GUSINull.h>=
#ifndef _GUSINull_
#define _GUSINull_
#ifdef GUSI_INTERNAL
#include "GUSIDevice.h"
// \section{Definition of [[GUSINullDevice]]}
//
// [[GUSINullDevice]] is a singleton subclass of [[GUSIDevice]].
//
// <Definition of class [[GUSINullDevice]]>=
class GUSINullDevice : public GUSIDevice {
public:
static GUSINullDevice * Instance();
virtual bool Want(GUSIFileToken & file);
virtual GUSISocket * open(GUSIFileToken & file, int flags);
virtual int stat(GUSIFileToken & file, struct stat * buf);
GUSISocket * open();
protected:
GUSINullDevice() {}
static GUSINullDevice * sInstance;
};
// <Inline member functions for class [[GUSINullDevice]]>=
inline GUSINullDevice * GUSINullDevice::Instance()
{
if (!sInstance)
sInstance = new GUSINullDevice;
return sInstance;
}
#endif /* GUSI_INTERNAL */
#endif /* _GUSINull_ */

71
GUSI/include/GUSIOTInet.h Executable file
View File

@ -0,0 +1,71 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIOpenTransport.nw- OpenTransport sockets
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.11 2001/01/17 08:54:12 neeri
// % Add Clone() implementations
// %
// % Revision 1.10 2000/06/12 04:20:59 neeri
// % Introduce GUSI_*printf
// %
// % Revision 1.9 2000/05/23 09:05:27 neeri
// % Improve formatting
// %
// % Revision 1.8 1999/09/26 03:57:12 neeri
// % Renamed broadcast option
// %
// % Revision 1.7 1999/09/09 07:20:29 neeri
// % Fix numerous bugs, add support for interface ioctls
// %
// % Revision 1.6 1999/08/26 05:45:06 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.5 1999/08/02 07:02:45 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.4 1999/05/29 06:26:44 neeri
// % Fixed header guards
// %
// % Revision 1.3 1999/04/14 04:21:19 neeri
// % Correct option sizes
// %
// % Revision 1.2 1999/04/10 05:17:51 neeri
// % Implement broadcast/multicast options
// %
// % Revision 1.1 1999/03/17 09:05:10 neeri
// % Added GUSITimer, expanded docs
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Open Transport TCP/IP sockets}
//
// For TCP and UDP, the strategy classes do most of the work, the derived socket
// classes only have to do option management.
//
// <GUSIOTInet.h>=
#ifndef _GUSIOTInet_
#define _GUSIOTInet_
#ifdef GUSI_SOURCE
#include <sys/cdefs.h>
__BEGIN_DECLS
// \section{Definition of Open Transport Internet hooks}
//
//
// <Definition of [[GUSIwithOTInetSockets]]>=
void GUSIwithOTInetSockets();
void GUSIwithOTTcpSockets();
void GUSIwithOTUdpSockets();
__END_DECLS
#endif /* GUSI_SOURCE */
#endif /* _GUSIOTInet_ */

93
GUSI/include/GUSIOTNetDB.h Executable file
View File

@ -0,0 +1,93 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIOTNetDB.nw - Open Transport DNS lookups
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.8 2000/06/12 04:20:59 neeri
// % Introduce GUSI_*printf
// %
// % Revision 1.7 2000/05/23 07:11:45 neeri
// % Improve formatting, handle failed lookups correctly
// %
// % Revision 1.6 2000/03/06 06:10:01 neeri
// % Reorganize Yield()
// %
// % Revision 1.5 1999/12/14 06:27:47 neeri
// % initialize OT before opening resolver
// %
// % Revision 1.4 1999/08/26 05:45:06 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.3 1999/06/30 07:42:06 neeri
// % Getting ready to release 2.0b3
// %
// % Revision 1.2 1999/05/30 03:09:31 neeri
// % Added support for MPW compilers
// %
// % Revision 1.1 1999/03/17 09:05:10 neeri
// % Added GUSITimer, expanded docs
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{IP Name Lookup in Open Transport}
//
//
// <GUSIOTNetDB.h>=
#ifndef _GUSIOTNetDB_
#define _GUSIOTNetDB_
#ifdef GUSI_INTERNAL
#include "GUSINetDB.h"
#include "GUSIContext.h"
#include "GUSIOpenTransport.h"
// \section{Definition of [[GUSIOTNetDB]]}
//
// We don't want to open the Open Transport headers files in our public header, but we
// need [[InetSvcRef]].
//
// <Name dropping for file GUSIOTNetDB>=
class TInternetServices;
typedef TInternetServices* InetSvcRef;
// <Definition of class [[GUSIOTNetDB]]>=
class GUSIOTNetDB : public GUSINetDB {
public:
static void Instantiate();
bool Resolver();
// <Overridden member functions for [[GUSIOTNetDB]]>=
virtual hostent * gethostbyname(const char * name);
// <Overridden member functions for [[GUSIOTNetDB]]>=
virtual hostent * gethostbyaddr(const void * addr, size_t len, int type);
// <Overridden member functions for [[GUSIOTNetDB]]>=
virtual char * inet_ntoa(in_addr inaddr);
// <Overridden member functions for [[GUSIOTNetDB]]>=
virtual long gethostid();
private:
GUSISpecificData<GUSIhostent, GUSIKillHostEnt> fHost;
// \section{Implementation of [[GUSIOTNetDB]]}
//
//
// <Privatissima of [[GUSIOTNetDB]]>=
GUSIOTNetDB();
// The [[GUSIOTNetDB]] notifier operates similarly to the [[GUSIOTSocket]] notifier,
// but it has to get the context to wake up somehow from its parameters.
//
// <Privatissima of [[GUSIOTNetDB]]>=
uint16_t fEvent;
uint32_t fCompletion;
OSStatus fAsyncError;
InetSvcRef fSvc;
GUSIContext * fCreationContext;
friend pascal void GUSIOTNetDBNotify(GUSIOTNetDB *, OTEventCode, OTResult, void *);
};
#endif /* GUSI_INTERNAL */
#endif /* _GUSIOTNetDB_ */

422
GUSI/include/GUSIOpenTransport.h Executable file
View File

@ -0,0 +1,422 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIOpenTransport.nw- OpenTransport sockets
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.18 2001/01/17 08:58:06 neeri
// % Releasing 2.1.4
// %
// % Revision 1.17 2000/10/16 04:07:23 neeri
// % Fix accept code
// %
// % Revision 1.16 2000/06/01 06:31:10 neeri
// % Reset shutdown flags on connect, refine test for data available, fix memory leak in UDP sendto
// %
// % Revision 1.15 2000/05/23 07:13:19 neeri
// % Improve formatting, implement immediate close and sorrect linger handling
// %
// % Revision 1.14 2000/03/15 07:19:53 neeri
// % Fix numerous race conditions
// %
// % Revision 1.13 2000/03/06 06:10:01 neeri
// % Reorganize Yield()
// %
// % Revision 1.12 1999/12/14 06:28:29 neeri
// % Read pending data while closing
// %
// % Revision 1.11 1999/12/13 02:44:19 neeri
// % Fix SO_LINGER, read results for disconnected sockets
// %
// % Revision 1.10 1999/10/15 02:48:50 neeri
// % Make disconnects orderly
// %
// % Revision 1.9 1999/09/09 07:20:29 neeri
// % Fix numerous bugs, add support for interface ioctls
// %
// % Revision 1.8 1999/09/03 06:31:36 neeri
// % Needed more mopups
// %
// % Revision 1.7 1999/08/26 05:43:09 neeri
// % Supply missing Unbind
// %
// % Revision 1.6 1999/08/02 07:02:45 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.5 1999/07/19 06:17:44 neeri
// % Fix nonblocking connect
// %
// % Revision 1.4 1999/06/28 06:04:59 neeri
// % Support interrupted calls
// %
// % Revision 1.3 1999/05/30 03:06:41 neeri
// % MPW compiler compatibility, fix select for datagram sockets
// %
// % Revision 1.2 1999/04/29 05:33:19 neeri
// % Fix fcntl prototype
// %
// % Revision 1.1 1999/03/17 09:05:11 neeri
// % Added GUSITimer, expanded docs
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Open Transport socket infrastructure}
//
// A [[GUSIOTSocket]] defines a class of Open Transport sockets. Since most
// families differ only in a few details, like address representation, we
// abstract the typical differences in a strategy class [[GUSIOTStrategy]].
//
// <GUSIOpenTransport.h>=
#ifndef _GUSIOpenTransport_
#define _GUSIOpenTransport_
#ifdef GUSI_INTERNAL
#include "GUSISocket.h"
#include "GUSISocketMixins.h"
#include "GUSIFactory.h"
#include <netinet/in.h>
#include <netinet/tcp.h>
#undef O_ASYNC
#undef O_NDELAY
#undef O_NONBLOCK
#undef SIGHUP
#undef SIGURG
#undef AF_INET
#undef TCP_KEEPALIVE
#undef TCP_NODELAY
#undef TCP_MAXSEG
#include <OpenTransport.h>
#include <OpenTptInternet.h>
// \section{Definition of [[GUSIOTStrategy]]}
//
// A [[GUSIOTStrategy]] contains all the tricky parts of each Open Transport
// family.
//
// <Definition of class [[GUSIOTStrategy]]>=
class GUSIOTStrategy {
public:
// [[CreateConfiguration]] creates an appropriate [[OTConfiguration]]. This
// method is not virtual, as it relies on the strategy method
// [[ConfigPath]].
//
// <Strategic interfaces for [[GUSIOTStrategy]]>=
OTConfiguration * CreateConfiguration();
// [[PackAddress]] converts a socket address into an OT address, and
// [[UnpackAddress]] performs the reverse step. [[CopyAddress]] copies an address.
//
// <Strategic interfaces for [[GUSIOTStrategy]]>=
virtual int PackAddress(
const void * address, socklen_t len, TNetbuf & addr, bool non_null = false) = 0;
virtual int UnpackAddress(const TNetbuf & addr, void * address, socklen_t * len) = 0;
virtual int CopyAddress(const TNetbuf & from, TNetbuf & to);
// [[EndpointInfo]] returns a data structure storing endpoint parameters. We only
// need one copy per socket type.
//
// <Strategic interfaces for [[GUSIOTStrategy]]>=
TEndpointInfo * EndpointInfo() { return &fEndpointInfo; }
protected:
// <Privatissima of [[GUSIOTStrategy]]>=
virtual const char * ConfigPath() = 0;
// <Privatissima of [[GUSIOTStrategy]]>=
TEndpointInfo fEndpointInfo;
// \section{Implementation of [[GUSIOTStrategy]]}
//
// [[GUSIOTStrategy]] is mostly abstract, except for the [[CreateConfiguration]]
// and [[CopyAddress]] methods.
//
// <Privatissima of [[GUSIOTStrategy]]>=
OTConfiguration * fConfig;
GUSIOTStrategy() : fConfig(nil) {}
virtual ~GUSIOTStrategy();
};
// \section{Definition of [[GUSIOTFactory]] and descendants}
//
// A [[GUSIOTFactory]] is an abstract class combining a socket creation
// mechanism with a strategy instance. To clarify our intent, we isolate
// the latter in [[GUSIOTStrategy]].
//
// <Definition of class [[GUSIOTFactory]]>=
class GUSIOTFactory : public GUSISocketFactory {
public:
static bool Initialize();
protected:
virtual GUSIOTStrategy *Strategy(int domain, int type, int protocol) = 0;
private:
// \section{Implementation of [[GUSIOTFactory]] and descendants}
//
//
// <Privatissima of [[GUSIOTFactory]]>=
static bool sOK;
};
// <Definition of class [[GUSIOTStreamFactory]]>=
class GUSIOTStreamFactory : public GUSIOTFactory {
public:
GUSISocket * socket(int domain, int type, int protocol);
};
// <Definition of class [[GUSIOTDatagramFactory]]>=
class GUSIOTDatagramFactory : public GUSIOTFactory {
public:
GUSISocket * socket(int domain, int type, int protocol);
};
// \section{Definition of [[GUSIOT]]}
//
// Open Transport allocates and deallocates many data structures, which we
// simplify with a smart template. Allocation works via class allocation
// operators, which is a bit weird admittedly.
//
// <Definition of template [[GUSIOT]]>=
template <class T, int tag> class GUSIOT : public T {
public:
void * operator new(size_t, EndpointRef ref)
{ OSStatus err; return OTAlloc(ref, tag, T_ALL, &err); }
void * operator new(size_t, EndpointRef ref, int fields)
{ OSStatus err; return OTAlloc(ref, tag, fields, &err); }
void operator delete(void * o)
{ if (o) OTFree(o, tag); }
};
template <class T, int tag> class GUSIOTAddr : public GUSIOT<T, tag> {
public:
int Pack(GUSIOTStrategy * strategy, const void * address, socklen_t len, bool non_null=false)
{ return strategy->PackAddress(address, len, addr, non_null); }
int Unpack(GUSIOTStrategy * strategy, void * address, socklen_t * len)
{ return strategy->UnpackAddress(addr, address, len); }
int Copy(GUSIOTStrategy * strategy, GUSIOTAddr<T, tag> * to)
{ return strategy->CopyAddress(addr, to->addr); }
};
typedef GUSIOTAddr<TBind, T_BIND> GUSIOTTBind;
typedef GUSIOTAddr<TCall, T_CALL> GUSIOTTCall;
typedef GUSIOTAddr<TUnitData, T_UNITDATA> GUSIOTTUnitData;
typedef GUSIOTAddr<TUDErr, T_UDERROR> GUSIOTTUDErr;
typedef GUSIOT<TDiscon, T_DIS> GUSIOTTDiscon;
typedef GUSIOT<TOptMgmt, T_OPTMGMT> GUSIOTTOptMgmt;
// \section{Definition of [[GUSIOTSocket]] and descendants}
//
// Open Transport sockets are rather lightweight, since OT is rather similar
// to sockets already.
//
// <Definition of class [[GUSIOTSocket]]>=
class GUSIOTSocket :
public GUSISocket,
protected GUSISMBlocking,
protected GUSISMState,
protected GUSISMAsyncError
{
public:
// <Overridden member functions for [[GUSIOTSocket]]>=
virtual int bind(void * name, socklen_t namelen);
// [[getsockname]] and [[getpeername]] unpack the stored addresses.
// Note that the reaction to [[nil]] addresses is a bit different.
//
// <Overridden member functions for [[GUSIOTSocket]]>=
virtual int getsockname(void * name, socklen_t * namelen);
// [[shutdown]] just delegates to [[GUSISMState]].
//
// <Overridden member functions for [[GUSIOTSocket]]>=
virtual int shutdown(int how);
// [[fcntl]] handles the blocking support.
//
// <Overridden member functions for [[GUSIOTSocket]]>=
virtual int fcntl(int cmd, va_list arg);
// [[ioctl]] deals with blocking support and with [[FIONREAD]].
//
// <Overridden member functions for [[GUSIOTSocket]]>=
virtual int ioctl(unsigned int request, va_list arg);
// [[getsockopt]] and [[setsockopt]] are available for a variety of options.
//
// <Overridden member functions for [[GUSIOTSocket]]>=
virtual int getsockopt(int level, int optname, void *optval, socklen_t * optlen);
// <Overridden member functions for [[GUSIOTSocket]]>=
virtual int setsockopt(int level, int optname, void *optval, socklen_t optlen);
// Open Transport sockets implement socket style calls.
//
// <Overridden member functions for [[GUSIOTSocket]]>=
virtual bool Supports(ConfigOption config);
protected:
GUSIOTSocket(GUSIOTStrategy * strategy);
// \section{Implementation of [[GUSIOTSocket]]}
//
// Open Transport may call this routine for dozens and dozens of different
// reasons. Pretty much every call results in a wakeup of the threads attached
// to the socket. We save some of the more interesting events in bitsets.
// in [[MopupEvents]].
//
// <Privatissima of [[GUSIOTSocket]]>=
uint16_t fNewEvent;
uint16_t fCurEvent;
uint16_t fEvent;
uint32_t fNewCompletion;
uint32_t fCurCompletion;
uint32_t fCompletion;
friend pascal void GUSIOTNotify(GUSIOTSocket *, OTEventCode, OTResult, void *);
// To avoid race conditions with the notifier, we sometimes need a lock.
//
// <Privatissima of [[GUSIOTSocket]]>=
class Lock {
public:
Lock(EndpointRef end) : fEndpoint(end) { OTEnterNotifier(fEndpoint); }
~Lock() { OTLeaveNotifier(fEndpoint); }
private:
EndpointRef fEndpoint;
};
// For some events, we have to take a followup action at a more convenient time.
//
// <Privatissima of [[GUSIOTSocket]]>=
virtual void MopupEvents();
// [[GUSIOTSocket]] creates an asynchronous endpoint for the appropriate
// provider.
//
// <Privatissima of [[GUSIOTSocket]]>=
GUSIOTStrategy * fStrategy;
EndpointRef fEndpoint;
linger fLinger;
UInt32 fDeadline;
// The destructor tears down the connection as gracefully as possible. It also respects
// the linger settings.
//
// <Privatissima of [[GUSIOTSocket]]>=
virtual void close();
virtual ~GUSIOTSocket();
// [[Clone]] creates another socket of the same class.
//
// <Privatissima of [[GUSIOTSocket]]>=
virtual GUSIOTSocket * Clone() = 0;
// At the time the socket function [[bind]] is called, we are not really ready
// yet to call [[OTBind]], but if we don't call it, we can't report whether the
// address was free.
//
// <Privatissima of [[GUSIOTSocket]]>=
GUSIOTTBind * fSockName;
int BindToAddress(GUSIOTTBind * addr);
// Open Transport takes unbinding a lot more serious than MacTCP.
//
// <Privatissima of [[GUSIOTSocket]]>=
void Unbind();
friend class GUSIOTStreamSocket;
friend class GUSIOTDatagramSocket;
};
// <Definition of class [[GUSIOTStreamSocket]]>=
class GUSIOTStreamSocket : public GUSIOTSocket {
public:
// [[Clone]] creates another socket of the same class.
//
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual GUSIOTSocket * Clone();
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual void close();
virtual bool Close(UInt32 now);
~GUSIOTStreamSocket();
// Stream sockets include a mopup action for connect and disconnect.
//
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual void MopupEvents();
// [[listen]] is a bit embarassing, because we already committed ourselves
// to a queue length of [[0]], so we have to unbind and rebind ourselves.
//
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual int listen(int qlen);
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual int getpeername(void * name, socklen_t * namelen);
// [[accept]] may become quite complex, because connections could nest. The
// listening socket calls [[OTListen]], queues candidates by their
// [[fNextListener]] field, and then trys calling [[OTAccept]] on the first
// candidate.
//
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual GUSISocket * accept(void * address, socklen_t * addrlen);
// [[connect]] is comparatively simple.
//
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual int connect(void * address, socklen_t addrlen);
// Data transfer is simple as well. Here is the version for stream protocols.
//
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual ssize_t recvfrom(const GUSIScatterer & buffer, int flags, void * from, socklen_t * fromlen);
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual ssize_t sendto(const GUSIGatherer & buffer, int flags, const void * to, socklen_t tolen);
// [[select]] for stream sockets intermingles data information and connection
// information as usual.
//
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual bool select(bool * canRead, bool * canWrite, bool * except);
// [[shutdown]] for stream sockets has to send an orderly disconnect.
//
// <Overridden member functions for [[GUSIOTStreamSocket]]>=
virtual int shutdown(int how);
protected:
GUSIOTStreamSocket(GUSIOTStrategy * strategy);
// Since all we need to know is in the [[GUSIOTStrategy]], it often suffices
// simply to create a [[GUSIOTSocket]]. Stream and datagram sockets differ
// merely in the descendant they create.
//
// <Privatissima of [[GUSIOTStreamSocket]]>=
friend class GUSIOTStreamFactory;
// <Privatissima of [[GUSIOTStreamSocket]]>=
friend pascal void GUSIOTNotify(GUSIOTSocket *, OTEventCode, OTResult, void *);
// The peer address for a [[GUSIOTStreamSocket]] is stored in a [[GUSIOTTCall]]
// structure.
//
// <Privatissima of [[GUSIOTStreamSocket]]>=
GUSIOTTCall * fPeerName;
// <Privatissima of [[GUSIOTStreamSocket]]>=
GUSIOTStreamSocket * fNextListener;
};
// <Definition of class [[GUSIOTDatagramSocket]]>=
class GUSIOTDatagramSocket : public GUSIOTSocket {
public:
// [[Clone]] creates another socket of the same class.
//
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
virtual GUSIOTSocket * Clone();
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
~GUSIOTDatagramSocket();
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
virtual int getpeername(void * name, socklen_t * namelen);
// A datagram socket can [[connect]] as many times as it wants.
//
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
virtual int connect(void * address, socklen_t addrlen);
// Datagram protocols use slightly different calls for data transfers.
//
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
virtual ssize_t recvfrom(const GUSIScatterer & buffer, int flags, void * from, socklen_t * fromlen);
// [[sendto]] needs either a valid [[to]] address or a stored peer address set by
// [[connect]].
//
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
virtual ssize_t sendto(const GUSIGatherer & buffer, int flags, const void * to, socklen_t tolen);
// [[select]] for datagram sockets returns data information only.
//
// <Overridden member functions for [[GUSIOTDatagramSocket]]>=
virtual bool select(bool * canRead, bool * canWrite, bool * except);
protected:
GUSIOTDatagramSocket(GUSIOTStrategy * strategy);
// <Privatissima of [[GUSIOTDatagramSocket]]>=
friend class GUSIOTDatagramFactory;
// Datagram sockets might be bound at rather arbitrary times.
//
// <Privatissima of [[GUSIOTDatagramSocket]]>=
int BindIfUnbound();
// The peer address for a [[GUSIOTDatagramSocket]] is stored in a [[GUSIOTTBind]]
// structure.
//
// <Privatissima of [[GUSIOTDatagramSocket]]>=
GUSIOTTBind * fPeerName;
};
#endif /* GUSI_INTERNAL */
#endif /* _GUSIOpenTransport_ */

115
GUSI/include/GUSIPOSIX.h Executable file
View File

@ -0,0 +1,115 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIPOSIX.nw - POSIX/Socket wrappers
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.22 2001/01/17 08:58:06 neeri
// % Releasing 2.1.4
// %
// % Revision 1.21 2000/10/29 18:36:32 neeri
// % Fix time_t signedness issues
// %
// % Revision 1.20 2000/10/16 04:34:23 neeri
// % Releasing 2.1.2
// %
// % Revision 1.19 2000/06/12 04:24:50 neeri
// % Fix time, localtime, gmtime
// %
// % Revision 1.18 2000/05/23 07:15:30 neeri
// % Improve formatting
// %
// % Revision 1.17 2000/03/06 08:18:25 neeri
// % Fix sleep, usleep, chdir; new Yield system
// %
// % Revision 1.16 2000/01/17 01:41:21 neeri
// % Fix rename() mangling
// %
// % Revision 1.15 1999/12/13 03:01:48 neeri
// % Another select() fix
// %
// % Revision 1.14 1999/11/15 07:22:34 neeri
// % Safe context setup. Fix sleep checking.
// %
// % Revision 1.13 1999/09/09 07:21:22 neeri
// % Add support for inet_aton
// %
// % Revision 1.12 1999/08/26 05:45:06 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.11 1999/07/19 06:21:03 neeri
// % Add mkdir/rmdir, fix various file manager related bugs
// %
// % Revision 1.10 1999/07/07 04:17:42 neeri
// % Final tweaks for 2.0b3
// %
// % Revision 1.9 1999/06/28 06:04:59 neeri
// % Support interrupted calls
// %
// % Revision 1.8 1999/05/30 03:09:31 neeri
// % Added support for MPW compilers
// %
// % Revision 1.7 1999/04/29 05:33:18 neeri
// % Fix fcntl prototype
// %
// % Revision 1.6 1999/03/29 09:51:29 neeri
// % New configuration system with support for hardcoded configurations.
// %
// % Revision 1.5 1999/03/17 09:05:11 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.4 1998/10/25 11:35:19 neeri
// % chdir, getcwd, setxxxent
// %
// % Revision 1.3 1998/10/11 16:45:22 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.2 1998/08/01 21:32:09 neeri
// % About ready for 2.0a1
// %
// % Revision 1.1 1998/01/25 21:02:49 neeri
// % Engine implemented, except for signals & scheduling
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{POSIX/Socket Wrappers}
//
// Now everything is in place to define the POSIX and socket routines
// themselves. As opposed to our usual practice, we don't declare the
// exported routines here, as they all have been declared in [[unistd.h]]
// or [[sys/socket.h]] already. The exceptions are [[remove]] and [[rename]],
// which are declared in [[stdio.h]], which we'd rather not include, and
// various calls which are not consistently declared.
//
// <GUSIPOSIX.h>=
#ifndef _GUSIPOSIX_
#define _GUSIPOSIX_
#include <signal.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <utime.h>
#include <netdb.h>
#include <arpa/inet.h>
__BEGIN_DECLS
int remove(const char * path);
int rename(const char *oldname, const char *newname);
int fgetfileinfo(const char * path, OSType * creator, OSType * type);
void fsetfileinfo(const char * path, OSType creator, OSType type);
time_t time(time_t * timer);
struct tm * localtime(const time_t * timer);
struct tm * gmtime(const time_t * timer);
time_t mktime(struct tm *timeptr);
__END_DECLS
#endif /* _GUSIPOSIX_ */

37
GUSI/include/GUSIPPC.h Executable file
View File

@ -0,0 +1,37 @@
// The [[GUSIPPCFactory]] singleton creates [[GUSIPPCSockets]].
//
// <GUSIPPC.h>=
#ifndef _GUSIPPC_
#define _GUSIPPC_
#ifdef GUSI_INTERNAL
#include "GUSISocket.h"
#include "GUSIFactory.h"
#include <sys/ppc.h>
// \section{Definition of [[GUSIPPCFactory]]}
//
// [[GUSIPPCFactory]] is a singleton subclass of [[GUSISocketFactory]].
//
// <Definition of class [[GUSIPPCFactory]]>=
class GUSIPPCFactory : public GUSISocketFactory {
public:
static GUSISocketFactory * Instance();
virtual GUSISocket * socket(int domain, int type, int protocol);
private:
GUSIPPCFactory() {}
static GUSISocketFactory * sInstance;
};
// <Inline member functions for class [[GUSIPPCFactory]]>=
inline GUSISocketFactory * GUSIPPCFactory::Instance()
{
if (!sInstance)
sInstance = new GUSIPPCFactory;
return sInstance;
}
#endif /* GUSI_INTERNAL */
#endif /* _GUSIPPC_ */

30
GUSI/include/GUSIPThread.h Executable file
View File

@ -0,0 +1,30 @@
// <GUSIPThread.h>=
#ifndef _GUSIPThread_
#define _GUSIPThread_
#include "GUSISpecific.h"
#include "GUSIContext.h"
#include "GUSIContextQueue.h"
#include <pthread.h>
// <Implementation of Pthread data types>=
struct GUSIPThread : public GUSIContext {
private:
GUSIPThread() : GUSIContext(0) {} // Never called
};
// <Implementation of Pthread data types>=
struct GUSIPThreadKey : public GUSISpecific {
GUSIPThreadKey(GUSIPThreadKeyDestructor destructor) : GUSISpecific(destructor) {}
};
// <Implementation of Pthread data types>=
struct GUSIPThreadMutex : public GUSIContextQueue {
bool fPolling;
GUSIPThreadMutex() : fPolling(false) {}
};
// <Implementation of Pthread data types>=
struct GUSIPThreadCond : public GUSIContextQueue {
};
#endif /* _GUSIPThread_ */

88
GUSI/include/GUSIPipe.h Executable file
View File

@ -0,0 +1,88 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIPipe.nw - Pipes
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.12 2000/05/23 07:18:03 neeri
// % Improve formatting
// %
// % Revision 1.11 2000/03/06 06:09:59 neeri
// % Reorganize Yield()
// %
// % Revision 1.10 1999/11/15 07:20:59 neeri
// % Add GUSIwithLocalSockets
// %
// % Revision 1.9 1999/08/26 05:45:07 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.8 1999/06/28 06:05:00 neeri
// % Support interrupted calls
// %
// % Revision 1.7 1999/05/29 06:26:45 neeri
// % Fixed header guards
// %
// % Revision 1.6 1999/03/17 09:05:12 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.5 1998/11/22 23:07:00 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.4 1998/10/25 11:57:38 neeri
// % Ready to release 2.0a3
// %
// % Revision 1.3 1998/01/25 20:53:57 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.2 1996/12/22 19:57:58 neeri
// % TCP streams work
// %
// % Revision 1.1 1996/11/24 12:52:08 neeri
// % Added GUSIPipeSockets
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{The GUSI Pipe Socket Class}
//
// Pipes and socket pairs are implemented with the [[GUSIPipeSocket]] class.
// The [[GUSIPipeFactory]] singleton creates pairs of [[GUSIPipeSockets]].
//
// <GUSIPipe.h>=
#ifndef _GUSIPipe_
#define _GUSIPipe_
#ifdef GUSI_INTERNAL
#include "GUSISocket.h"
#include "GUSIFactory.h"
// \section{Definition of [[GUSIPipeFactory]]}
//
// [[GUSIPipeFactory]] is a singleton subclass of [[GUSISocketFactory]].
//
// <Definition of class [[GUSIPipeFactory]]>=
class GUSIPipeFactory : public GUSISocketFactory {
public:
static GUSISocketFactory * Instance();
virtual GUSISocket * socket(int domain, int type, int protocol);
virtual int socketpair(int domain, int type, int protocol, GUSISocket * s[2]);
private:
GUSIPipeFactory() {}
static GUSISocketFactory * sInstance;
};
// <Inline member functions for class [[GUSIPipeFactory]]>=
inline GUSISocketFactory * GUSIPipeFactory::Instance()
{
if (!sInstance)
sInstance = new GUSIPipeFactory;
return sInstance;
}
#endif /* GUSI_INTERNAL */
#endif /* _GUSIPipe_ */

48
GUSI/include/GUSISIOUX.h Executable file
View File

@ -0,0 +1,48 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSISIOUX.nw - SIOUX Support
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.8 2000/05/23 07:18:03 neeri
// % Improve formatting
// %
// % Revision 1.7 2000/03/06 06:03:29 neeri
// % Check device families for file paths
// %
// % Revision 1.6 1999/08/26 05:45:08 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.5 1999/06/08 04:31:30 neeri
// % Getting ready for 2.0b2
// %
// % Revision 1.4 1999/05/29 06:26:45 neeri
// % Fixed header guards
// %
// % Revision 1.3 1999/03/17 09:05:12 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.2 1998/11/22 23:07:01 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.1 1998/10/25 11:57:39 neeri
// % Ready to release 2.0a3
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{SIOUX Support}
//
// To combine GUSI with SIOUX, terminal I/O needs to interface with the SIOUX
// event handling.
//
// SIOUX support is installed implicitly through [[GUSISetupConsoleDescriptors]]
//
// <GUSISIOUX.h>=
#ifndef _GUSISIOUX_
#define _GUSISIOUX_
#endif /* _GUSISIOUX_ */

27
GUSI/include/GUSISIOW.h Executable file
View File

@ -0,0 +1,27 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSISIOW.nw - SIOW Interface
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.2 1999/08/26 05:45:08 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.1 1999/07/19 06:17:08 neeri
// % Add SIOW support
// %
//
// \chapter{SIOW Support}
//
// SIOW support is based on MPW support, adding a few event hooks so update and activate events
// get handled during blocking calls. SIOW support is installed implecitly through [[GUSIDefaultSetupConsole]].
//
// <GUSISIOW.h>=
#ifndef _GUSISIOW_
#define _GUSISIOW_
#endif /* _GUSISIOW_ */

149
GUSI/include/GUSISignal.h Executable file
View File

@ -0,0 +1,149 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSISignal.nw - Signal engine
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.7 2000/10/16 04:08:51 neeri
// % Add binary compatibility for CW SIGINT
// %
// % Revision 1.6 2000/05/23 07:18:03 neeri
// % Improve formatting
// %
// % Revision 1.5 2000/03/15 07:22:07 neeri
// % Enforce alignment choices
// %
// % Revision 1.4 1999/12/13 03:07:25 neeri
// % Releasing 2.0.2
// %
// % Revision 1.3 1999/11/15 07:20:18 neeri
// % Safe context setup
// %
// % Revision 1.2 1999/08/26 05:45:09 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.1 1999/06/30 07:42:07 neeri
// % Getting ready to release 2.0b3
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Signal support}
//
// We support signals in the half assed way characteristic for GUSI's approach to
// asynchronous issues: Delivery is very much synchronous, basically within [[Yield]]
// calls. Signal handling behavior is encapsulated in the classes [[GUSISigContext]] and
// [[GUSISigProcess]] whose instances are manufactured by a [[GUSISigFactory]].
//
// <GUSISignal.h>=
#ifndef _GUSISIGNAL_
#define _GUSISIGNAL_
#include <signal.h>
#ifdef GUSI_SOURCE
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of the signal handling engine}
//
// A [[GUSISigProcess]] contains the per-process signal state. [[GetAction]] and [[SetAction]] manipulate the
// action associated with a signal, [[Pending]] returns the set of pending signals, [[Post]] marks a signal
// as pending (but possibly blocked), and [[Raise]] executes a signal (which we have determined is not
// blocked).
//
// <Definition of class [[GUSISigProcess]]>=
class GUSISigContext;
class GUSISigProcess {
public:
virtual struct sigaction & GetAction(int sig);
virtual int SetAction(int sig, const struct sigaction & act);
virtual sigset_t Pending() const;
virtual void ClearPending(sigset_t clear);
virtual void Post(int sig);
virtual bool Raise(int sig, GUSISigContext * context);
virtual ~GUSISigProcess();
protected:
// [[GUSISigProcess]] stores the signal handlers and the set of signals pending against the process.
//
// <Privatissima of [[GUSISigProcess]]>=
sigset_t fPending;
struct sigaction fAction[NSIG-1];
// Some actions can't be caught and/or ignored. [[CantCatch]] and [[CantIgnore]] report those.
//
// <Privatissima of [[GUSISigProcess]]>=
virtual bool CantCatch(int sig);
virtual bool CantIgnore(int sig);
// The default behavior for many signals is to abort the process.
//
// <Privatissima of [[GUSISigProcess]]>=
virtual bool DefaultAction(int sig, const struct sigaction & act);
friend class GUSISigFactory;
GUSISigProcess();
};
// A [[GUSISigContext]] contains the per-thread signal state, primarily blocking info. To support
// [[pthread_kill]], we have out own set of pending signals. [[GetBlocked]] and [[SetBlocked]] manipulate
// the set of blocking signals, [[Pending]] returns the set of pending signals, [[Post]] marks a
// signal as pending (but possibly blocked), and [[Raise]] executes all eligible signals.
//
// <Definition of class [[GUSISigContext]]>=
class GUSISigContext {
public:
virtual sigset_t GetBlocked() const;
virtual void SetBlocked(sigset_t sigs);
virtual sigset_t Pending() const;
virtual sigset_t Pending(GUSISigProcess * proc) const;
virtual void ClearPending(sigset_t clear);
virtual void Post(int sig);
virtual sigset_t Ready(GUSISigProcess * proc);
virtual bool Raise(GUSISigProcess * proc, bool allSigs = false);
virtual ~GUSISigContext();
protected:
// [[GUSISigContext]] mainly deals with a set of blocked signals, which it inherits from its parent.
//
// <Privatissima of [[GUSISigContext]]>=
sigset_t fPending;
sigset_t fBlocked;
// Many signals cannot be blocked. [[CantBlock]] defines those.
//
// <Privatissima of [[GUSISigContext]]>=
virtual sigset_t CantBlock();
friend class GUSISigFactory;
GUSISigContext(const GUSISigContext * parent);
};
// The [[GUSISigFactory]] singleton creates the above two classes, allowing a future extension to
// handle more signals.
//
// <Definition of class [[GUSISigFactory]]>=
class GUSISigFactory {
public:
virtual GUSISigProcess * CreateSigProcess();
virtual GUSISigContext * CreateSigContext(const GUSISigContext * parent);
virtual ~GUSISigFactory();
static GUSISigFactory * Instance();
static void SetInstance(GUSISigFactory * instance);
protected:
GUSISigFactory() {}
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
#endif
#endif /* _GUSISIGNAL_ */

362
GUSI/include/GUSISocket.h Executable file
View File

@ -0,0 +1,362 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSISocket.nw - The socket class
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:14 chombier
// % Initial import
// %
// % Revision 1.18 2000/10/16 04:34:23 neeri
// % Releasing 2.1.2
// %
// % Revision 1.17 2000/05/23 07:19:34 neeri
// % Improve formatting, add close queue
// %
// % Revision 1.16 2000/03/15 07:20:53 neeri
// % Add GUSISocket::AddContextInScope
// %
// % Revision 1.15 1999/10/15 02:48:51 neeri
// % Make disconnects orderly
// %
// % Revision 1.14 1999/09/26 03:59:26 neeri
// % Releasing 2.0fc1
// %
// % Revision 1.13 1999/08/26 05:45:09 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.12 1999/06/08 04:31:31 neeri
// % Getting ready for 2.0b2
// %
// % Revision 1.11 1999/05/29 06:26:45 neeri
// % Fixed header guards
// %
// % Revision 1.10 1999/04/29 05:33:18 neeri
// % Fix fcntl prototype
// %
// % Revision 1.9 1999/03/17 09:05:13 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.8 1998/11/22 23:07:01 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.7 1998/10/11 16:45:23 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.6 1998/08/01 21:29:53 neeri
// % Use context queues
// %
// % Revision 1.5 1998/01/25 20:53:58 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.4 1997/11/13 21:12:12 neeri
// % Fall 1997
// %
// % Revision 1.3 1996/11/24 13:00:28 neeri
// % Fix comment leaders
// %
// % Revision 1.2 1996/11/24 12:52:09 neeri
// % Added GUSIPipeSockets
// %
// % Revision 1.1.1.1 1996/11/03 02:43:32 neeri
// % Imported into CVS
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{The GUSI Socket Class}
//
// GUSI is constructed around the [[GUSISocket]] class. This class is
// mostly an abstract superclass, but all virtual procedures are implemented
// to return sensible error codes.
//
// <GUSISocket.h>=
#ifndef _GUSISocket_
#define _GUSISocket_
#ifdef GUSI_SOURCE
#include "GUSIBasics.h"
#include "GUSIContext.h"
#include "GUSIContextQueue.h"
#include "GUSIBuffer.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <stdarg.h>
#include <ConditionalMacros.h>
#include <LowMem.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of [[GUSISocket]]}
//
// [[GUSISocket]] consists of a few maintenance functions and the socket operations.
// Each operation consists to a POSIX/BSD function with the file descriptor operand
// left out.
//
// <Definition of class [[GUSISocket]]>=
class GUSISocket {
// Since a single [[GUSISocket]] may (through [[dup]]) be installed multiply
// in a descriptor table or even in multiple descriptor tables, [[GUSISocket]]s
// are not destroyed directly, but by manipulating a reference count. As soon
// as the reference count hits zero, the destructor (which, of course, should
// probably be overridden) is called.
//
// Since destructors cannot call virtual functions, we call [[close]] which
// eventually calls the destructor. Some socket types can take quite long to close
// under unfavorable circumstances. To speed up the process, we have the option of
// queueing the socket up and regularly having [[Close]] called on it.
//
// <Reference counting for [[GUSISocket]]>=
public:
void AddReference();
void RemoveReference();
virtual void close();
void CheckClose(UInt32 now = LMGetTicks());
protected:
GUSISocket();
virtual ~GUSISocket();
virtual bool Close(UInt32 now = LMGetTicks());
private:
u_long fRefCount;
// [[GUSIContext]]s are defined in {\tt GUSIBasics}. A context references all
// information you need in a completion procedure: The contents of [[A5]],
// the process ID, and thread information. [[Wakeup]] wakes up the threads
// and/or processes associated with the socket and is guaranteed to work even
// at interrupt level. [[AddContext]] adds another context. [[RemoveContext]]
// indicates that this context no longer should be woken up when something happens.
// To keep a context added inside a scope, declare an automatic object of class
// [[AddContextInScope]].
//
// <Context links for [[GUSISocket]]>=
public:
void Wakeup();
void AddContext(GUSIContext * context = nil);
void RemoveContext(GUSIContext * context = nil);
class AddContextInScope {
public:
AddContextInScope(GUSISocket * sock, GUSIContext * context = nil)
: fSocket(sock), fContext(context)
{ fSocket->AddContext(fContext); }
~AddContextInScope() { fSocket->RemoveContext(fContext); }
private:
GUSISocket * fSocket;
GUSIContext * fContext;
};
private:
GUSIContextQueue fContexts;
// There may be various reasons to keep sockets in queue. Currently the
// only reason is to queue up dying sockets.
//
// <Queue management for [[GUSISocket]]>=
public:
void Enqueue(GUSISocket ** queue);
void Dequeue();
private:
GUSISocket ** fQueue;
GUSISocket * fNextSocket;
GUSISocket * fPrevSocket;
// Both read and write calls on sockets come in five different variants:
//
// \begin{enumerate}
// \item [[read]] and [[write]]
// \item [[recv]] and [[send]]
// \item [[readv]] and [[writev]]
// \item [[recvfrom]] and [[sendto]]
// \item [[recvmsg]] and [[sendmsg]]
// \end{enumerate}
//
// GUSI initially maps variants 3 and 5 of these calls to the [[recvmsg]] and
// [[sendmsg]] member functions, variants 2 and 4 to the [[recvfrom]] and
// [[sendto]] member functions, and variant 1 to the [[read]] and
// [[write]] member functions.
//
// The simpler member functions can always be translated into the complex member
// functions, and under some circumstances, the opposite is also possible.
// To avoid translation loops, the translation routines (i.e., the default
// implementation of [[GUSISocket::read]] and [[GUSISocket::recvmsg]]
// check for the availablility of the other function by calling [[Supports]].
// This member function must be overridden for any reasonable socket class.
//
// <Configuration options for [[GUSISocket]]>=
protected:
enum ConfigOption {
kSimpleCalls, // [[read]], [[write]]
kSocketCalls, // [[recvfrom]], [[sendto]]
kMsgCalls // [[recvmsg]], [[sendmsg]]
};
virtual bool Supports(ConfigOption config);
public:
// Most sockets have names, which to [[GUSISocket]] are just opaque blocks of
// memory. A name for a socket is established (before the socket is actually
// used, of course) through [[bind]]. The name may be queried with
// [[getsockname]] and once the socket is connected, the name of the peer
// endpoint may be queried with [[getpeername]].
//
// <Socket name management for [[GUSISocket]]>=
virtual int bind(void * name, socklen_t namelen);
virtual int getsockname(void * name, socklen_t * namelen);
virtual int getpeername(void * name, socklen_t * namelen);
// Sockets follow either a virtual circuit model where all data is exchanged
// with the same peer throughout the lifetime of the connection, or a datagram
// model where potentially every message is exchanged with a different peer.
//
// The vast majority of protocols follow the virtual circuit model. The server
// end, typically after calling [[bind]] to attach the socket to a well known
// address, calls [[listen]] to establish its willingness to accept connections.
// [[listen]] takes a queue length parameter, which however is ignored for many
// types of sockets.
//
// Incoming connections are then accepted by calling [[accept]]. When [[accept]]
// is successful, it always returns a new [[GUSISocket]], while the original socket
// remains available for further connections. To avoid blocking on [[accept]], you may poll for connections with an
// [[accept()] call in nonblocking mode or query the result of [[select]] whether
// the socket is ready for reading.
//
// The client end in the virtual circuit model connects itself to the well known
// address by calling [[connect]]. To avoid blocking on [[connect]], you may
// call it in nonblocking mode and then query the result of [[select]] whether
// the socket is ready for writing.
//
// In the datagram model, you don't need to establish connections. You may call
// [[connect]] anyway to temporarily establish a virtual circuit.
//
// <Connection establishment for [[GUSISocket]]>=
virtual int listen(int qlen);
virtual GUSISocket * accept(void * address, socklen_t * addrlen);
virtual int connect(void * address, socklen_t addrlen);
// As mentioned before, there are three variants each for reading and writing.
// The socket variants provide a means to pass a peer address for the datagram
// model, while the msg variants also provides fields for passing access rights,
// which is, however not currently supported in GUSI. As syntactic sugar, the more
// traditional flavors with [[buffer]]/[[length]] buffers are also supported.
//
// <Sending and receiving data for [[GUSISocket]]>=
virtual ssize_t read(const GUSIScatterer & buffer);
virtual ssize_t write(const GUSIGatherer & buffer);
virtual ssize_t recvfrom(
const GUSIScatterer & buffer, int flags, void * from, socklen_t * fromlen);
virtual ssize_t sendto(
const GUSIGatherer & buffer, int flags, const void * to, socklen_t tolen);
virtual ssize_t recvmsg(msghdr * msg, int flags);
virtual ssize_t sendmsg(const msghdr * msg, int flags);
ssize_t read(void * buffer, size_t length);
ssize_t write(const void * buffer, size_t length);
ssize_t recvfrom(
void * buffer, size_t length, int flags, void * from, socklen_t * fromlen);
ssize_t sendto(
const void * buffer, size_t length, int flags, const void * to, socklen_t tolen);
// A multitude of parameters can be manipulated for a [[GUSISocket]] through
// the socket oriented calls [[getsockopt]], [[setsockopt]], the file oriented
// call [[fcntl]], and the device oriented call [[ioctl]].
//
// [[isatty]] returns whether the socket should be considered an interactive
// console.
//
// <Maintaining properties for [[GUSISocket]]>=
virtual int getsockopt(int level, int optname, void *optval, socklen_t * optlen);
virtual int setsockopt(int level, int optname, void *optval, socklen_t optlen);
virtual int fcntl(int cmd, va_list arg);
virtual int ioctl(unsigned int request, va_list arg);
virtual int isatty();
// Three of the operations make sense primarily for files, and most other socket
// types accept the default implementations. [[fstat]] returns information about
// an open file, [[lseek]] repositions the read/write pointer, and [[ftruncate]]
// cuts off an open file at a certain point.
//
// <File oriented operations for [[GUSISocket]]>=
virtual int fstat(struct stat * buf);
virtual off_t lseek(off_t offset, int whence);
virtual int ftruncate(off_t offset);
// [[select]] polls or waits for one of a group of [[GUSISocket]] to become
// ready for reading, writing, or for an exceptional condition to occur.
// First, [[pre_select]] is called once for all [[GUSISocket]]s in the group.
// It returns [[true]] is the socket will wake up as soon as one of the events
// occurs and [[false]] if GUSI needs to poll.
// Next, [[select]] is called for all [[GUSISocket]]s once or multiple times,
// until a condition becomes true or the call times out. Finally, [[post_select]]
// is called for all members of the group.
//
// <Multiplexing for [[GUSISocket]]>=
virtual bool pre_select(bool wantRead, bool wantWrite, bool wantExcept);
virtual bool select(bool * canRead, bool * canWrite, bool * exception);
virtual void post_select(bool wantRead, bool wantWrite, bool wantExcept);
// A socket connection is usually full duplex. By calling [[shutdown(1)]], you
// indicate that you won't write any more data on this socket. The values 0 (no
// more reads) and 2 (no more read/write) are used less frequently.
//
// <Miscellaneous operations for [[GUSISocket]]>=
virtual int shutdown(int how);
// Some socket types do not write out data immediately. Calling [[fsync]] guarantees
// that all data is written.
//
// <Miscellaneous operations for [[GUSISocket]]>=
virtual int fsync();
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// \section{Implementation of [[GUSISocket]]}
//
// \subsection{General socket management}
//
//
// <Inline member functions for class [[GUSISocket]]>=
inline void GUSISocket::AddReference()
{
++fRefCount;
}
inline void GUSISocket::RemoveReference()
{
if (!--fRefCount)
close();
}
// \subsection{Context management}
//
//
// <Inline member functions for class [[GUSISocket]]>=
inline void GUSISocket::Wakeup()
{
fContexts.Wakeup();
}
// The traditional flavors of the I/O calls are translated to the scatterer/gatherer
// variants.
//
// <Inline member functions for class [[GUSISocket]]>=
inline ssize_t GUSISocket::read(void * buffer, size_t length)
{
return read(GUSIScatterer(buffer, length));
}
inline ssize_t GUSISocket::write(const void * buffer, size_t length)
{
return write(GUSIGatherer(buffer, length));
}
inline ssize_t GUSISocket::recvfrom(
void * buffer, size_t length, int flags, void * from, socklen_t * fromlen)
{
return recvfrom(GUSIScatterer(buffer, length), flags, from, fromlen);
}
inline ssize_t GUSISocket::sendto(
const void * buffer, size_t length, int flags, const void * to, socklen_t tolen)
{
return sendto(GUSIGatherer(buffer, length), flags, to, tolen);
}
#endif /* GUSI_SOURCE */
#endif /* _GUSISocket_ */

360
GUSI/include/GUSISocketMixins.h Executable file
View File

@ -0,0 +1,360 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSISocketMixins.nw - Useful building blocks
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:14 chombier
// % Initial import
// %
// % Revision 1.11 2000/10/16 04:10:12 neeri
// % Add GUSISMProcess
// %
// % Revision 1.10 2000/05/23 07:24:58 neeri
// % Improve formatting
// %
// % Revision 1.9 1999/08/26 05:45:09 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.8 1999/08/02 07:02:46 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.7 1999/05/29 06:26:45 neeri
// % Fixed header guards
// %
// % Revision 1.6 1999/04/29 05:33:18 neeri
// % Fix fcntl prototype
// %
// % Revision 1.5 1999/03/17 09:05:13 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.4 1998/10/11 16:45:24 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.3 1998/01/25 20:53:59 neeri
// % Engine implemented, except for signals & scheduling
// %
// % Revision 1.2 1997/11/13 21:12:13 neeri
// % Fall 1997
// %
// % Revision 1.1 1996/12/16 02:12:42 neeri
// % TCP Sockets sort of work
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Mixin Classes for Sockets}
//
// This section contains some building block classes for sockets:
//
// \begin{itemize}
// \item [[GUSISMBlocking]] implements the blocking/nonblocking flag.
// \item [[GUSISMState]] implements a state variable.
// \item [[GUSISMInputBuffer]] provides a [[GUSIBuffer]] for input.
// \item [[GUSISMOutputBuffer]] provides a [[GUSIBuffer]] for output.
// \item [[GUSISMAsyncError]] provides storage for asynchronous errors.
// \item [[GUSISMProcess]] maintains a link to the process instance.
// \end{itemize}
//
//
// <GUSISocketMixins.h>=
#ifndef _GUSISocketMixins_
#define _GUSISocketMixins_
#ifdef GUSI_INTERNAL
#include "GUSISocket.h"
#include "GUSIBuffer.h"
#include <fcntl.h>
#include <sys/ioctl.h>
// \section{Definition of [[GUSISocketMixins]]}
//
// [[GUSISMBlocking]] implements the [[fBlocking]] flags and the [[DoIoctl]] and
// [[DoFcntl]] variants to manipulate it. These two functions work like their
// [[GUSISocket]] member function counterparts, but handle the return value
// differently: The POSIX function result is stored in [[*result]], while the
// return value indicates whether the request was handled.
//
// <Definition of class [[GUSISMBlocking]]>=
class GUSISMBlocking {
public:
GUSISMBlocking();
bool fBlocking;
bool DoFcntl(int * result, int cmd, va_list arg);
bool DoIoctl(int * result, unsigned int request, va_list arg);
};
// [[GUSISMState]] captures the state of a socket over its lifetime. It starts out
// as [[Unbound]]. [[bind]] will put it into [[Unconnected]] state, though few
// socket classes care about this distinction. [[listen]] will put it into
// [[Listening]] state. [[accept]] starts a [[Connected]] new socket.
// [[connect]] puts an [[Unconnected]] socket into [[Connecting]] state from
// where it emerges [[Connected]]. [[fReadShutdown]] and [[fWriteShutdown]] record
// shutdown promises.
//
// <Definition of class [[GUSISMState]]>=
class GUSISMState {
public:
enum State {
Unbound,
Unconnected,
Listening,
Connecting,
Connected,
Closing
};
GUSISMState();
State fState;
bool fReadShutdown;
bool fWriteShutdown;
void Shutdown(int how);
};
// [[GUSISMInputBuffer]] defines the input buffer and some socket options that go
// with it. [[DoGetSockOpt]] and [[DoSetSockOpt]] work the same way as
// [[DoFcntl]] and [[DoIoctl]] above.
//
// <Definition of class [[GUSISMInputBuffer]]>=
class GUSISMInputBuffer {
public:
GUSIRingBuffer fInputBuffer;
GUSISMInputBuffer();
bool DoGetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t * optlen);
bool DoSetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t optlen);
bool DoIoctl(int * result, unsigned int request, va_list arg);
};
// [[GUSISMOutputBuffer]] defines the output buffer and some socket options that go
// with it.
//
// <Definition of class [[GUSISMOutputBuffer]]>=
class GUSISMOutputBuffer {
public:
GUSIRingBuffer fOutputBuffer;
GUSISMOutputBuffer();
bool DoGetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t * optlen);
bool DoSetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t optlen);
};
// [[GUSISMAsyncError]] stores asynchronous errors and makes them available via
// [[getsockopt]]. [[GetAsyncError]] returns the error and resets the stored value.
//
// <Definition of class [[GUSISMAsyncError]]>=
class GUSISMAsyncError {
public:
GUSISMAsyncError();
int fAsyncError;
int SetAsyncPosixError(int error);
int SetAsyncMacError(OSErr error);
int GetAsyncError();
bool DoGetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t * optlen);
};
// [[GUSISMProcess]] stores a link to the global [[GUSIProcess]] instance, which is useful for completion routines.
//
// <Definition of class [[GUSISMProcess]]>=
class GUSISMProcess {
public:
GUSISMProcess();
GUSIProcess * Process();
private:
GUSIProcess * fProcess;
};
// \section{Implementation of [[GUSISocketMixins]]}
//
// Because all the member functions are simple and called in few places, it
// makes sense to inline them.
//
// All sockets start out blocking.
//
// <Inline member functions for class [[GUSISMBlocking]]>=
inline GUSISMBlocking::GUSISMBlocking() : fBlocking(true) {}
// For historical reasons, there is both an [[ioctl]] and a [[fcntl]] interface
// to the blocking flag.
//
// <Inline member functions for class [[GUSISMBlocking]]>=
inline bool GUSISMBlocking::DoFcntl(int * result, int cmd, va_list arg)
{
switch(cmd) {
case F_GETFL :
return (*result = fBlocking ? 0: FNDELAY), true;
case F_SETFL :
fBlocking = !(va_arg(arg, int) & FNDELAY);
return (*result = 0), true;
}
return false;
}
inline bool GUSISMBlocking::DoIoctl(int * result, unsigned int request, va_list arg)
{
if (request == FIONBIO) {
fBlocking = !*va_arg(arg, int *);
return (*result = 0), true;
}
return false;
}
// Sockets start out as unconnected.
//
// <Inline member functions for class [[GUSISMState]]>=
inline GUSISMState::GUSISMState() :
fState(Unbound), fReadShutdown(false), fWriteShutdown(false) {}
// <Inline member functions for class [[GUSISMState]]>=
inline void GUSISMState::Shutdown(int how)
{
if (!(how & 1))
fReadShutdown = true;
if (how > 0)
fWriteShutdown = true;
}
// Buffers initially are 8K.
//
// <Inline member functions for class [[GUSISMInputBuffer]]>=
inline GUSISMInputBuffer::GUSISMInputBuffer() : fInputBuffer(8192) {}
// [[getsockopt]] is used to obtain the buffer size.
//
// <Inline member functions for class [[GUSISMInputBuffer]]>=
inline bool GUSISMInputBuffer::DoGetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t *)
{
if (level == SOL_SOCKET && optname == SO_RCVBUF) {
*(int *)optval = (int)fInputBuffer.Size();
return (*result = 0), true;
}
return false;
}
// [[setsockopt]] modifies the buffer size.
//
// <Inline member functions for class [[GUSISMInputBuffer]]>=
inline bool GUSISMInputBuffer::DoSetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t)
{
if (level == SOL_SOCKET && optname == SO_RCVBUF) {
fInputBuffer.SwitchBuffer(*(int *)optval);
return (*result = 0), true;
}
return false;
}
// [[ioctl]] returns the number of available bytes.
//
// <Inline member functions for class [[GUSISMInputBuffer]]>=
inline bool GUSISMInputBuffer::DoIoctl(int * result, unsigned int request, va_list arg)
{
if (request == FIONREAD) {
*va_arg(arg, long *) = fInputBuffer.Valid();
return (*result = 0), true;
}
return false;
}
// [[GUSISMOutputBuffer]] works identically to the input buffer.
//
// <Inline member functions for class [[GUSISMOutputBuffer]]>=
inline GUSISMOutputBuffer::GUSISMOutputBuffer() : fOutputBuffer(8192) {}
// [[getsockopt]] is used to obtain the buffer size.
//
// <Inline member functions for class [[GUSISMOutputBuffer]]>=
inline bool GUSISMOutputBuffer::DoGetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t *)
{
if (level == SOL_SOCKET && optname == SO_SNDBUF) {
*(int *)optval = (int)fOutputBuffer.Size();
return (*result = 0), true;
}
return false;
}
// [[setsockopt]] is modifies the buffer size.
//
// <Inline member functions for class [[GUSISMOutputBuffer]]>=
inline bool GUSISMOutputBuffer::DoSetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t)
{
if (level == SOL_SOCKET && optname == SO_SNDBUF) {
fOutputBuffer.SwitchBuffer(*(int *)optval);
return (*result = 0), true;
}
return false;
}
// <Inline member functions for class [[GUSISMAsyncError]]>=
inline GUSISMAsyncError::GUSISMAsyncError()
: fAsyncError(0)
{
}
// The central member functions of [[GUSISMAsyncError]] are [[SetAsyncXXXError]] and
// [[GetAsyncError]].
//
// <Inline member functions for class [[GUSISMAsyncError]]>=
inline int GUSISMAsyncError::SetAsyncPosixError(int error)
{
if (error) {
fAsyncError = error;
GUSI_MESSAGE(("GUSISMAsyncError::SetAsyncPosixError %d\n", fAsyncError));
return -1;
}
return 0;
}
inline int GUSISMAsyncError::GetAsyncError()
{
int err = fAsyncError;
fAsyncError = 0;
return err;
}
// For some reason, the CW Pro 4 compilers generated bad code for this in some combination, so
// we make it out of line.
//
// <Inline member functions for class [[GUSISMAsyncError]]>=
inline int GUSISMAsyncError::SetAsyncMacError(OSErr error)
{
if (error) {
fAsyncError = GUSIMapMacError(error);
GUSI_MESSAGE(("GUSISMAsyncError::SetAsyncMacError %d -> %d\n", error, fAsyncError));
return -1;
}
return 0;
}
// [[DoGetSockOpt]] only handles [[SO_ERROR]] (hi Philippe!).
//
// <Inline member functions for class [[GUSISMAsyncError]]>=
inline bool GUSISMAsyncError::DoGetSockOpt(
int * result, int level, int optname,
void *optval, socklen_t * optlen)
{
if (level == SOL_SOCKET && optname == SO_ERROR) {
*(int *)optval = GetAsyncError();
*optlen = sizeof(int);
return (*result = 0), true;
}
return false;
}
// <Inline member functions for class [[GUSISMProcess]]>=
inline GUSISMProcess::GUSISMProcess()
: fProcess(GUSIProcess::Instance())
{
}
inline GUSIProcess * GUSISMProcess::Process()
{
return fProcess;
}
#endif /* GUSI_INTERNAL */
#endif /* _GUSISocketMixins_ */

186
GUSI/include/GUSISpecific.h Executable file
View File

@ -0,0 +1,186 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSISpecific.nw - Thread specific variables
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:14 chombier
// % Initial import
// %
// % Revision 1.9 2000/10/16 04:11:21 neeri
// % Plug memory leak
// %
// % Revision 1.8 2000/03/15 07:22:07 neeri
// % Enforce alignment choices
// %
// % Revision 1.7 1999/08/26 05:45:10 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.6 1999/05/30 03:09:31 neeri
// % Added support for MPW compilers
// %
// % Revision 1.5 1999/04/29 04:58:20 neeri
// % Fix key destruction bug
// %
// % Revision 1.4 1999/03/17 09:05:13 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.3 1998/10/11 16:45:25 neeri
// % Ready to release 2.0a2
// %
// % Revision 1.2 1998/08/01 21:32:11 neeri
// % About ready for 2.0a1
// %
// % Revision 1.1 1998/01/25 21:02:52 neeri
// % Engine implemented, except for signals & scheduling
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Thread Specific Variables}
//
// It is often useful to have variables which maintain a different value
// for each process. The [[GUSISpecific]] class implements such a mechanism
// in a way that is easily mappable to pthreads.
//
//
// <GUSISpecific.h>=
#ifndef _GUSISpecific_
#define _GUSISpecific_
#ifndef GUSI_SOURCE
typedef struct GUSISpecific GUSISpecific;
#else
#include <Types.h>
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of Thread Specific Variables}
//
// A [[GUSISpecific]] instance contains a variable ID and a per-process
// destructor.
//
// <Definition of class [[GUSISpecific]]>=
extern "C" {
typedef void (*GUSISpecificDestructor)(void *);
}
class GUSISpecific {
friend class GUSISpecificTable;
public:
GUSISpecific(GUSISpecificDestructor destructor = nil);
~GUSISpecific();
void Destruct(void * data);
private:
GUSISpecificDestructor fDestructor;
unsigned fID;
static unsigned sNextID;
};
// A [[GUSIContext]] contains a [[GUSISpecificTable]] storing the values of all
// thread specific variables defined for this thread.
//
// <Definition of class [[GUSISpecificTable]]>=
class GUSISpecificTable {
friend class GUSISpecific;
public:
GUSISpecificTable();
~GUSISpecificTable();
void * GetSpecific(const GUSISpecific * key) const;
void SetSpecific(const GUSISpecific * key, void * value);
void DeleteSpecific(const GUSISpecific * key);
private:
static void Register(GUSISpecific * key);
static void Destruct(GUSISpecific * key);
// We store a [[GUSISpecificTable]] as a contiguous range of IDs.
//
// <Privatissima of [[GUSISpecificTable]]>=
void *** fValues;
unsigned fAlloc;
bool Valid(const GUSISpecific * key) const;
// All keys are registered in a global table.
//
// <Privatissima of [[GUSISpecificTable]]>=
static GUSISpecific *** sKeys;
static unsigned sKeyAlloc;
};
// To simplify having a particular variable assume a different instance in every
// thread, we define the [[GUSISpecificData]] template.
//
// <Definition of template [[GUSISpecificData]]>=
template <class T, GUSISpecificDestructor D>
class GUSISpecificData {
public:
GUSISpecificData() : fKey(D) { }
T & operator*() { return *get(); }
T * operator->() { return get(); }
const GUSISpecific * Key() const { return &fKey; }
T * get(GUSISpecificTable * table);
T * get() { return get(GUSIContext::Current()); }
protected:
GUSISpecific fKey;
};
template <class T, GUSISpecificDestructor D>
T * GUSISpecificData<T,D>::get(GUSISpecificTable * table)
{
void * data = table->GetSpecific(&fKey);
if (!data)
table->SetSpecific(&fKey, data = new T);
return static_cast<T *>(data);
}
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
// <Inline member functions for class [[GUSISpecific]]>=
inline GUSISpecific::GUSISpecific(GUSISpecificDestructor destructor)
: fDestructor(destructor), fID(sNextID++)
{
GUSISpecificTable::Register(this);
}
inline GUSISpecific::~GUSISpecific()
{
GUSISpecificTable::Destruct(this);
}
inline void GUSISpecific::Destruct(void * data)
{
if (fDestructor)
fDestructor(data);
}
// <Inline member functions for class [[GUSISpecificTable]]>=
inline bool GUSISpecificTable::Valid(const GUSISpecific * key) const
{
return key && key->fID < fAlloc;
}
// <Inline member functions for class [[GUSISpecificTable]]>=
inline GUSISpecificTable::GUSISpecificTable()
: fValues(nil), fAlloc(0)
{
}
// <Inline member functions for class [[GUSISpecificTable]]>=
inline void * GUSISpecificTable::GetSpecific(const GUSISpecific * key) const
{
if (Valid(key))
return fValues[0][key->fID];
else
return nil;
}
#endif /* GUSI_SOURCE */
#endif /* _GUSISpecific_ */

192
GUSI/include/GUSITimer.h Executable file
View File

@ -0,0 +1,192 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSITimer.nw - Timing functions
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:16 chombier
// % Initial import
// %
// % Revision 1.12 2001/01/17 08:48:04 neeri
// % Introduce Expired(), Reset()
// %
// % Revision 1.11 2000/10/29 18:36:32 neeri
// % Fix time_t signedness issues
// %
// % Revision 1.10 2000/06/12 04:24:50 neeri
// % Fix time, localtime, gmtime
// %
// % Revision 1.9 2000/05/23 07:24:58 neeri
// % Improve formatting
// %
// % Revision 1.8 2000/03/15 07:22:07 neeri
// % Enforce alignment choices
// %
// % Revision 1.7 1999/11/15 07:20:18 neeri
// % Safe context setup
// %
// % Revision 1.6 1999/08/26 05:45:10 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.5 1999/08/02 07:02:46 neeri
// % Support for asynchronous errors and other socket options
// %
// % Revision 1.4 1999/07/07 04:17:43 neeri
// % Final tweaks for 2.0b3
// %
// % Revision 1.3 1999/06/28 06:08:46 neeri
// % Support flexible timer classes
// %
// % Revision 1.2 1999/05/30 03:06:21 neeri
// % Fixed various bugs in cleanup and wakeup
// %
// % Revision 1.1 1999/03/17 09:05:14 neeri
// % Added GUSITimer, expanded docs
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Timing functions}
//
// This section defines mechanisms to measure time. The basic mechanism is
// [[GUSITimer]] which can wake up a [[GUSIContext]] at some later time.
//
// <GUSITimer.h>=
#ifndef _GUSITimer_
#define _GUSITimer_
#ifndef GUSI_SOURCE
typedef struct GUSITimer GUSITimer;
#else
#include "GUSISpecific.h"
#include <errno.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/time.h>
#include <inttypes.h>
#include <MacTypes.h>
#include <Timer.h>
#include <Math64.h>
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of timing}
//
// [[GUSITime]] is an universal (if somewhat costly) format for
// the large variety of timing formats used in MacOS and POSIX.
//
// <Definition of class [[GUSITime]]>=
class GUSITime {
public:
enum Format {seconds, ticks, msecs, usecs, nsecs};
#if !TYPE_LONGLONG
GUSITime(int32_t val, Format format);
GUSITime(uint32_t val, Format format);
#endif
GUSITime(int64_t val, Format format=nsecs) { Construct(val, format); }
GUSITime(const timeval & tv);
GUSITime(const timespec & ts);
GUSITime(const tm & t);
GUSITime() {}
int32_t Get(Format format) { return S32Set(Get64(format)); }
uint32_t UGet(Format format)
{ return U32SetU(SInt64ToUInt64(Get64(format))); }
int64_t Get64(Format format);
operator int64_t() { return fTime; }
operator timeval();
operator timespec();
operator tm();
GUSITime GM2LocalTime();
GUSITime Local2GMTime();
GUSITime & operator +=(const GUSITime & other)
{ fTime = S64Add(fTime, other.fTime); return *this; }
GUSITime & operator -=(const GUSITime & other)
{ fTime = S64Subtract(fTime, other.fTime); return *this; }
static GUSITime Now();
static timezone & Zone();
private:
void Construct(int64_t val, Format format);
time_t Deconstruct(int64_t & remainder);
int64_t fTime;
static int64_t sTimeOffset;
static timezone sTimeZone;
};
inline GUSITime operator+(const GUSITime & a, const GUSITime & b)
{ GUSITime t(a); return t+=b; }
inline GUSITime operator-(const GUSITime & a, const GUSITime & b)
{ GUSITime t(a); return t-=b; }
// A [[GUSITimer]] is a time manager task that wakes up a [[GUSIContext]].
//
// <Definition of class [[GUSITimer]]>=
#if PRAGMA_STRUCT_ALIGN
#pragma options align=mac68k
#endif
class GUSIContext;
extern "C" void GUSIKillTimers(void * timers);
class GUSITimer : public TMTask {
public:
GUSITimer(bool wakeup = true, GUSIContext * context = 0);
virtual ~GUSITimer();
void Sleep(long ms, bool driftFree = false);
void MicroSleep(long us, bool driftFree = false)
{ Sleep(-us, driftFree); }
GUSIContext * Context() { return fQueue->fContext; }
GUSITimer * Next() { return fNext; }
bool Primed() { return (qType&kTMTaskActive) != 0; }
bool Expired() { return !(qType&kTMTaskActive); }
virtual void Wakeup();
void Kill();
void Reset();
struct Queue {
GUSITimer * fTimer;
GUSIContext * fContext;
Queue() : fTimer(0) {}
};
QElem * Elem() { return reinterpret_cast<QElem *>(&this->qLink); }
protected:
Queue * fQueue;
GUSITimer * fNext;
class TimerQueue : public GUSISpecificData<Queue,GUSIKillTimers> {
public:
~TimerQueue();
};
static TimerQueue sTimerQueue;
static TimerUPP sTimerProc;
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
#endif /* GUSI_SOURCE */
#endif /* _GUSITimer_ */

59
GUSI/include/arpa/inet.h Executable file
View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)inet.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _INET_H_
#define _INET_H_
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
/* External definitions for functions in inet(3) */
#include <sys/cdefs.h>
/* XNS mandates availability of xtonx() and uintx_t -- neeri */
#include <netinet/in.h>
#include <machine/endian.h>
__BEGIN_DECLS
in_addr_t inet_addr __P((const char *));
int inet_aton __P((const char *, struct in_addr *));
in_addr_t inet_lnaof __P((struct in_addr));
struct in_addr inet_makeaddr __P((uint32_t , in_addr_t));
in_addr_t inet_netof __P((struct in_addr));
in_addr_t inet_network __P((const char *));
char *inet_ntoa __P((struct in_addr));
__END_DECLS
#endif /* !_INET_H_ */

66
GUSI/include/compat.h Executable file
View File

@ -0,0 +1,66 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)compat.h 8.1 (Berkeley) 6/2/93
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _COMPAT_H_
#define _COMPAT_H_
/*
* If your system doesn't specify a max size for a SIZE_T, check
* to make sure this is the right one.
*/
#ifndef SIZE_T_MAX
#define SIZE_T_MAX UINT_MAX
#endif
#define index(a, b) strchr(a, b)
#define rindex(a, b) strrchr(a, b)
#define bzero(a, b) memset(a, 0, b)
#define bcmp(a, b, n) memcmp(a, b, n)
#define bcopy(a, b, n) memmove(b, a, n)
/* POSIX 1003.2 RE limit. */
#ifndef _POSIX2_RE_DUP_MAX
#define _POSIX2_RE_DUP_MAX 255
#endif
#ifndef MAX
#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a))
#endif
#ifndef MIN
#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
#endif
#endif /* !_COMPAT_H_ */

56
GUSI/include/dirent.h Executable file
View File

@ -0,0 +1,56 @@
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)dirent.h 8.1 (Berkeley) 6/8/93
*/
#ifndef _DIRENT_H_
#define _DIRENT_H_
struct dirent {
ino_t d_ino; /* file number of entry */
char d_name[255 + 1]; /* name must be no longer than this */
};
typedef void * DIR;
#include <sys/cdefs.h>
__BEGIN_DECLS
DIR *opendir __P((const char *));
struct dirent *readdir __P((DIR *));
void rewinddir __P((DIR *));
int closedir __P((DIR *));
long telldir __P((DIR *));
void seekdir __P((DIR *, long));
__END_DECLS
#endif /* !_DIRENT_H_ */

44
GUSI/include/errno.h Executable file
View File

@ -0,0 +1,44 @@
/* Metrowerks Standard Library Version 2.4 1998 March 10 */
/*
* errno.h
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _ERRNO_H
#define _ERRNO_H
#ifdef __MWERKS__
#include <cerrno>
/*
* Undef error codes defined by MSL. We are overriding the MSL implementations, so
* these versions of the codes should never be generated anyway.
*/
#undef EEXIST
#undef ENOTEMPTY
#undef EISDIR
#undef EPERM
#undef EACCES
#undef EBADF
#undef EDEADLOCK
#undef EMFILE
#undef ENOENT
#undef ENFILE
#undef ENOSPC
#undef EINVAL
#undef EIO
#undef ENOMEM
#undef ENOSYS
#undef ENAMETOOLONG
#else
#include <mpw/errno.h>
#endif
#include <sys/errno.h>
#if defined(__cplusplus) && defined(_MSL_USING_NAMESPACE) && (__MSL__ < 0x5000)
using namespace std;
#endif
#endif

133
GUSI/include/fcntl.h Executable file
View File

@ -0,0 +1,133 @@
/*-
* Copyright (c) 1983, 1990, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)fcntl.h 8.3 (Berkeley) 1/21/94
*
* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch>
*/
#ifndef _FCNTL_H_
#define _FCNTL_H_
/*
* This file includes the definitions for open and fcntl
* described by POSIX for <fcntl.h>; it also includes
* related kernel definitions.
*/
#include <sys/types.h>
/* open-only flags */
#define O_RDONLY 0x0001 /* open for reading only */
#define O_WRONLY 0x0002 /* open for writing only */
#define O_RDWR 0x0000 /* open for reading and writing */
#define O_ACCMODE 0x0003 /* mask for above modes */
#define O_NONBLOCK 0x0004 /* no delay */
#define O_APPEND 0x0008 /* set append mode */
#define O_CREAT 0x0200 /* create if nonexistant */
#define O_TRUNC 0x0400 /* truncate to zero length */
#define O_EXCL 0x0800 /* error if already exists */
#ifndef _POSIX_SOURCE
/* Mac specific */
#define O_ALIAS 0x2000 /* Open alias file (if the file is an alias) */
#define O_RSRC 0x4000 /* Open the resource fork */
#endif
/* defined by POSIX 1003.1; BSD default, so no bit required */
#define O_NOCTTY 0 /* don't assign controlling terminal */
#ifndef _POSIX_SOURCE
#define FNDELAY O_NONBLOCK /* compat */
#endif
/*
* Constants used for fcntl(2)
*/
/* command values */
#define F_DUPFD 0 /* duplicate file descriptor */
#define F_GETFD 1 /* get file descriptor flags */
#define F_SETFD 2 /* set file descriptor flags */
#define F_GETFL 3 /* get file status flags */
#define F_SETFL 4 /* set file status flags */
#define F_GETOWN 5 /* get SIGIO/SIGURG proc/pgrp */
#define F_SETOWN 6 /* set SIGIO/SIGURG proc/pgrp */
#define F_GETLK 7 /* get record locking information */
#define F_SETLK 8 /* set record locking information */
#define F_SETLKW 9 /* F_SETLK; wait if blocked */
/* file descriptor flags (F_GETFD, F_SETFD) */
#define FD_CLOEXEC 1 /* close-on-exec flag */
/* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */
#define F_RDLCK 1 /* shared or read lock */
#define F_UNLCK 2 /* unlock */
#define F_WRLCK 3 /* exclusive or write lock */
/*
* Advisory file segment locking data type -
* information passed to system by user
*/
struct flock {
off_t l_start; /* starting offset */
off_t l_len; /* len = 0 means until end of file */
pid_t l_pid; /* lock owner */
short l_type; /* lock type: read/write, etc. */
short l_whence; /* type of l_start */
};
#include <sys/cdefs.h>
#include <stdio.h>
__BEGIN_DECLS
int open __P((const char *, int, ...));
int creat __P((const char *, ...));
int fcntl __P((int, int, ...));
/* This properly belongs into stdio.h, but that header is outside of
GUSI's control
*/
#ifdef __MWERKS__
FILE * fdopen(int fildes, char *type);
#else
FILE * fdopen(int fildes, const char *type);
#endif
__END_DECLS
#endif /* !_FCNTL_H_ */

22
GUSI/include/inttypes.h Executable file
View File

@ -0,0 +1,22 @@
/* Written for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _INTTYPES_H_
#define _INTTYPES_H_
/*
* Regrettably, this is needed for *int64_t
*/
#include <MacTypes.h>
typedef char int8_t;
typedef short int16_t;
typedef long int32_t;
typedef SInt64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef UInt64 uint64_t;
typedef long intptr_t;
typedef unsigned long uintptr_t;
#endif /* _INTTYPES_H_ */

73
GUSI/include/machine/ansi.h Executable file
View File

@ -0,0 +1,73 @@
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ansi.h 8.2 (Berkeley) 1/4/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _ANSI_H_
#define _ANSI_H_
/*
* Types which are fundamental to the implementation and may appear in
* more than one standard header are defined here. Standard headers
* then use:
* #ifdef _BSD_SIZE_T_
* typedef _BSD_SIZE_T_ size_t;
* #undef _BSD_SIZE_T_
* #endif
*/
#define _BSD_CLOCK_T_ unsigned long /* clock() */
#define _BSD_PTRDIFF_T_ int /* ptr1 - ptr2 */
#define _BSD_SIZE_T_ unsigned long /* sizeof() */
#define _BSD_SSIZE_T_ long /* byte count or error */
#define _BSD_TIME_T_ unsigned long /* time() */
#define _BSD_VA_LIST_ char * /* va_list */
/*
* Runes (wchar_t) is declared to be an ``int'' instead of the more natural
* ``unsigned long'' or ``long''. Two things are happening here. It is not
* unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
* it looks like 10646 will be a 31 bit standard. This means that if your
* ints cannot hold 32 bits, you will be in trouble. The reason an int was
* chosen over a long is that the is*() and to*() routines take ints (says
* ANSI C), but they use _RUNE_T_ instead of int. By changing it here, you
* lose a bit of ANSI conformance, but your programs will still work.
*
* Note that _WCHAR_T_ and _RUNE_T_ must be of the same type. When wchar_t
* and rune_t are typedef'd, _WCHAR_T_ will be undef'd, but _RUNE_T remains
* defined for ctype.h.
*/
#define _BSD_WCHAR_T_ int /* wchar_t */
#define _BSD_RUNE_T_ int /* rune_t */
#endif /* _ANSI_H_ */

84
GUSI/include/machine/endian.h Executable file
View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 1987, 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)endian.h 8.1 (Berkeley) 6/10/93
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _ENDIAN_H_
#define _ENDIAN_H_
/* xtonx() now defined in terms of inttypes -- neeri */
#include <inttypes.h>
/*
* Define the order of 32-bit words in 64-bit words.
*/
#define _QUAD_HIGHWORD 0
#define _QUAD_LOWWORD 1
#ifndef _POSIX_SOURCE
/*
* Definitions for byte order, according to byte significance from low
* address to high.
*/
#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */
#define BYTE_ORDER BIG_ENDIAN
#include <sys/cdefs.h>
__BEGIN_DECLS
uint32_t htonl __P((uint32_t));
uint16_t htons __P((uint16_t));
uint32_t ntohl __P((uint32_t));
uint16_t ntohs __P((uint16_t));
__END_DECLS
/*
* Macros for network/external number representation conversion.
*/
#define ntohl(x) (x)
#define ntohs(x) (x)
#define htonl(x) (x)
#define htons(x) (x)
#define NTOHL(x) (x)
#define NTOHS(x) (x)
#define HTONL(x) (x)
#define HTONS(x) (x)
#endif /* !_POSIX_SOURCE */
#endif /* !_ENDIAN_H_ */

41
GUSI/include/machine/signal.h Executable file
View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 1986, 1989, 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)signal.h 8.1 (Berkeley) 6/10/93
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
/*
* Machine-dependent signal definitions
*/
typedef int sig_atomic_t;

131
GUSI/include/net/if.h Executable file
View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)if.h 8.1 (Berkeley) 6/10/93
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
/*
* Structures defining a network interface, providing a packet
* transport mechanism (ala level 0 of the PUP protocols).
*
* Each interface accepts output datagrams of a specified maximum
* length, and provides higher level routines with input datagrams
* received from its medium.
*
* Output occurs when the routine if_output is called, with three parameters:
* (*ifp->if_output)(ifp, m, dst, rt)
* Here m is the mbuf chain to be sent and dst is the destination address.
* The output routine encapsulates the supplied datagram if necessary,
* and then transmits it on its medium.
*
* On input, each interface unwraps the data received by it, and either
* places it on the input queue of a internetwork datagram routine
* and posts the associated software interrupt, or passes the datagram to a raw
* packet input routine.
*
* Routines exist for locating interfaces by their addresses
* or for locating a interface on a certain network, as well as more general
* routing and gateway routines maintaining information used to locate
* interfaces. These routines live in the files if.c and route.c
*/
#define IFF_UP 0x1 /* interface is up */
#define IFF_BROADCAST 0x2 /* broadcast address valid */
#define IFF_DEBUG 0x4 /* turn on debugging */
#define IFF_LOOPBACK 0x8 /* is a loopback net */
#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
#define IFF_RUNNING 0x40 /* resources allocated */
#define IFF_NOARP 0x80 /* no address resolution protocol */
#define IFF_PROMISC 0x100 /* receive all packets */
#define IFF_ALLMULTI 0x200 /* receive all multicast packets */
#define IFF_OACTIVE 0x400 /* transmission in progress */
#define IFF_SIMPLEX 0x800 /* can't hear own transmissions */
#define IFF_LINK0 0x1000 /* per link layer defined bit */
#define IFF_LINK1 0x2000 /* per link layer defined bit */
#define IFF_LINK2 0x4000 /* per link layer defined bit */
#define IFF_MULTICAST 0x8000 /* supports multicast */
/* flags set internally only: */
#define IFF_CANTCHANGE \
(IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
/*
* Interface request structure used for socket
* ioctl's. All interface ioctl's must have parameter
* definitions which begin with ifr_name. The
* remainder may be interface specific.
*/
struct ifreq {
#define IFNAMSIZ 16
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
short ifru_flags;
int ifru_metric;
caddr_t ifru_data;
} ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_flags ifr_ifru.ifru_flags /* flags */
#define ifr_metric ifr_ifru.ifru_metric /* metric */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
};
struct ifaliasreq {
char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
struct sockaddr ifra_addr;
struct sockaddr ifra_broadaddr;
struct sockaddr ifra_mask;
};
/*
* Structure used in SIOCGIFCONF request.
* Used to retrieve interface configuration
* for machine (useful for programs which
* must know all networks accessible).
*/
struct ifconf {
int ifc_len; /* size of associated buffer */
union {
caddr_t ifcu_buf;
struct ifreq *ifcu_req;
} ifc_ifcu;
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
};

128
GUSI/include/netdb.h Executable file
View File

@ -0,0 +1,128 @@
/*-
* Copyright (c) 1980, 1983, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)netdb.h 8.1 (Berkeley) 6/2/93
* $Id$
* -
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
* -
* --Copyright--
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _NETDB_H_
#define _NETDB_H_
#define _PATH_HEQUIV "/etc/hosts.equiv"
#define _PATH_HOSTS "/etc/hosts"
#define _PATH_NETWORKS "/etc/networks"
#define _PATH_PROTOCOLS "/etc/protocols"
#define _PATH_SERVICES "/etc/services"
/*
* Structures returned by network data base library. All addresses are
* supplied in host order, and returned in network order (suitable for
* use in system calls).
*/
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses from name server */
#define h_addr h_addr_list[0] /* address, for backward compatiblity */
};
struct servent {
char *s_name; /* official service name */
char **s_aliases; /* alias list */
int s_port; /* port # */
char *s_proto; /* protocol to use */
};
struct protoent {
char *p_name; /* official protocol name */
char **p_aliases; /* alias list */
int p_proto; /* protocol # */
};
/*
* Error return codes from gethostbyname() and gethostbyaddr()
* (left in h_errno).
*/
extern int h_errno;
#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
#define NO_DATA 4 /* Valid name, no data record of requested type */
#define NO_ADDRESS NO_DATA /* no address, look for MX record */
#include <sys/cdefs.h>
__BEGIN_DECLS
void endhostent __P((void));
void endprotoent __P((void));
void endservent __P((void));
struct hostent *gethostbyaddr __P((const void *, size_t, int));
struct hostent *gethostbyname __P((const char *));
struct hostent *gethostent __P((void));
struct protoent *getprotobyname __P((const char *));
struct protoent *getprotobynumber __P((int));
struct protoent *getprotoent __P((void));
struct servent *getservbyname __P((const char *, const char *));
struct servent *getservbyport __P((int, const char *));
struct servent *getservent __P((void));
void herror __P((const char *));
char *hstrerror __P((int));
void setprotoent __P((int));
void setservent __P((int));
__END_DECLS
#endif /* !_NETDB_H_ */

248
GUSI/include/netinet/in.h Executable file
View File

@ -0,0 +1,248 @@
/*
* Copyright (c) 1982, 1986, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)in.h 8.3 (Berkeley) 1/3/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _NETINET_IN_H_
#define _NETINET_IN_H_
/* xtonx() mandated available by XNS -- neeri */
#include <machine/endian.h>
/*
* Constants and structures defined by the internet system,
* Per RFC 790, September 1981, and numerous additions.
*/
/*
* Protocols
*/
#define IPPROTO_IP 0 /* dummy for IP */
#define IPPROTO_ICMP 1 /* control message protocol */
#define IPPROTO_IGMP 2 /* group mgmt protocol */
#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */
#define IPPROTO_TCP 6 /* tcp */
#define IPPROTO_EGP 8 /* exterior gateway protocol */
#define IPPROTO_PUP 12 /* pup */
#define IPPROTO_UDP 17 /* user datagram protocol */
#define IPPROTO_IDP 22 /* xns idp */
#define IPPROTO_TP 29 /* tp-4 w/ class negotiation */
#define IPPROTO_EON 80 /* ISO cnlp */
#define IPPROTO_ENCAP 98 /* encapsulation header */
#define IPPROTO_RAW 255 /* raw IP packet */
#define IPPROTO_MAX 256
/*
* Local port number conventions:
* Ports < IPPORT_RESERVED are reserved for
* privileged processes (e.g. root).
* Ports > IPPORT_USERRESERVED are reserved
* for servers, not necessarily privileged.
*/
#define IPPORT_RESERVED 1024
#define IPPORT_USERRESERVED 5000
/* Types mandated by XNS -- neeri */
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
/*
* Internet address (a structure for historical reasons)
*/
struct in_addr {
in_addr_t s_addr;
};
/*
* Definitions of bits in internet address integers.
* On subnets, the decomposition of addresses to host and net parts
* is done according to subnet mask, not the masks here.
*/
#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0)
#define IN_CLASSA_NET 0xff000000
#define IN_CLASSA_NSHIFT 24
#define IN_CLASSA_HOST 0x00ffffff
#define IN_CLASSA_MAX 128
#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000)
#define IN_CLASSB_NET 0xffff0000
#define IN_CLASSB_NSHIFT 16
#define IN_CLASSB_HOST 0x0000ffff
#define IN_CLASSB_MAX 65536
#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000)
#define IN_CLASSC_NET 0xffffff00
#define IN_CLASSC_NSHIFT 8
#define IN_CLASSC_HOST 0x000000ff
#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */
#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */
#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */
#define IN_MULTICAST(i) IN_CLASSD(i)
#define IN_EXPERIMENTAL(i) (((long)(i) & 0xf0000000) == 0xf0000000)
#define IN_BADCLASS(i) (((long)(i) & 0xf0000000) == 0xf0000000)
#define INADDR_ANY (u_long)0x00000000
#define INADDR_BROADCAST (u_long)0xffffffff /* must be masked */
#define INADDR_NONE 0xffffffff /* -1 return */
#define INADDR_UNSPEC_GROUP (u_long)0xe0000000 /* 224.0.0.0 */
#define INADDR_ALLHOSTS_GROUP (u_long)0xe0000001 /* 224.0.0.1 */
#define INADDR_MAX_LOCAL_GROUP (u_long)0xe00000ff /* 224.0.0.255 */
#define IN_LOOPBACKNET 127 /* official! */
/* Mandated by XNS -- neeri */
#ifndef _SA_FAMILY_T_DEFINED
#define _SA_FAMILY_T_DEFINED
typedef uint16_t sa_family_t;
#endif
/*
* Socket address, internet style.
*/
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
/*
* Structure used to describe IP options.
* Used to store options internally, to pass them to a process,
* or to restore options retrieved earlier.
* The ip_dst is used for the first-hop gateway when using a source route
* (this gets put into the header proper).
*/
typedef struct {
struct in_addr ip_dst; /* first hop, 0 w/o src rt */
char ip_opts[40]; /* actually variable in size */
} ip_opts;
/*
* Options for use with [gs]etsockopt at the IP level.
* First word of comment is data type; bool is stored in int.
*/
#define IP_OPTIONS 0x01
#define IP_TOS 0x02
#define IP_TTL 0x03
#define IP_REUSEADDR 0x04
#define IP_DONTROUTE 0x10
#define IP_BROADCAST 0x20
#define IP_HDRINCL 0x1002
#define IP_RCVOPTS 0x1005
#define IP_RCVDSTADDR 0x1007
#define IP_MULTICAST_IF 0x1010 /* set/get IP multicast interface */
#define IP_MULTICAST_TTL 0x1011 /* set/get IP multicast timetolive */
#define IP_MULTICAST_LOOP 0x1012 /* set/get IP multicast loopback */
#define IP_ADD_MEMBERSHIP 0x1013 /* add an IP group membership */
#define IP_DROP_MEMBERSHIP 0x1014 /* drop an IP group membership */
#define IP_BROADCAST_IF 0x1015 /* Set interface for broadcasts */
#define IP_RCVIFADDR 0x1016 /* Set interface for broadcasts */
/*
* Defaults and limits for options
*/
#define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */
#define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */
#define IP_MAX_MEMBERSHIPS 20 /* per socket; must fit in one mbuf */
/*
* Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.
*/
struct ip_mreq {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
};
/*
* Definitions for inet sysctl operations.
*
* Third level is protocol number.
* Fourth level is desired variable within that protocol.
*/
#define IPPROTO_MAXID (IPPROTO_IDP + 1) /* don't list to IPPROTO_MAX */
#define CTL_IPPROTO_NAMES { \
{ "ip", CTLTYPE_NODE }, \
{ "icmp", CTLTYPE_NODE }, \
{ "igmp", CTLTYPE_NODE }, \
{ "ggp", CTLTYPE_NODE }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ "tcp", CTLTYPE_NODE }, \
{ 0, 0 }, \
{ "egp", CTLTYPE_NODE }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ "pup", CTLTYPE_NODE }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ "udp", CTLTYPE_NODE }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ "idp", CTLTYPE_NODE }, \
}
/*
* Names for IP sysctl objects
*/
#define IPCTL_FORWARDING 1 /* act as router */
#define IPCTL_SENDREDIRECTS 2 /* may send redirects when forwarding */
#define IPCTL_DEFTTL 3 /* default TTL */
#ifdef notyet
#define IPCTL_DEFMTU 4 /* default MTU */
#endif
#define IPCTL_MAXID 5
#define IPCTL_NAMES { \
{ 0, 0 }, \
{ "forwarding", CTLTYPE_INT }, \
{ "redirect", CTLTYPE_INT }, \
{ "ttl", CTLTYPE_INT }, \
{ "mtu", CTLTYPE_INT }, \
}
#endif /* _NETINET_IN_H_ */

94
GUSI/include/netinet/tcp.h Executable file
View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)tcp.h 8.1 (Berkeley) 6/10/93
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
typedef u_long tcp_seq;
/*
* TCP header.
* Per RFC 793, September, 1981.
*/
struct tcphdr {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_off:4, /* data offset */
th_x2:4; /* (unused) */
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
#define TCPOPT_EOL 0
#define TCPOPT_NOP 1
#define TCPOPT_MAXSEG 2
#define TCPOLEN_MAXSEG 4
#define TCPOPT_WINDOW 3
#define TCPOLEN_WINDOW 3
#define TCPOPT_SACK_PERMITTED 4 /* Experimental */
#define TCPOLEN_SACK_PERMITTED 2
#define TCPOPT_SACK 5 /* Experimental */
#define TCPOPT_TIMESTAMP 8
#define TCPOLEN_TIMESTAMP 10
#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
#define TCPOPT_TSTAMP_HDR \
(TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
/*
* Default maximum segment size for TCP.
* With an IP MSS of 576, this is 536,
* but 512 is probably more convenient.
* This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
*/
#define TCP_MSS 512
#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
#define TCP_MAX_WINSHIFT 14 /* maximum window shift */
/*
* User-settable options (used with setsockopt).
*/
#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
#define TCP_MAXSEG 0x02 /* set maximum segment size */
#define TCP_KEEPALIVE 0x08 /* seconds between keepalive packets */

299
GUSI/include/pthread.h Executable file
View File

@ -0,0 +1,299 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIPThread.nw - Pthreads wrappers
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:16 chombier
// % Initial import
// %
// % Revision 1.14 2001/01/17 08:55:16 neeri
// % Detect and return ETIMEDOUT condition
// %
// % Revision 1.13 2000/10/29 20:31:53 neeri
// % Releasing 2.1.3
// %
// % Revision 1.12 2000/05/23 07:16:35 neeri
// % Improve formatting, make data types opaque, tune mutexes
// %
// % Revision 1.11 2000/03/06 06:10:00 neeri
// % Reorganize Yield()
// %
// % Revision 1.10 2000/01/17 01:40:31 neeri
// % Correct macro spelling, update references
// %
// % Revision 1.9 1999/11/15 07:20:19 neeri
// % Safe context setup
// %
// % Revision 1.8 1999/09/09 07:22:15 neeri
// % Add support for mutex and cond attribute creation/destruction
// %
// % Revision 1.7 1999/08/26 05:45:07 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.6 1999/07/07 04:17:42 neeri
// % Final tweaks for 2.0b3
// %
// % Revision 1.5 1999/06/30 07:42:07 neeri
// % Getting ready to release 2.0b3
// %
// % Revision 1.4 1999/05/30 03:06:55 neeri
// % MPW compiler compatibility, recursive mutex locks
// %
// % Revision 1.3 1999/03/17 09:05:12 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.2 1998/08/01 21:32:10 neeri
// % About ready for 2.0a1
// %
// % Revision 1.1 1998/01/25 21:02:51 neeri
// % Engine implemented, except for signals & scheduling
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Pthreads Wrappers}
//
// As opposed to POSIX.1, with which I think I'm reasonable competent by now,
// I have little practical experience, let alone in-depth familiarity with
// Pthreads, so I'm going by what I learned from
//
// \begin{itemize}
// \item Reading \emph{B.~Nicols, D.~Buttlar, and J.~Proulx Farrell,
// ``Pthreads Programming'', O'Reilly \& Associates} and
// \emph{D.~Butenhof, ``Programming with POSIX Threads'', Addison Wesley}.
//
// \item Taking a few glimpses at Chris Provenzano's pthreads implementation.
// \item Reading the news:comp.programming.threads newsgroup.
// \end{itemize}
//
// If you believe that I've misunderstood Pthreads in my implementation, feel free
// to contact me.
//
// As opposed to most other modules, the header files we're generating here don't
// have GUSI in its name.
//
// <pthread.h>=
#ifndef _PTHREAD_H_
#define _PTHREAD_H_
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/time.h>
__BEGIN_DECLS
// \section{Definition of Pthread data types}
//
// I used to be fairly cavalier about exposing internal GUSI data structures,
// on second thought this was not a good idea. To keep C happy, we define
// [[struct]] wrappers for what ultimately will mostly be classes.
//
// <Pthread data types>=
typedef struct GUSIPThread * pthread_t;
// A [[pthread_attr_t]] collects thread creation attributes. This is implemented
// as a pointer so it's easier to change the size of the underlying data structure.
//
// <Pthread data types>=
typedef struct GUSIPThreadAttr * pthread_attr_t;
// A [[pthread_key_t]] is a key to look up thread specific data.
//
// <Pthread data types>=
typedef struct GUSIPThreadKey * pthread_key_t;
// A [[pthread_once_t]] registers whether some routine has run once. It must always
// be statically initialized to [[PTHREAD_ONCE_INIT]] (Although in our implementation,
// it doesn't matter).
//
// <Pthread data types>=
typedef char pthread_once_t;
enum {
PTHREAD_ONCE_INIT = 0
};
// A [[pthread_mutex_t]] is a mutual exclusion variable, implemented as a pointer
// to a [[GUSIContextQueue]]. For initialization convenience, a 0 value means
// an unlocked mutex. No attributes are supported so far.
//
// <Pthread data types>=
typedef struct GUSIPThreadMutex * pthread_mutex_t;
typedef void * pthread_mutexattr_t;
#define PTHREAD_MUTEX_INITIALIZER 0
// A [[pthread_cond_t]] is a condition variable, which looks rather similar
// to a mutex, but has different semantics. No attributes are supported so far.
//
// <Pthread data types>=
typedef struct GUSIPThreadCond * pthread_cond_t;
typedef void * pthread_condattr_t;
#define PTHREAD_COND_INITIALIZER 0
// [[pthread_attr_init]] initializes an attribute object with the
// default values.
//
// <Pthread function declarations>=
int pthread_attr_init(pthread_attr_t * attr);
// [[pthread_attr_destroy]] destroys an attribute object.
//
// <Pthread function declarations>=
int pthread_attr_destroy(pthread_attr_t * attr);
// The detach state defines whether a thread will be defined joinable or
// detached.
//
// <Pthread function declarations>=
enum {
PTHREAD_CREATE_JOINABLE,
PTHREAD_CREATE_DETACHED
};
int pthread_attr_getdetachstate(const pthread_attr_t * attr, int * state);
int pthread_attr_setdetachstate(pthread_attr_t * attr, int state);
// The stack size defines how much stack space will be allocated. Stack overflows
// typically lead to utterly nasty crashes.
//
// <Pthread function declarations>=
int pthread_attr_getstacksize(const pthread_attr_t * attr, size_t * size);
int pthread_attr_setstacksize(pthread_attr_t * attr, size_t size);
// \section{Creation and Destruction of PThreads}
//
// First, we define wrapper to map the different calling conventions of Pthreads
// and Macintosh threads.
//
// <Pthread function declarations>=
__BEGIN_DECLS
typedef void * (*GUSIPThreadProc)(void *);
__END_DECLS
// [[pthread_create]] stuffs the arguments in a [[CreateArg]] and creates the
// context.
//
// <Pthread function declarations>=
int pthread_create(
pthread_t * thread,
const pthread_attr_t * attr, GUSIPThreadProc proc, void * arg);
// A thread can either be detached, in which case it will just go away after it's
// done, or it can be joinable, in which case it will wait for [[pthread_join]]
// to be called.
//
// <Pthread function declarations>=
int pthread_detach(pthread_t thread);
// [[pthread_join]] waits for the thread to die and optionally returns its last
// words.
//
// <Pthread function declarations>=
int pthread_join(pthread_t thread, void **value);
// [[pthread_exit]] ends the existence of a thread.
//
// <Pthread function declarations>=
int pthread_exit(void *value);
// \section{Pthread thread specific data}
//
// Thread specific data offers a possibility to quickly look up a value that may be
// different for every thread.
//
// [[pthread_key_create]] creates an unique key visible to all threads in a
// process.
//
// <Pthread function declarations>=
__BEGIN_DECLS
typedef void (*GUSIPThreadKeyDestructor)(void *);
__END_DECLS
int pthread_key_create(pthread_key_t * key, GUSIPThreadKeyDestructor destructor);
// [[pthread_key_delete]] deletes a key, but does not call any destructors.
//
// <Pthread function declarations>=
int pthread_key_delete(pthread_key_t key);
// [[pthread_getspecific]] returns the thread specific value for a key.
//
// <Pthread function declarations>=
void * pthread_getspecific(pthread_key_t key);
// [[pthread_setspecific]] sets a new thread specific value for a key.
//
// <Pthread function declarations>=
int pthread_setspecific(pthread_key_t key, void * value);
// \section{Synchronization mechanisms of PThreads}
//
// Since we're only dealing with cooperative threads, all synchronization
// mechanisms can be implemented using means that might look naive to a student
// of computer science, but that actually work perfectly well in our case.
//
// We currently don't support mutex and condition variable attributes. To minimize
// the amount of code changes necessary inclients, we support creating and destroying
// them, at least.
//
// <Pthread function declarations>=
int pthread_mutexattr_init(pthread_mutexattr_t * attr);
int pthread_mutexattr_destroy(pthread_mutexattr_t * attr);
// <Pthread function declarations>=
int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t *);
int pthread_mutex_destroy(pthread_mutex_t * mutex);
// Lock may create the queue if it was allocated statically. Mutexes are implemented
// as a queue of context, with the frontmost context holding the lock. Simple enough,
// isn't it?
//
// <Pthread function declarations>=
int pthread_mutex_lock(pthread_mutex_t * mutex);
// Strangely enough, [[pthread_mutex_trylock]] is much more of a problem if we want
// to maintain a semblance of scheduling fairness. In particular, we need the [[Yield]]
// in case somebody checks a mutex in a loop with no other yield point.
//
// <Pthread function declarations>=
int pthread_mutex_trylock(pthread_mutex_t * mutex);
// Unlocking pops us off the queue and wakes up the new lock owner.
//
// <Pthread function declarations>=
int pthread_mutex_unlock(pthread_mutex_t * mutex);
// On to condition variable attributes, which we don't really support either.
//
// <Pthread function declarations>=
int pthread_condattr_init(pthread_condattr_t * attr);
int pthread_condattr_destroy(pthread_condattr_t * attr);
// Condition variables in some respects work very similar to mutexes.
//
// <Pthread function declarations>=
int pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t *);
int pthread_cond_destroy(pthread_cond_t * cond);
// [[pthread_cond_wait]] releases the mutex, sleeps on the condition variable,
// and reacquires the mutex.
//
// <Pthread function declarations>=
int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex);
// [[pthread_cond_timedwait]] adds a timeout value (But it still could block
// indefinitely trying to reacquire the mutex). Note that the timeout specifies
// an absolute wakeup time, not an interval.
//
// <Pthread function declarations>=
int pthread_cond_timedwait(
pthread_cond_t * cond, pthread_mutex_t * mutex,
const struct timespec * patience);
// [[pthread_cond_signal]] wakes up a context from the queue. Since we typically
// still hold the associated mutex, it would be a bad idea (though not a disastrous
// one) to put a yield in here.
//
// <Pthread function declarations>=
int pthread_cond_signal(pthread_cond_t * cond);
// [[pthread_cond_broadcast]] wakes up a the entire queue (but only one context
// will get the mutex).
//
// <Pthread function declarations>=
int pthread_cond_broadcast(pthread_cond_t * cond);
// \section{Pthread varia}
//
// [[pthread_self]] returns the current thread.
//
// <Pthread function declarations>=
pthread_t pthread_self(void);
// [[pthread_equal]] compares two thread handles.
//
// <Pthread function declarations>=
int pthread_equal(pthread_t t1, pthread_t t2);
// [[pthread_once]] calls a routines, guaranteeing that it will be called exactly
// once per process.
//
// <Pthread function declarations>=
__BEGIN_DECLS
typedef void (*GUSIPThreadOnceProc)(void);
__END_DECLS
int pthread_once(pthread_once_t * once_block, GUSIPThreadOnceProc proc);
__END_DECLS
#endif /* _PTHREAD_H_ */

16
GUSI/include/sched.h Executable file
View File

@ -0,0 +1,16 @@
// <sched.h>=
#ifndef _SCHED_H_
#define _SCHED_H_
#include <sys/cdefs.h>
/* Required by UNIX 98 */
#include <sys/time.h>
__BEGIN_DECLS
// [[sched_yield]] yields the processor for other runnable threads.
//
// <Sched function declarations>=
int sched_yield();
__END_DECLS
#endif /* _SCHED_H_ */

75
GUSI/include/signal.h Executable file
View File

@ -0,0 +1,75 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)signal.h 8.3 (Berkeley) 3/30/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _USER_SIGNAL_H
#define _USER_SIGNAL_H
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/signal.h>
#include <pthread.h>
#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
extern const char *const sys_signame[NSIG];
#endif
__BEGIN_DECLS
int raise __P((int));
#ifndef _ANSI_SOURCE
int kill __P((pid_t, int));
int sigaction __P((int, const struct sigaction *, struct sigaction *));
int sigaddset __P((sigset_t *, int));
int sigdelset __P((sigset_t *, int));
int sigemptyset __P((sigset_t *));
int sigfillset __P((sigset_t *));
int sigismember __P((const sigset_t *, int));
int sigpending __P((sigset_t *));
int sigprocmask __P((int, const sigset_t *, sigset_t *));
int sigsuspend __P((const sigset_t *));
int pthread_kill __P((pthread_t, int));
int pthread_sigmask __P((int, const sigset_t *, sigset_t *));
int sigwait __P((const sigset_t *, int *));
#endif /* !_ANSI_SOURCE */
__END_DECLS
/* List definitions after function declarations, or Reiser cpp gets upset. */
#define sigaddset(set, signo) (*(set) |= 1 << ((signo) - 1), 0)
#define sigdelset(set, signo) (*(set) &= ~(1 << ((signo) - 1)), 0)
#define sigemptyset(set) (*(set) = 0, 0)
#define sigfillset(set) (*(set) = ~(sigset_t)0, 0)
#define sigismember(set, signo) ((*(set) & (1 << ((signo) - 1))) != 0)
#endif /* !_USER_SIGNAL_H */

53
GUSI/include/sys/cdefs.h Executable file
View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Berkeley Software Design, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)cdefs.h 8.7 (Berkeley) 1/21/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _CDEFS_H_
#define _CDEFS_H_
#if defined(__cplusplus)
#define __BEGIN_DECLS extern "C" {
#define __END_DECLS }
#else
#define __BEGIN_DECLS
#define __END_DECLS
#endif
#define __P(x) x
#endif /* !_CDEFS_H_ */

127
GUSI/include/sys/errno.h Executable file
View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)errno.h 8.5 (Berkeley) 1/21/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* Input/output error */
#define ENXIO 6 /* Device not configured */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file descriptor */
#define ECHILD 10 /* No child processes */
#define EDEADLK 11 /* Resource deadlock avoided */
/* 11 was EAGAIN */
#define ENOMEM 12 /* Cannot allocate memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ECANCELED 15 /* Operation cancelled */
#define EBUSY 16 /* Device busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* Operation not supported by device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* Too many open files in system */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Inappropriate ioctl for device */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
/* math software */
#define EDOM 33 /* Numerical argument out of domain */
#define ERANGE 34 /* Result too large */
/* non-blocking and interrupt i/o */
#define EAGAIN 35 /* Resource temporarily unavailable */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define EINPROGRESS 36 /* Operation now in progress */
#define EALREADY 37 /* Operation already in progress */
/* ipc/network software -- argument errors */
#define ENOTSOCK 38 /* Socket operation on non-socket */
#define EDESTADDRREQ 39 /* Destination address required */
#define EMSGSIZE 40 /* Message too long */
#define EPROTOTYPE 41 /* Protocol wrong type for socket */
#define ENOPROTOOPT 42 /* Protocol not available */
#define EPROTONOSUPPORT 43 /* Protocol not supported */
#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
#define EOPNOTSUPP 45 /* Operation not supported */
#define EPFNOSUPPORT 46 /* Protocol family not supported */
#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
#define EADDRINUSE 48 /* Address already in use */
#define EADDRNOTAVAIL 49 /* Can't assign requested address */
/* ipc/network software -- operational errors */
#define ENETDOWN 50 /* Network is down */
#define ENETUNREACH 51 /* Network is unreachable */
#define ENETRESET 52 /* Network dropped connection on reset */
#define ECONNABORTED 53 /* Software caused connection abort */
#define ECONNRESET 54 /* Connection reset by peer */
#define ENOBUFS 55 /* No buffer space available */
#define EISCONN 56 /* Socket is already connected */
#define ENOTCONN 57 /* Socket is not connected */
#define ESHUTDOWN 58 /* Can't send after socket shutdown */
#define ETOOMANYREFS 59 /* Too many references: can't splice */
#define ETIMEDOUT 60 /* Operation timed out */
#define ECONNREFUSED 61 /* Connection refused */
#define ELOOP 62 /* Too many levels of symbolic links */
#define ENAMETOOLONG 63 /* File name too long */
/* should be rearranged */
#define EHOSTDOWN 64 /* Host is down */
#define EHOSTUNREACH 65 /* No route to host */
#define ENOTEMPTY 66 /* Directory not empty */
#define ENOLCK 77 /* No locks available */
#define ENOSYS 78 /* Function not implemented */
#ifndef _POSIX_SOURCE
#define ELOOK 67 /* Internal mapping for kOTLookErr, don't return to client */
#define ELAST 78 /* Must be equal largest errno */
#endif /* _POSIX_SOURCE */

56
GUSI/include/sys/filio.h Executable file
View File

@ -0,0 +1,56 @@
/*-
* Copyright (c) 1982, 1986, 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)filio.h 8.1 (Berkeley) 3/28/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_FILIO_H_
#define _SYS_FILIO_H_
#include <sys/ioccom.h>
/* Generic file-descriptor ioctl's. */
#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
#define FIONCLEX _IO('f', 2) /* remove close on exec */
#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
#define FIOSETOWN _IOW('f', 124, int) /* set owner */
#define FIOGETOWN _IOR('f', 123, int) /* get owner */
#endif /* !_SYS_FILIO_H_ */

65
GUSI/include/sys/ioccom.h Executable file
View File

@ -0,0 +1,65 @@
/*-
* Copyright (c) 1982, 1986, 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ioccom.h 8.2 (Berkeley) 3/28/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_IOCCOM_H_
#define _SYS_IOCCOM_H_
/*
* Ioctl's have the command encoded in the lower word, and the size of
* any in or out parameters in the upper word. The high 3 bits of the
* upper word are used to encode the in/out status of the parameter.
*/
#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */
#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16))
#define IOCGROUP(x) (((x) >> 8) & 0xff)
#define IOCPARM_MAX NBPG /* max size of ioctl, mult. of NBPG */
#define IOC_VOID 0x20000000 /* no parameters */
#define IOC_OUT 0x40000000 /* copy out parameters */
#define IOC_IN 0x80000000 /* copy in parameters */
#define IOC_INOUT (IOC_IN|IOC_OUT)
#define IOC_DIRMASK 0xe0000000 /* mask for IN/OUT/VOID */
#define _IOC(inout,group,num,len) \
(inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num))
#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0)
#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t))
/* this should be _IORW, but stdio got there first */
#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
#endif /* !_SYS_IOCCOM_H_ */

71
GUSI/include/sys/ioctl.h Executable file
View File

@ -0,0 +1,71 @@
/*-
* Copyright (c) 1982, 1986, 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ioctl.h 8.6 (Berkeley) 3/28/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_IOCTL_H_
#define _SYS_IOCTL_H_
#include <sys/ttycom.h>
/*
* Pun for SunOS prior to 3.2. SunOS 3.2 and later support TIOCGWINSZ
* and TIOCSWINSZ (yes, even 3.2-3.5, the fact that it wasn't documented
* nonwithstanding).
*/
struct ttysize {
unsigned short ts_lines;
unsigned short ts_cols;
unsigned short ts_xxx;
unsigned short ts_yyy;
};
#define TIOCGSIZE TIOCGWINSZ
#define TIOCSSIZE TIOCSWINSZ
#include <sys/ioccom.h>
#include <sys/filio.h>
#include <sys/sockio.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
int ioctl __P((int, unsigned long, ...));
__END_DECLS
#endif /* !_SYS_IOCTL_H_ */

55
GUSI/include/sys/ppc.h Executable file
View File

@ -0,0 +1,55 @@
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSIPPC.nw - Program-Program Communications
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:18 chombier
// % Initial import
// %
// % Revision 1.9 2000/10/29 19:13:57 neeri
// % Numerous fixes to make it actually work
// %
// % Revision 1.8 2000/10/16 04:34:23 neeri
// % Releasing 2.1.2
// %
// % Revision 1.7 2000/05/23 07:15:31 neeri
// % Improve formatting
// %
// % Revision 1.6 2000/03/06 06:10:00 neeri
// % Reorganize Yield()
// %
// % Revision 1.5 1999/11/15 07:21:36 neeri
// % Add GUSIwithPPCSockets
// %
// % Revision 1.4 1999/08/26 05:45:07 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.3 1999/06/28 06:05:00 neeri
// % Support interrupted calls
// %
// % Revision 1.2 1999/06/08 04:31:30 neeri
// % Getting ready for 2.0b2
// %
// % Revision 1.1 1999/03/17 09:05:12 neeri
// % Added GUSITimer, expanded docs
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{The GUSI PPC Socket Class}
//
// The [[GUSIPPCSocket]] class implements communication via the Program-Program
// Communications Toolbox (For a change, the PPC does not stand for ``PowerPC''
// here).
//
// We give PPC sockets their own official looking header.
//
// <sys/ppc.h>=
#include <PPCToolbox.h>
struct sockaddr_ppc {
sa_family_t sppc_family; /* AF_PPC */
LocationNameRec sppc_location;
PPCPortRec sppc_port;
};

123
GUSI/include/sys/signal.h Executable file
View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)signal.h 8.2 (Berkeley) 1/21/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_SIGNAL_H_
#define _SYS_SIGNAL_H_
#include <sys/cdefs.h>
#define NSIG 32 /* counting 0; could be 33 (mask is 1-32) */
#ifndef _ANSI_SOURCE
#include <machine/signal.h> /* sigcontext; codes for SIGILL, SIGFPE */
#endif
__BEGIN_DECLS
typedef void (*__sig_handler)(int);
__END_DECLS
/* 1 is SIGABRT for MPW and CW */
#define SIGINT 2 /* interrupt */
#define SIGQUIT 3 /* quit */
/* 4 is SIGINT for CW */
#define SIGABRT 6 /* abort() */
#define SIGFPE 8 /* floating point exception */
#define SIGKILL 9 /* kill (cannot be caught or ignored) */
#define SIGSEGV 11 /* segmentation violation */
#define SIGPIPE 13 /* write on a pipe with no one to read it */
#define SIGALRM 14 /* alarm clock */
#define SIGTERM 15 /* software termination signal from kill */
#ifndef _POSIX_SOURCE
#define SIGURG 16 /* urgent condition on IO channel */
#endif
#define SIGSTOP 17 /* sendable stop signal not from tty */
#define SIGTSTP 18 /* stop signal from tty */
#define SIGCONT 19 /* continue a stopped process */
#define SIGCHLD 20 /* to parent on child stop or exit */
#define SIGTTIN 21 /* to readers pgrp upon background tty read */
#define SIGTTOU 22 /* like TTIN for output if (tp->t_local&LTOSTOP) */
#define SIGHUP 24 /* hangup */
#define SIGILL 25 /* illegal instruction (not reset when caught) */
#ifndef _POSIX_SOURCE
#define SIGIO 23 /* input/output possible signal */
#define SIGPROF 27 /* profiling time alarm */
#define SIGWINCH 28 /* window size changes */
#endif
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
#define SIG_DFL (__sig_handler)0
#define SIG_IGN (__sig_handler)1
#define SIG_ERR (__sig_handler)-1
#ifndef _ANSI_SOURCE
typedef unsigned int sigset_t;
/*
* Signal vector "template" used in sigaction call.
*/
struct sigaction {
__sig_handler sa_handler; /* signal handler */
sigset_t sa_mask; /* signal mask to apply */
int sa_flags; /* see signal options below */
};
#define SA_NOCLDSTOP 0x0008 /* do not generate SIGCHLD on child stop */
#define SA_RESETHAND 0x0001 /* emulate ANSI signals */
#define SA_RESTART 0x0002 /* restart slow system calls */
#define SA_NODEFER 0x0004 /* don't block current signal */
/*
* Flags for sigprocmask:
*/
#define SIG_BLOCK 1 /* block specified signal set */
#define SIG_UNBLOCK 2 /* unblock specified signal set */
#define SIG_SETMASK 3 /* set specified signal set */
#endif /* !_ANSI_SOURCE */
/*
* For historical reasons; programs expect signal's return value to be
* defined by <sys/signal.h>.
*/
__BEGIN_DECLS
__sig_handler signal __P((int, __sig_handler));
__END_DECLS
#endif /* !_SYS_SIGNAL_H_ */

266
GUSI/include/sys/socket.h Executable file
View File

@ -0,0 +1,266 @@
/*
* Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)socket.h 8.4 (Berkeley) 2/21/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_SOCKET_H_
#define _SYS_SOCKET_H_
/*
* Definitions related to sockets: types, address families, options.
*/
/*
* Types
*/
#define SOCK_STREAM 1 /* stream socket */
#define SOCK_DGRAM 2 /* datagram socket */
#define SOCK_RAW 3 /* raw-protocol interface */
#define SOCK_RDM 4 /* reliably-delivered message */
#define SOCK_SEQPACKET 5 /* sequenced packet stream */
/*
* Option flags per-socket.
*/
#define SO_DEBUG 0x0001 /* turn on debugging info recording */
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
#define SO_DONTROUTE 0x0010 /* just use interface addresses */
#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
/*
* Additional options, not kept in so_options.
*/
#define SO_SNDBUF 0x1001 /* send buffer size */
#define SO_RCVBUF 0x1002 /* receive buffer size */
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
#define SO_RCVTIMEO 0x1006 /* receive timeout */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
/* Mandated by XNS -- neeri */
typedef unsigned socklen_t;
/*
* Structure used for manipulating linger option.
*/
struct linger {
int l_onoff; /* option on/off */
int l_linger; /* linger time */
};
/*
* Level number for (get/set)sockopt() to apply to socket itself.
*/
#define SOL_SOCKET 0xffff /* options for socket level */
/*
* Address families.
*/
#define AF_UNSPEC 0 /* unspecified */
#define AF_LOCAL 1 /* local to host (pipes, portals) */
#define AF_UNIX AF_LOCAL /* backward compatibility */
#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
#define AF_PPC 3 /* PPC Toolbox */
#define AF_PAP 4 /* Printer Access Protocol */
#define AF_APPLETALK 16 /* Apple Talk */
#define ATALK_SYMADDR 272 /* Symbolic Address for AppleTalk */
#define AF_MAX 20
#define PF_UNSPEC 0 /* unspecified */
#define PF_LOCAL 1 /* local to host (pipes, portals) */
#define PF_UNIX AF_LOCAL /* backward compatibility */
#define PF_INET 2 /* internetwork: UDP, TCP, etc. */
#define PF_PPC 3 /* PPC Toolbox */
#define PF_PAP 4 /* Printer Access Protocol */
#define PF_APPLETALK 16 /* Apple Talk */
/* Mandated by XNS -- neeri */
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#ifndef _SA_FAMILY_T_DEFINED
#define _SA_FAMILY_T_DEFINED
typedef unsigned short sa_family_t;
#endif
/*
* Structure used by kernel to store most
* addresses.
*/
struct sockaddr {
sa_family_t sa_family; /* address family */
char sa_data[14]; /* actually longer; address value */
};
/*
* Definitions for network related sysctl, CTL_NET.
*
* Second level is protocol family.
* Third level is protocol number.
*
* Further levels are defined by the individual families below.
*/
#define NET_MAXID AF_MAX
#define CTL_NET_NAMES { \
{ 0, 0 }, \
{ "unix", CTLTYPE_NODE }, \
{ "inet", CTLTYPE_NODE }, \
{ "ppc", CTLTYPE_NODE }, \
{ "pap", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "", CTLTYPE_NODE }, \
{ "appletalk", CTLTYPE_NODE }, \
}
/*
* PF_ROUTE - Routing table
*
* Three additional levels are defined:
* Fourth: address family, 0 is wildcard
* Fifth: type of info, defined below
* Sixth: flag(s) to mask with for NET_RT_FLAGS
*/
#define NET_RT_DUMP 1 /* dump; may limit to a.f. */
#define NET_RT_FLAGS 2 /* by flags, e.g. RESOLVING */
#define NET_RT_IFLIST 3 /* survey interface list */
#define NET_RT_MAXID 4
#define CTL_NET_RT_NAMES { \
{ 0, 0 }, \
{ "dump", CTLTYPE_STRUCT }, \
{ "flags", CTLTYPE_STRUCT }, \
{ "iflist", CTLTYPE_STRUCT }, \
}
/*
* Maximum queue length specifiable by listen.
*/
#define SOMAXCONN 5
/*
* Message header for recvmsg and sendmsg calls.
* Used value-result for recvmsg, value only for sendmsg.
*/
struct msghdr {
void * msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
int msg_iovlen; /* # elements in msg_iov */
void * msg_control; /* ancillary data, see below */
socklen_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
#define MSG_OOB 0x1 /* process out-of-band data */
#define MSG_PEEK 0x2 /* peek at incoming message */
#define MSG_DONTROUTE 0x4 /* send without using routing tables */
#define MSG_EOR 0x8 /* data completes record */
#define MSG_TRUNC 0x10 /* data discarded before delivery */
#define MSG_CTRUNC 0x20 /* control data lost before delivery */
#define MSG_WAITALL 0x40 /* wait for full request or error */
#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */
/*
* Header for ancillary data objects in msg_control buffer.
* Used for additional information with/about a datagram
* not expressible by flags. The format is a sequence
* of message elements headed by cmsghdr structures.
*/
struct cmsghdr {
socklen_t cmsg_len; /* data byte count, including hdr */
int cmsg_level; /* originating protocol */
int cmsg_type; /* protocol-specific type */
/* followed by u_char cmsg_data[]; */
};
/* given pointer to struct cmsghdr, return pointer to data */
#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
/* given pointer to struct cmsghdr, return pointer to next cmsghdr */
#define CMSG_NXTHDR(mhdr, cmsg) \
(((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
(mhdr)->msg_control + (mhdr)->msg_controllen) ? \
(struct cmsghdr *)NULL : \
(struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
/* "Socket"-level control message types: */
#define SCM_RIGHTS 0x01 /* access rights (array of int) */
#include <sys/cdefs.h>
__BEGIN_DECLS
int accept __P((int, struct sockaddr *, socklen_t *));
int bind __P((int, const struct sockaddr *, socklen_t));
int connect __P((int, const struct sockaddr *, socklen_t));
int getpeername __P((int, struct sockaddr *, socklen_t *));
int getsockname __P((int, struct sockaddr *, socklen_t *));
int getsockopt __P((int, int, int, void *, socklen_t *));
int listen __P((int, int));
ssize_t recv __P((int, void *, size_t, int));
ssize_t recvfrom __P((int, void *, size_t, int, struct sockaddr *, socklen_t *));
ssize_t recvmsg __P((int, struct msghdr *, int));
ssize_t send __P((int, const void *, size_t, int));
ssize_t sendto __P((int, const void *,
size_t, int, const struct sockaddr *, socklen_t));
ssize_t sendmsg __P((int, const struct msghdr *, int));
int setsockopt __P((int, int, int, const void *, socklen_t));
int shutdown __P((int, int));
int socket __P((int, int, int));
int socketpair __P((int, int, int, int *));
__END_DECLS
#endif /* !_SYS_SOCKET_H_ */

78
GUSI/include/sys/sockio.h Executable file
View File

@ -0,0 +1,78 @@
/*-
* Copyright (c) 1982, 1986, 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)sockio.h 8.1 (Berkeley) 3/28/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_SOCKIO_H_
#define _SYS_SOCKIO_H_
#include <sys/ioccom.h>
/* Socket ioctl's. */
#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */
#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */
#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */
#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */
#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */
#define SIOCSPGRP _IOW('s', 8, int) /* set process group */
#define SIOCGPGRP _IOR('s', 9, int) /* get process group */
#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */
#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */
#define OSIOCGIFADDR _IOWR('i', 13, struct ifreq) /* get ifnet address */
#define SIOCGIFADDR _IOWR('i', 33, struct ifreq) /* get ifnet address */
#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */
#define OSIOCGIFDSTADDR _IOWR('i', 15, struct ifreq) /* get p-p address */
#define SIOCGIFDSTADDR _IOWR('i', 34, struct ifreq) /* get p-p address */
#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */
#define SIOCGIFFLAGS _IOWR('i', 17, struct ifreq) /* get ifnet flags */
#define OSIOCGIFBRDADDR _IOWR('i', 18, struct ifreq) /* get broadcast addr */
#define SIOCGIFBRDADDR _IOWR('i', 35, struct ifreq) /* get broadcast addr */
#define SIOCSIFBRDADDR _IOW('i', 19, struct ifreq) /* set broadcast addr */
#define OSIOCGIFCONF _IOWR('i', 20, struct ifconf) /* get ifnet list */
#define SIOCGIFCONF _IOWR('i', 36, struct ifconf) /* get ifnet list */
#define OSIOCGIFNETMASK _IOWR('i', 21, struct ifreq) /* get net addr mask */
#define SIOCGIFNETMASK _IOWR('i', 37, struct ifreq) /* get net addr mask */
#define SIOCSIFNETMASK _IOW('i', 22, struct ifreq) /* set net addr mask */
#define SIOCGIFMETRIC _IOWR('i', 23, struct ifreq) /* get IF metric */
#define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) /* set IF metric */
#define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */
#define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */
#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */
#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */
#endif /* !_SYS_SOCKIO_H_ */

111
GUSI/include/sys/stat.h Executable file
View File

@ -0,0 +1,111 @@
/*-
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)stat.h 8.6 (Berkeley) 3/8/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_STAT_H_
#define _SYS_STAT_H_
#include <time.h>
struct stat {
dev_t st_dev; /* inode's device */
ino_t st_ino; /* inode's number */
mode_t st_mode; /* inode protection mode */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of the file's owner */
gid_t st_gid; /* group ID of the file's group */
dev_t st_rdev; /* device type */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last data modification */
time_t st_ctime; /* time of last file status change */
off_t st_size; /* file size, in bytes */
long st_blocks; /* blocks allocated for file */
unsigned long st_blksize; /* optimal blocksize for I/O */
unsigned long st_flags; /* user defined flags for file */
};
#define S_ISUID 0004000 /* set user id on execution */
#define S_ISGID 0002000 /* set group id on execution */
#define S_IRWXU 0000700 /* RWX mask for owner */
#define S_IRUSR 0000400 /* R for owner */
#define S_IWUSR 0000200 /* W for owner */
#define S_IXUSR 0000100 /* X for owner */
#define S_IRWXG 0000070 /* RWX mask for group */
#define S_IRGRP 0000040 /* R for group */
#define S_IWGRP 0000020 /* W for group */
#define S_IXGRP 0000010 /* X for group */
#define S_IRWXO 0000007 /* RWX mask for other */
#define S_IROTH 0000004 /* R for other */
#define S_IWOTH 0000002 /* W for other */
#define S_IXOTH 0000001 /* X for other */
#define S_IFMT 0170000 /* type of file mask */
#define S_IFIFO 0010000 /* named pipe (fifo) */
#define S_IFCHR 0020000 /* character special */
#define S_IFDIR 0040000 /* directory */
#define S_IFBLK 0060000 /* block special */
#define S_IFREG 0100000 /* regular */
#define S_IFLNK 0120000 /* symbolic link */
#define S_IFSOCK 0140000 /* socket */
#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */
#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */
#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */
#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */
#define S_ISFIFO(m) ((m & 0170000) == 0100000 || \
(m & 0170000) == 0140000) /* fifo or socket */
#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */
#define S_ISSOCK(m) ((m & 0170000) == 0100000 || \
(m & 0170000) == 0140000) /* fifo or socket */
#include <sys/cdefs.h>
__BEGIN_DECLS
int chmod __P((const char *, mode_t));
int fstat __P((int, struct stat *));
int mkdir __P((const char *, ...));
int stat __P((const char *, struct stat *));
int lstat __P((const char *, struct stat *));
__END_DECLS
#endif /* !_SYS_STAT_H_ */

153
GUSI/include/sys/time.h Executable file
View File

@ -0,0 +1,153 @@
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)time.h 8.1 (Berkeley) 6/2/93
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_TIME_H_
#define _SYS_TIME_H_
#include <time.h>
#include <sys/types.h>
/*
* Structure returned by gettimeofday(2) system call,
* and used in other calls.
*/
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* and microseconds */
};
/*
* Structure defined by POSIX.4 to be like a timeval.
*/
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* and nanoseconds */
};
#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
}
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
(tv)->tv_sec = (ts)->tv_sec; \
(tv)->tv_usec = (ts)->tv_nsec / 1000; \
}
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
#define DST_NONE 0 /* not on dst */
#define DST_USA 1 /* USA style dst */
#define DST_AUST 2 /* Australian style dst */
#define DST_WET 3 /* Western European dst */
#define DST_MET 4 /* Middle European dst */
#define DST_EET 5 /* Eastern European dst */
#define DST_CAN 6 /* Canada */
/* Operations on timevals. */
#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
/*
* Names of the interval timers, and structure
* defining a timer setting.
*/
#define ITIMER_REAL 0
#define ITIMER_VIRTUAL 1
#define ITIMER_PROF 2
struct itimerval {
struct timeval it_interval; /* timer interval */
struct timeval it_value; /* current value */
};
/*
* Getkerninfo clock information structure
*/
struct clockinfo {
int hz; /* clock frequency */
int tick; /* micro-seconds per hz tick */
int stathz; /* statistics clock frequency */
int profhz; /* profiling clock frequency */
};
#define NBBY 8 /* number of bits in a byte */
/*
* Select uses bit masks of file descriptors in longs. These macros
* manipulate such bit fields (the filesystem macros use chars).
* FD_SETSIZE may be defined by the user, but the default here should
* be enough for most uses.
*/
#ifndef FD_SETSIZE
#define FD_SETSIZE 256
#endif
typedef long fd_mask;
#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
typedef struct fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} fd_set;
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_COPY(f, t) memcpy(t, f, sizeof(*(f)))
#define FD_ZERO(p) memset(p, 0, sizeof(*(p)))
#include <time.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
int getitimer __P((int, struct itimerval *));
int gettimeofday __P((struct timeval *, struct timezone *));
int setitimer __P((int, const struct itimerval *, struct itimerval *));
int utimes __P((const char *, const struct timeval *));
int select __P((int, fd_set *, fd_set *, fd_set *, struct timeval *));
__END_DECLS
#endif /* !_SYS_TIME_H_ */

134
GUSI/include/sys/ttycom.h Executable file
View File

@ -0,0 +1,134 @@
/*-
* Copyright (c) 1982, 1986, 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ttycom.h 8.1 (Berkeley) 3/28/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_TTYCOM_H_
#define _SYS_TTYCOM_H_
/* MPW specific codes */
#define FIOINTERACTIVE (('f'<<8)|0x02) /* If device is interactive */
#define FIOREFNUM (('f'<<8)|0x05) /* Return fs refnum */
#define FIOSETEOF (('f'<<8)|0x06) /* Set file length */
#include <sys/ioccom.h>
/*
* Tty ioctl's except for those supported only for backwards compatibility
* with the old tty driver.
*/
/*
* Window/terminal size structure. This information is stored by the kernel
* in order to provide a consistent interface, but is not used by the kernel.
*/
struct winsize {
unsigned short ws_row; /* rows, in characters */
unsigned short ws_col; /* columns, in characters */
unsigned short ws_xpixel; /* horizontal size, pixels */
unsigned short ws_ypixel; /* vertical size, pixels */
};
#define TIOCMODG _IOR('t', 3, int) /* get modem control state */
#define TIOCMODS _IOW('t', 4, int) /* set modem control state */
#define TIOCM_LE 0001 /* line enable */
#define TIOCM_DTR 0002 /* data terminal ready */
#define TIOCM_RTS 0004 /* request to send */
#define TIOCM_ST 0010 /* secondary transmit */
#define TIOCM_SR 0020 /* secondary receive */
#define TIOCM_CTS 0040 /* clear to send */
#define TIOCM_CAR 0100 /* carrier detect */
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RNG 0200 /* ring */
#define TIOCM_RI TIOCM_RNG
#define TIOCM_DSR 0400 /* data set ready */
/* 8-10 compat */
#define TIOCEXCL _IO('t', 13) /* set exclusive use of tty */
#define TIOCNXCL _IO('t', 14) /* reset exclusive use of tty */
/* 15 unused */
#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */
/* 17-18 compat */
#define TIOCGETA _IOR('t', 19, struct termios) /* get termios struct */
#define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */
#define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */
#define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */
#define TIOCGETD _IOR('t', 26, int) /* get line discipline */
#define TIOCSETD _IOW('t', 27, int) /* set line discipline */
/* 127-124 compat */
#define TIOCSBRK _IO('t', 123) /* set break bit */
#define TIOCCBRK _IO('t', 122) /* clear break bit */
#define TIOCSDTR _IO('t', 121) /* set data terminal ready */
#define TIOCCDTR _IO('t', 120) /* clear data terminal ready */
#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */
#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */
/* 117-116 compat */
#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
#define TIOCSTI _IOW('t', 114, char) /* simulate terminal input */
#define TIOCNOTTY _IO('t', 113) /* void tty association */
#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */
#define TIOCPKT_DATA 0x00 /* data packet */
#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */
#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */
#define TIOCPKT_STOP 0x04 /* stop output */
#define TIOCPKT_START 0x08 /* start output */
#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */
#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */
#define TIOCMBIS _IOW('t', 108, int) /* bis modem bits */
#define TIOCMBIC _IOW('t', 107, int) /* bic modem bits */
#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */
#define TIOCREMOTE _IOW('t', 105, int) /* remote input editing */
#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */
#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */
#define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */
#define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */
#define TIOCCONS _IOW('t', 98, int) /* become virtual console */
#define TIOCSCTTY _IO('t', 97) /* become controlling tty */
#define TIOCEXT _IOW('t', 96, int) /* pty: external processing */
#define TIOCSIG _IO('t', 95) /* pty: generate signal */
#define TIOCDRAIN _IO('t', 94) /* wait till output drained */
#define TTYDISC 0 /* termios tty line discipline */
#define TABLDISC 3 /* tablet discipline */
#define SLIPDISC 4 /* serial IP discipline */
#endif /* !_SYS_TTYCOM_H_ */

96
GUSI/include/sys/types.h Executable file
View File

@ -0,0 +1,96 @@
/*-
* Copyright (c) 1982, 1986, 1991, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)types.h 8.4 (Berkeley) 1/21/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_TYPES_H_
#define _SYS_TYPES_H_
/* Machine type dependent parameters. */
#include <machine/endian.h>
#ifndef _POSIX_SOURCE
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef char * caddr_t; /* core address */
#endif
typedef unsigned long dev_t; /* device number */
typedef unsigned long gid_t; /* group id */
typedef unsigned long ino_t; /* inode number */
typedef unsigned short mode_t; /* permissions */
typedef unsigned short nlink_t; /* link count */
typedef long off_t; /* file offset */
typedef long pid_t; /* process id */
typedef unsigned long uid_t; /* user id */
typedef long suseconds_t;/* Microseconds */
typedef unsigned long useconds_t;/* Microseconds */
/*
* This belongs in unistd.h, but is placed here to ensure that programs
* casting the second parameter of lseek to off_t will get the correct
* version of lseek.
*/
#include <sys/cdefs.h>
__BEGIN_DECLS
off_t lseek __P((int, off_t, int));
__END_DECLS
#include <machine/ansi.h>
/* Pthreads data types */
#include <pthread.h>
/* To avoid ugly namespace issues, we borrow all ANSI C defined types
from ANSI headers
*/
/* size_t */
#include <stddef.h>
/* time_t and clock_t */
#include <time.h>
#ifdef _BSD_SSIZE_T_
typedef _BSD_SSIZE_T_ ssize_t;
#undef _BSD_SSIZE_T_
#endif
#endif /* !_SYS_TYPES_H_ */

51
GUSI/include/sys/uio.h Executable file
View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 1982, 1986, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* [¤3 Deleted as of 22Jul99, see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* for details]
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)uio.h 8.5 (Berkeley) 2/22/94
*/
/* Adapted for GUSI by Matthias Neeracher <neeri@iis.ee.ethz.ch> */
#ifndef _SYS_UIO_H_
#define _SYS_UIO_H_
struct iovec {
void *iov_base; /* Base address. */
size_t iov_len; /* Length. */
};
#include <sys/cdefs.h>
__BEGIN_DECLS
ssize_t readv __P((int, const struct iovec *, int));
ssize_t writev __P((int, const struct iovec *, int));
__END_DECLS
#endif /* !_SYS_UIO_H_ */

Some files were not shown because too many files have changed in this diff Show More