Plan 9 from Bell Labs’s /usr/web/sources/contrib/de0u/root/sys/src/cmd/squeak/Plan9/vm/sqPlan9main.c.bak

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
 * General squeak functions and interpreter entrypoint for Plan9.
 *
 * Author: Alex Franchuk (alex.franchuk@gmail.com)
 */

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include "sq.h"
#include "p9iface.h"

#define DefaultHeapSize 20      /* megabytes BEYOND actual image size */

int    argCnt=		0;	/* global copies for access from plugins */
char **argVec=		0;
char **envVec=		0;

static int    vmArgCnt=		0;	/* for getAttributeIntoLength() */
static char **vmArgVec=		0;
static int    squeakArgCnt=	0;
static char **squeakArgVec=	0;

static long   extraMemory=	0;

char   imageName[MAXPATHLEN+1]; /* full path to image */
char   shortImageName[MAXPATHLEN+1];	/* image name */
char   vmName[MAXPATHLEN+1];     /* full path to VM */
char   vmPath[MAXPATHLEN+1];     /* full path to image directory */


/*** errors ***/
static void outOfMemory(void)
{
  fprintf(stderr, "out of memory\n");
  exit(1);
}

static void sigsegv(int ignore)
{
  printf("\nSegmentation fault\n\n");
}


static void parseArguments(int argc, char **argv)
{
# define skipArg()	(--argc, argv++)
# define saveArg()	(vmArgVec[vmArgCnt++]= *skipArg())

	saveArg();	/* vm name */

	while ((argc > 0) && (**argv == '-'))	{ /* more options to parse */
		if (!strcmp(*argv, "--")) break; /* escape from option processing */

		/* Skip all options for now */
		skipArg();
	}

	if (!argc) return;
	
	if (!strcmp(*argv, "--")) skipArg();
	else { /* image name */
		strcpy(shortImageName, saveArg());

		if (!strstr(shortImageName, ".image"))
			strcat(shortImageName, ".image");
	}

	getcwd(imageName,sizeof(imageName));
	strcat(imageName, "/");
	strcat(imageName, shortImageName);
	strcpy(vmPath, imageName);
	int lastslash = -1;
	for (int i = 0; i < sizeof(vmPath) && vmPath[i] != '\0'; i++) {
		if (vmPath[i] == '/') {
			lastslash = i;
		}
	}
	if (lastslash != -1) {
		vmPath[lastslash+1] = '\0';
	}
	/*cleanname(imageName);*/

	/* save remaining arguments as Squeak arguments */
	while (argc > 0)
		squeakArgVec[squeakArgCnt++]= *skipArg();

# undef saveArg
# undef skipArg
}

void imgInit(void)
{
	/* read the image file and allocate memory for Squeak heap */
	FILE *f = 0;
	struct stat sb;
	char imageName[MAXPATHLEN];

	strcpy(imageName, shortImageName);
	
	if ((-1 == stat(imageName, &sb)) || (0 == (f = fopen(imageName, "r")))) {
		fprintf(stderr, "Image file could not be opened: %s", imageName);
		exit(1);
	}
	
	extraMemory = DefaultHeapSize * 1024 *1024;
	extraMemory += (long)sb.st_size;
	readImageFromFileHeapSize(f, extraMemory);
	sqImageFileClose(f);
}

/*** interpreter entrypoint ***/
int main(int argc, char **argv, char **envp) {
	/* Make parameters global for access from plugins */
	argCnt= argc;
	argVec= argv;
	envVec= envp;

	/* Allocate arrays to store copies of pointers to command line
		arguments.  Used by getAttributeIntoLength(). */

	if ((vmArgVec= calloc(argc + 1, sizeof(char *))) == 0)
		outOfMemory();

	if ((squeakArgVec= calloc(argc + 1, sizeof(char *))) == 0)
		outOfMemory();

	signal(SIGSEGV, sigsegv);

#if defined(HAVE_TZSET)
	tzset();	/* should _not_ be necessary! */
#endif

	parseArguments(argc, argv);

	/* fill in vm path */
	getcwd(vmName, sizeof(vmName));
	strcat(vmName,"/");
	strcat(vmName, argVec[0]);

	/* init system */
	if (displayInit() == -1) {
		printf("Failed to initialize display\n");
		return EXIT_FAILURE;
	}
	if (ioInit() == -1) {
		printf("Failed to initialize keyboard/mouse\n");
		return EXIT_FAILURE;
	}
	imgInit();
	timeInit();

	/* run Squeak */
	interpret();

	/* destroy data from initialization */
	ioDestroy();
	displayDestroy();
	
	return EXIT_SUCCESS;
}

/* Copy aFilenameString to aCharBuffer and optionally resolveAlias (or
   symbolic link) to the real path of the target.  Answer 0 if
   successful of -1 to indicate an error.  Assume aCharBuffer is at
   least MAXPATHLEN bytes long.  Note that MAXSYMLINKS is a lower bound
   on the (potentially unlimited) number of symlinks allowed in a
   path, but calling sysconf() seems like overkill. */

sqInt sqGetFilenameFromString(char *aCharBuffer, char *aFilenameString, sqInt filenameLength, sqInt resolveAlias)
{
  int numLinks= 0;
  struct stat st;

  if ((filenameLength < 0) || (filenameLength > MAXPATHLEN)) {
  	  return -1;
  }
  strncpy(aCharBuffer, aFilenameString, filenameLength);

  return 0;
}

/* Attribute functions */
static char *getAttribute(sqInt id)
{
	if (id < 0) {
		if (-id  < vmArgCnt)
			return vmArgVec[-id];
	}
	else switch (id) {
		case 0:
			return vmName[0] ? vmName : vmArgVec[0];
		case 1:
			return imageName;
		case 1001:
			/* OS type: "unix", "win32", "mac", ... */
			return OS_TYPE;
		case 1002:
			/* OS name: "solaris2.5" on unix, "win95" on win32, ... */
			return VM_HOST_OS;
		case 1003:
			/* processor architecture: "68k", "x86", "PowerPC", ...  */
			return VM_HOST_CPU;
		case 1004:
			/* Interpreter version string */
			return  (char *)interpreterVersion;
		case 1005:
			/* window system name */
			return  WINDOW_SYS_NAME;
		case 1006:
			/* vm build string */
			return VM_BUILD_STRING;
		default:
			if ((id - 2) < squeakArgCnt)
				return squeakArgVec[id - 2];
		}

	success(false);
	return "";
}

sqInt attributeSize(sqInt indexNumber) {
	return strlen(getAttribute(indexNumber));
}

sqInt getAttributeIntoLength(sqInt indexNumber, sqInt byteArrayIndex, sqInt length) {
	if (length > 0) {
		strncpy((char*)pointerForOop(byteArrayIndex), getAttribute(indexNumber), length);
	}
	return 0;
}


/* Image functions */
char *getImageName(void) {
	return imageName;
}

sqInt imageNameGetLength(sqInt sqImageNameIndex, sqInt length) {
	char* buf = (char*)pointerForOop(sqImageNameIndex);
	int count = length < strlen(imageName) ? length : strlen(imageName);

	strncpy(buf, imageName, count);
	return count;
}

sqInt imageNamePutLength(sqInt sqImageNameIndex, sqInt length) {
	char* buf = (char*)pointerForOop(sqImageNameIndex);
	int count = length < sizeof(imageName) ? length : sizeof(imageName) - 1;

	strncpy(imageName, buf, count);
	imageName[length] = '\0';
	return count;
}

sqInt imageNameSize(void) {
	return strlen(imageName);
}

sqInt vmPathSize(void) {
	return strlen(vmPath);
}

sqInt vmPathGetLength(sqInt sqVMPathIndex, sqInt length) {
	char* buf = (char*)pointerForOop(sqVMPathIndex);
	int count = length < strlen(vmPath) ? length : strlen(vmPath);

	strncpy(buf, vmPath, count);
	return count;
}

/* Image security traps */
sqInt ioCanRenameImage(void) {
	return true;
}

sqInt ioCanWriteImage(void) {
	return true;
}

sqInt ioDisableImageWrite(void) {
	return false;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.