text: /* Automatically generated by
  	VMPluginCodeGenerator VMMaker.oscog-eem.2944 uuid: 242b00d2-2d09-4363-8f25-cedcd6ee2187
     from
  	UnixAioPlugin VMConstruction-Plugins-AioPlugin.oscog-eem.26 uuid: 9d32c4ef-9646-4ce2-b069-44fe86a2dbfb
   */
  static char __buildInfo[] = "UnixAioPlugin VMConstruction-Plugins-AioPlugin.oscog-eem.26 uuid: 9d32c4ef-9646-4ce2-b069-44fe86a2dbfb " __DATE__ ;
  
  
  #include "config.h"
  #include <math.h>
  #include "sqMathShim.h"
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <time.h>
  #include <unistd.h>
  #define FILEHANDLETYPE FILE *  /* the type of low level stream to be used in a struct SQFile */
  
  /* Do not include the entire sq.h file but just those parts needed. */
  #include "sqConfig.h"			/* Configuration options */
  #include "sqVirtualMachine.h"	/*  The virtual machine proxy definition */
  #include "sqPlatformSpecific.h"	/* Platform specific definitions */
  
  #include "FilePlugin.h"
  #include "SocketPlugin.h"
  #include "config.h"
  #define SESSIONIDENTIFIERTYPE int
  #include "sqaio.h"
  #include "sqMemoryAccess.h"
  
  #define true 1
  #define false 0
  #define null 0  /* using 'null' because nil is predefined in Think C */
  #ifdef SQUEAK_BUILTIN_PLUGIN
  # undef EXPORT
  # define EXPORT(returnType) static returnType
  # define INT_EXT "(i)"
  #else
  # define INT_EXT "(e)"
  #endif
  
  
  /*** Function Prototypes ***/
  static void aioForwardwithDataandFlags(int fd, void *data, int flags);
  static sqInt fileDescriptorFrom(sqInt aSQFileByteArray);
  static FILEHANDLETYPE fileHandleFrom(sqInt sqFileStructByteArray);
  static usqIntptr_t fileRecordSize(void);
  static SQFile * fileValueOf(sqInt anSQFileRecord);
  EXPORT(const char*) getModuleName(void);
  static sqInt getThisSessionIdentifier(void);
  static sqInt isNonNullSQFile(sqInt objectPointer);
  static sqInt isNullSQSocket(sqInt objectPointer);
  static sqInt isSQFileObject(sqInt objectPointer);
  static sqInt isSQSocketObject(sqInt objectPointer);
  static sqInt isValidFileSession(sqInt objectPointer);
  EXPORT(sqInt) primitiveAioDisable(void);
  EXPORT(sqInt) primitiveAioEnable(void);
  EXPORT(sqInt) primitiveAioHandle(void);
  EXPORT(sqInt) primitiveAioSuspend(void);
  EXPORT(sqInt) primitiveModuleName(void);
  EXPORT(sqInt) primitiveOSFileHandle(void);
  EXPORT(sqInt) primitiveOSSocketHandle(void);
  EXPORT(sqInt) primitiveVersionString(void);
  EXPORT(sqInt) setInterpreter(struct VirtualMachine *anInterpreter);
  static int socketDescriptorFrom(sqInt sqSocketOop);
  static usqIntptr_t socketRecordSize(void);
  static SQSocket * socketValueOf(sqInt anSQSocketRecord);
  static char * versionString(void);
  
  
  /*** Variables ***/
  
  #if !defined(SQUEAK_BUILTIN_PLUGIN)
  static void * (*arrayValueOf)(sqInt oop);
  static sqInt (*booleanValueOf)(sqInt obj);
  static sqInt (*byteSizeOf)(sqInt oop);
  static sqInt (*failed)(void);
  static sqInt (*getThisSessionID)(void);
  static sqInt (*isBytes)(sqInt oop);
  static sqInt (*methodReturnInteger)(sqInt integer);
  static sqInt (*methodReturnString)(char *aCString);
  static sqInt (*primitiveFail)(void);
  static sqInt (*signalSemaphoreWithIndex)(sqInt semaIndex);
  static sqInt (*stackIntegerValue)(sqInt offset);
  static sqInt (*stackValue)(sqInt offset);
  #else /* !defined(SQUEAK_BUILTIN_PLUGIN) */
  extern void * arrayValueOf(sqInt oop);
  extern sqInt booleanValueOf(sqInt obj);
  extern sqInt byteSizeOf(sqInt oop);
  extern sqInt failed(void);
  extern sqInt getThisSessionID(void);
  extern sqInt isBytes(sqInt oop);
  extern sqInt methodReturnInteger(sqInt integer);
  extern sqInt methodReturnString(char *aCString);
  extern sqInt primitiveFail(void);
  extern sqInt signalSemaphoreWithIndex(sqInt semaIndex);
  extern sqInt stackIntegerValue(sqInt offset);
  extern sqInt stackValue(sqInt offset);
  extern
  #endif
  struct VirtualMachine* interpreterProxy;
  static const char *moduleName = "AioPlugin VMConstruction-Plugins-AioPlugin.oscog-eem.26 " INT_EXT;
  
  
  /*** Macros ***/
  #define sessionIdentifierFromSqFile(sqFile) (SESSIONIDENTIFIERTYPE) (((SQFile *)(sqFile))->sessionID)
  
  
  
  /*	This function is called to signal a Smalltalk Semaphore when an
  	asynchronous event is
  	detected. When translated to C, the name of this method is
  	aioForwardwithDataandFlags. The event handler is set up by
  	#primitiveAioHandle. 
   */
  
  	/* UnixAioPlugin>>#aioForward:withData:andFlags: */
  static void
  aioForwardwithDataandFlags(int fd, void *data, int flags)
  {
      int *pfd;
      sqInt semaIndex;
  
  	pfd = data;
  	semaIndex = *pfd;
  	signalSemaphoreWithIndex(semaIndex);
  }
  
  
  /*	Answer the OS file descriptor, an integer value, from a SQFile data
  	structure byte array, or answer -1 if unable to obtain the file descriptor
  	(probably due
  	to receiving an incorrect type of object as aFileHandle).
   */
  /*	return type should be int, but skip the declaration to permit inlining */
  
  	/* AioPlugin>>#fileDescriptorFrom: */
  static sqInt
  fileDescriptorFrom(sqInt aSQFileByteArray)
  {
  	if (!((((isBytes(aSQFileByteArray))
  		 && ((byteSizeOf(aSQFileByteArray)) == (sizeof(SQFile))))
  		 && ((getThisSessionID()) == (sessionIdentifierFromSqFile(arrayValueOf(aSQFileByteArray)))))
  		 && (isNonNullSQFile(aSQFileByteArray)))) {
  		return -1;
  	}
  	return fileno(fileHandleFrom(aSQFileByteArray));
  }
  
  
  /*	Answer a file handle from a SQFile structure. On most platforms, this
  	will be a (FILE *). On Win32, it is a HANDLE. */
  
  	/* AioPlugin>>#fileHandleFrom: */
  static FILEHANDLETYPE
  fileHandleFrom(sqInt sqFileStructByteArray)
  {
      SQFile *sqFile;
  
  	sqFile = arrayValueOf(sqFileStructByteArray);
  	return sqFile->file;
  }
  
  
  /*	Answer the size of a SQFile data structure in bytes. */
  
  	/* AioPlugin>>#fileRecordSize */
  static usqIntptr_t
  fileRecordSize(void)
  {
  	return sizeof(SQFile);
  }
  
  
  /*	Return a pointer to the first byte of of the SQFile data structure file
  	record within
  	anSQFileRecord, which is expected to be a ByteArray of size
  	self>>fileRecordSize. 
   */
  
  	/* AioPlugin>>#fileValueOf: */
  static SQFile *
  fileValueOf(sqInt anSQFileRecord)
  {
  	return arrayValueOf(anSQFileRecord);
  }
  
  
  /*	Note: This is hardcoded so it can be run from Squeak.
  	The module name is used for validating a module *after*
  	it is loaded to check if it does really contain the module
  	we're thinking it contains. This is important! */
  
  	/* InterpreterPlugin>>#getModuleName */
  EXPORT(const char*)
  getModuleName(void)
  {
  	return moduleName;
  }
  
  	/* AioPlugin>>#getThisSessionIdentifier */
  static sqInt
  getThisSessionIdentifier(void)
  {
  	return getThisSessionID();
  }
  
  
  /*	Check for the common failure mode of a SQFile record with all zeros. */
  
  	/* AioPlugin>>#isNonNullSQFile: */
  static sqInt
  isNonNullSQFile(sqInt objectPointer)
  {
      unsigned idx;
      unsigned char *sqFileBytes;
  
  	sqFileBytes = arrayValueOf(objectPointer);
  	idx = 0;
  	while (idx < (sizeof(SQFile))) {
  		if ((sqFileBytes[idx]) != 0) {
  			return 1;
  		}
  		idx += 1;
  	}
  	return 0;
  }
  
  
  /*	Check for the common failure mode of a SQSocket record with all zeros. */
  
  	/* AioPlugin>>#isNullSQSocket: */
  static sqInt
  isNullSQSocket(sqInt objectPointer)
  {
      sqInt idx;
      unsigned char *sqSocketBytes;
  
  	sqSocketBytes = arrayValueOf(objectPointer);
  	idx = 0;
  	while (idx < (sizeof(SQSocket))) {
  		if ((sqSocketBytes[idx]) != 0) {
  			return 0;
  		}
  		idx += 1;
  	}
  	return 1;
  }
  
  
  /*	Answer true if objectPointer appears to be a valid SQFile ByteArray.
  	This check is appropriate if objectPointer has been passed as a parameter
  	to a primitive, and is expected to represent a valid file reference. */
  
  	/* AioPlugin>>#isSQFileObject: */
  static sqInt
  isSQFileObject(sqInt objectPointer)
  {
  	return (((isBytes(objectPointer))
  	 && ((byteSizeOf(objectPointer)) == (sizeof(SQFile))))
  	 && ((getThisSessionID()) == (sessionIdentifierFromSqFile(arrayValueOf(objectPointer)))))
  	 && (isNonNullSQFile(objectPointer));
  }
  
  
  /*	Answer true if objectPointer appears to be a valid SQSocket ByteArray.
  	This check
  	is appropriate if objectPointer has been passed as a parameter to a
  	primitive, and
  	is expected to represent a valid socket reference.
   */
  
  	/* AioPlugin>>#isSQSocketObject: */
  static sqInt
  isSQSocketObject(sqInt objectPointer)
  {
  	return ((isBytes(objectPointer))
  	 && ((byteSizeOf(objectPointer)) == (sizeof(SQSocket))))
  	 && (!(isNullSQSocket(objectPointer)));
  }
  
  
  /*	Answer true if the file session matches the current interpreter session
  	identifier. 
   */
  
  	/* AioPlugin>>#isValidFileSession: */
  static sqInt
  isValidFileSession(sqInt objectPointer)
  {
  	return (getThisSessionID()) == (sessionIdentifierFromSqFile(arrayValueOf(objectPointer)));
  }
  
  
  /*	Definitively disable asynchronous event notification for a descriptor.
  	The parameter is an OS level integer file descriptor. */
  
  	/* UnixAioPlugin>>#primitiveAioDisable */
  EXPORT(sqInt)
  primitiveAioDisable(void)
  {
      sqInt fd;
  
  	fd = stackIntegerValue(0);
  	if ((failed())
  	 || (fd < 0)) {
  		return primitiveFail();
  	}
  	aioDisable(fd);
  	methodReturnInteger(fd);
  	return 0;
  }
  
  
  /*	Enable asynchronous notification for a descriptor. The first parameter is
  	an OS
  	level integer file descriptor. The second parameter is the index of a
  	Semaphore to
  	be notified, and the third parameter is a flag indicating that descriptor
  	represents an external object and should not be closed on termination of
  	aio handling. Answer
  	the semaphore index.
   */
  
  	/* UnixAioPlugin>>#primitiveAioEnable */
  EXPORT(sqInt)
  primitiveAioEnable(void)
  {
      static int eventSemaphoreIndices[FD_SETSIZE];
      sqInt externalNotification;
      sqInt fd;
      sqInt flags;
      sqInt semaIndex;
  
  	fd = stackIntegerValue(2);
  	semaIndex = stackIntegerValue(1);
  	externalNotification = booleanValueOf(stackValue(0));
  	if ((failed())
  	 || (fd < 0)) {
  		return primitiveFail();
  	}
  	eventSemaphoreIndices[semaIndex] = semaIndex;
  	flags = (externalNotification
  		? AIO_EXT
  		: 0);
  	aioEnable(fd, (&(eventSemaphoreIndices[semaIndex])), flags);
  	methodReturnInteger(semaIndex);
  	return 0;
  }
  
  
  /*	Handle asynchronous event notification for a descriptor. The first
  	parameter is
  	an OS level integer file descriptor. The remaining three parameters are
  	Boolean flags representing the types of events for which notification is
  	being requested:
  	handle exceptions, handle for read, and handle for write.
  	Flags are defined in the aio.h source as:
  	AIO_X	(1<<0)	handle for exceptions
  	AIO_R	(1<<1)	handle for read
  	AIO_W	(1<<2)	handle for write */
  
  	/* UnixAioPlugin>>#primitiveAioHandle */
  EXPORT(sqInt)
  primitiveAioHandle(void)
  {
      sqInt exceptionWatch;
      sqInt fd;
      sqInt flags;
      sqInt readWatch;
      sqInt writeWatch;
  
  	fd = stackIntegerValue(3);
  	exceptionWatch = booleanValueOf(stackValue(2));
  	readWatch = booleanValueOf(stackValue(1));
  	writeWatch = booleanValueOf(stackValue(0));
  	if (!(failed())) {
  		flags = 0;
  		if (fd < 0) {
  			return primitiveFail();
  		}
  		if (exceptionWatch) {
  			flags = flags | (AIO_X);
  		}
  		if (readWatch) {
  			flags = flags | (AIO_R);
  		}
  		if (writeWatch) {
  			flags = flags | (AIO_W);
  		}
  		aioHandle(fd, aioForwardwithDataandFlags, flags);
  		methodReturnInteger(flags);
  	}
  	return 0;
  }
  
  
  /*	Temporarily suspend asynchronous event notification for a descriptor. The
  	first parameter is an OS level integer file descriptor. The remaining
  	three parameters
  	are Boolean flags representing the types of events for which notification
  	is being
  	requested: handle exceptions, handle for read, and handle for write.
  	Flags are defined in the aio.h source as:
  	AIO_X	(1<<0)	handle for exceptions
  	AIO_R	(1<<1)	handle for read
  	AIO_W	(1<<2)	handle for write */
  
  	/* UnixAioPlugin>>#primitiveAioSuspend */
  EXPORT(sqInt)
  primitiveAioSuspend(void)
  {
      sqInt exceptionWatch;
      sqInt fd;
      sqInt flags;
      sqInt readWatch;
      sqInt writeWatch;
  
  	fd = stackIntegerValue(3);
  	exceptionWatch = booleanValueOf(stackValue(2));
  	readWatch = booleanValueOf(stackValue(1));
  	writeWatch = booleanValueOf(stackValue(0));
  	if (!(failed())) {
  		flags = 0;
  		if (fd < 0) {
  			return primitiveFail();
  		}
  		if (exceptionWatch) {
  			flags = flags | (AIO_X);
  		}
  		if (readWatch) {
  			flags = flags | (AIO_R);
  		}
  		if (writeWatch) {
  			flags = flags | (AIO_W);
  		}
  		aioSuspend(fd, flags);
  		methodReturnInteger(flags);
  	}
  	return 0;
  }
  
  
  /*	Answer a string containing the module name string for this plugin. */
  
  	/* AioPlugin>>#primitiveModuleName */
  EXPORT(sqInt)
  primitiveModuleName(void)
  {
  	methodReturnString(getModuleName());
  	return 0;
  }
  
  
  /*	Take a struct SQFile from the stack, and answer the value of its Unix file
  	number. 
   */
  
  	/* UnixAioPlugin>>#primitiveOSFileHandle */
  EXPORT(sqInt)
  primitiveOSFileHandle(void)
  {
      sqInt sqFileOop;
  
  	sqFileOop = stackValue(0);
  	if (!((((isBytes(sqFileOop))
  		 && ((byteSizeOf(sqFileOop)) == (sizeof(SQFile))))
  		 && ((getThisSessionID()) == (sessionIdentifierFromSqFile(arrayValueOf(sqFileOop)))))
  		 && (isNonNullSQFile(sqFileOop)))) {
  		return primitiveFail();
  	}
  	methodReturnInteger(fileDescriptorFrom(sqFileOop));
  	return 0;
  }
  
  
  /*	Take a struct SQSocket from the stack, and answer the value of its Unix
  	file number.
   */
  
  	/* UnixAioPlugin>>#primitiveOSSocketHandle */
  EXPORT(sqInt)
  primitiveOSSocketHandle(void)
  {
      int fileNo;
      sqInt sqSocketOop;
  
  	sqSocketOop = stackValue(0);
  	if (!((((isBytes(sqSocketOop))
  		 && ((byteSizeOf(sqSocketOop)) == (sizeof(SQSocket))))
  		 && (!(isNullSQSocket(sqSocketOop))))
  		 && (((fileNo = socketDescriptorFrom(sqSocketOop))) >= 0))) {
  		return primitiveFail();
  	}
  	methodReturnInteger(fileNo);
  	return 0;
  }
  
  
  /*	Answer a string containing the version string for this plugin. */
  
  	/* AioPlugin>>#primitiveVersionString */
  EXPORT(sqInt)
  primitiveVersionString(void)
  {
  	methodReturnString(versionString());
  	return 0;
  }
  
  
  /*	Note: This is coded so that it can be run in Squeak. */
  
  	/* InterpreterPlugin>>#setInterpreter: */
  EXPORT(sqInt)
  setInterpreter(struct VirtualMachine *anInterpreter)
  {
      sqInt ok;
  
  
  	/* This may seem tautological, but in a real plugin it checks that the VM provides
  	   the version the plugin was compiled against which is the version the plugin expects. */
  	interpreterProxy = anInterpreter;
  	ok = ((interpreterProxy->majorVersion()) == (VM_PROXY_MAJOR))
  	 && ((interpreterProxy->minorVersion()) >= (VM_PROXY_MINOR));
  	if (ok) {
  		
  #if !defined(SQUEAK_BUILTIN_PLUGIN)
  		arrayValueOf = interpreterProxy->arrayValueOf;
  		booleanValueOf = interpreterProxy->booleanValueOf;
  		byteSizeOf = interpreterProxy->byteSizeOf;
  		failed = interpreterProxy->failed;
  		getThisSessionID = interpreterProxy->getThisSessionID;
  		isBytes = interpreterProxy->isBytes;
  		methodReturnInteger = interpreterProxy->methodReturnInteger;
  		methodReturnString = interpreterProxy->methodReturnString;
  		primitiveFail = interpreterProxy->primitiveFail;
  		signalSemaphoreWithIndex = interpreterProxy->signalSemaphoreWithIndex;
  		stackIntegerValue = interpreterProxy->stackIntegerValue;
  		stackValue = interpreterProxy->stackValue;
  #endif /* !defined(SQUEAK_BUILTIN_PLUGIN) */
  	}
  	return ok;
  }
  
  
  /*	Answer the OS file descriptor, an integer value, from a SQSocket data
  	structure, or answer -1 if unable to obtain the file descriptor (probably
  	due to receiving
  	an incorrect type of object as aFileHandle).
  	
  	Warning: The first element of privateSocketStruct happens to be the Unix
  	file number of the socket. See sqUnixSocket.c for the definition. This
  	method takes
  	advantage of this, and will break if anyone ever redefines the data
  	structure. 
   */
  
  	/* AioPlugin>>#socketDescriptorFrom: */
  static int
  socketDescriptorFrom(sqInt sqSocketOop)
  {
      void *privateSocketStruct;
      SQSocket *sqSocket;
  
  	/* begin socketValueOf: */
  	sqSocket = arrayValueOf(sqSocketOop);
  	privateSocketStruct = sqSocket->privateSocketPtr;
  	if (privateSocketStruct == 0) {
  		return -1;
  	}
  	return * (int *) privateSocketStruct;
  }
  
  
  /*	Answer the size of a SQSocket data structure in bytes. */
  
  	/* AioPlugin>>#socketRecordSize */
  static usqIntptr_t
  socketRecordSize(void)
  {
  	return sizeof(SQSocket);
  }
  
  
  /*	Return a pointer to the first byte of of the SQsocket data structure
  	socket record within
  	anSQSocketRecord, which is expected to be a ByteArray of size
  	self>>socketRecordSize. 
   */
  
  	/* AioPlugin>>#socketValueOf: */
  static SQSocket *
  socketValueOf(sqInt anSQSocketRecord)
  {
  	return arrayValueOf(anSQSocketRecord);
  }
  
  
  /*	Answer a string containing the version string for this plugin. Handle MNU
  	errors, which can occur if class InterpreterPlugin has been removed from
  	the system.
  	
  	Important: When this method is changed, the class side method must also be
  	changed to match.
   */
  /*	2.0 supports 64bit code base */
  
  	/* AioPlugin>>#versionString */
  static char *
  versionString(void)
  {
      static char version[]= "2.2.6";
  
  	return version;
  }
  
  
  #ifdef SQUEAK_BUILTIN_PLUGIN
  
  static char _m[] = "AioPlugin";
  void* AioPlugin_exports[][3] = {
  	{(void*)_m, "getModuleName", (void*)getModuleName},
  	{(void*)_m, "primitiveAioDisable\000\000", (void*)primitiveAioDisable},
  	{(void*)_m, "primitiveAioEnable\000\000", (void*)primitiveAioEnable},
  	{(void*)_m, "primitiveAioHandle\000\000", (void*)primitiveAioHandle},
  	{(void*)_m, "primitiveAioSuspend\000\000", (void*)primitiveAioSuspend},
  	{(void*)_m, "primitiveModuleName\000\377", (void*)primitiveModuleName},
  	{(void*)_m, "primitiveOSFileHandle\000\001", (void*)primitiveOSFileHandle},
  	{(void*)_m, "primitiveOSSocketHandle\000\001", (void*)primitiveOSSocketHandle},
  	{(void*)_m, "primitiveVersionString\000\377", (void*)primitiveVersionString},
  	{(void*)_m, "setInterpreter", (void*)setInterpreter},
  	{NULL, NULL, NULL}
  };
  
  #else /* ifdef SQ_BUILTIN_PLUGIN */
  
  signed char primitiveAioDisableAccessorDepth = 0;
  signed char primitiveAioEnableAccessorDepth = 0;
  signed char primitiveAioHandleAccessorDepth = 0;
  signed char primitiveAioSuspendAccessorDepth = 0;
  signed char primitiveOSFileHandleAccessorDepth = 1;
  signed char primitiveOSSocketHandleAccessorDepth = 1;
  
  #endif /* ifdef SQ_BUILTIN_PLUGIN */
  