Skip to content

Commit

Permalink
I improved the automatic image search of the minheadless VM.
Browse files Browse the repository at this point in the history
  • Loading branch information
ronsaldo committed Jun 12, 2019
1 parent a661f1f commit adba21b
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 2 deletions.
9 changes: 9 additions & 0 deletions include/OpenSmalltalkVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ typedef enum
OSVM_ERROR_UNSUPPORTED_PARAMETER,
OSVM_ERROR_FAILED_TO_OPEN_FILE,
OSVM_ERROR_FAILED_TO_LOAD_IMAGE,
OSVM_ERROR_FAILED_TO_FIND_IMAGE,
} OSVMError;

/**
Expand All @@ -99,6 +100,14 @@ typedef struct OSVMInstance *OSVMInstanceHandle;
*/
OSVM_VM_CORE_PUBLIC int osvm_getInterfaceVersion(void);

/**
* This function finds a default startup image for a given VM executable path.
* \param startupImagePathResult A pointer to store the startup image path.
* Must be freed with osvm_free(). This can be NULL.
* \return 1 for found, 0 for not found.
*/
OSVM_VM_CORE_PUBLIC int osvm_findStartupImage(const char *vmExecutablePath, char **startupImagePathResult);

/**
* Simple all mighty main entry point for running an OpenSmalltalk VM
*/
Expand Down
2 changes: 1 addition & 1 deletion platforms/Cross/vm/sqPath.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
#elif defined(__unix__) || defined(__MACH__) || defined(__APPLE__)
#include <unistd.h>
#else
#include <string.h>
#define getcwd(target, targetSize) strcpy(target, ".")
#endif
#include <string.h>

#include "sqPath.h"
#include "sqTextEncoding.h"
Expand Down
131 changes: 130 additions & 1 deletion platforms/minheadless/common/sqVirtualMachineInterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

#ifndef _WIN32
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#endif

#include <stdio.h>
Expand All @@ -51,6 +53,10 @@ struct OSVMInstance
*/
extern int sqVMOptionTraceModuleLoading;

extern int osvm_isFile(const char *path);
extern int osvm_findImagesInFolder(const char *searchPath, char *imagePathBuffer, size_t imagePathBufferSize);


static struct OSVMInstance osvmInstanceSingleton;

char imageName[FILENAME_MAX];
Expand Down Expand Up @@ -463,6 +469,118 @@ parseArguments(int argc, char **argv)
return OSVM_SUCCESS;
}

#ifndef _WIN32
int
osvm_isFile(const char *path)
{
struct stat s;
if(stat(path, &s) == 0)
return s.st_mode & S_IFREG;

return 0;
}

int
osvm_findImagesInFolder(const char *searchPath, char *imagePathBuffer, size_t imagePathBufferSize)
{
struct dirent *entry;
int result = 0;
DIR *dir = opendir(searchPath);
if(!dir)
return 0;

while((entry = readdir(dir)) != NULL)
{
char *name = entry->d_name;
char *extension = strrchr(name, '.');
if(!extension)
continue;

if(strcmp(extension, ".image") != 0)
continue;

if(result == 0)
snprintf(imagePathBuffer, imagePathBufferSize, "%s/%s", searchPath, name);
++result;
}
closedir(dir);

return result;
}
#endif

OSVM_VM_CORE_PUBLIC int
osvm_findStartupImage(const char *vmExecutablePath, char **startupImagePathResult)
{
char *imagePathBuffer = osvm_malloc(FILENAME_MAX+1);
char *vmPathBuffer = osvm_malloc(FILENAME_MAX+1);
char *searchPathBuffer = osvm_malloc(FILENAME_MAX+1);
findExecutablePath(vmExecutablePath, vmPathBuffer, FILENAME_MAX+1);

if(startupImagePathResult)
*startupImagePathResult = NULL;

// Find the mandatory startup.image.
snprintf(imagePathBuffer, FILENAME_MAX+1, "%s/startup.image", vmPathBuffer);
if(osvm_isFile(imagePathBuffer))
{
if(startupImagePathResult)
*startupImagePathResult = imagePathBuffer;
else
osvm_free(imagePathBuffer);
osvm_free(vmPathBuffer);
osvm_free(searchPathBuffer);
return 1;
}

#ifdef __APPLE__
snprintf(imagePathBuffer, FILENAME_MAX+1, "%s/../Resources/startup.image", vmPathBuffer);
if(osvm_isFile(imagePathBuffer))
{
if(startupImagePathResult)
*startupImagePathResult = imagePathBuffer;
else
osvm_free(imagePathBuffer);
osvm_free(vmPathBuffer);
osvm_free(searchPathBuffer);
return 1;
}
#endif

// Find automatically an image.
int foundImageCount = 0;

// Search on the VM executable path.
foundImageCount += osvm_findImagesInFolder(vmPathBuffer, imagePathBuffer, FILENAME_MAX+1);

#ifdef __APPLE__
// Search along the bundled resources.
snprintf(searchPathBuffer, FILENAME_MAX+1, "%s/../Resources", vmPathBuffer);
foundImageCount += osvm_findImagesInFolder(searchPathBuffer, imagePathBuffer, FILENAME_MAX+1);
#endif

// Search in the current working directory.
sqGetCurrentWorkingDir(searchPathBuffer, FILENAME_MAX+1);
foundImageCount += osvm_findImagesInFolder(searchPathBuffer, imagePathBuffer, FILENAME_MAX+1);

osvm_free(vmPathBuffer);
osvm_free(searchPathBuffer);
if(foundImageCount == 1)
{
if(startupImagePathResult)
*startupImagePathResult = imagePathBuffer;
else
osvm_free(imagePathBuffer);
return 1;
}
else
{
// The image is not found or it is ambiguous.
osvm_free(imagePathBuffer);
return 0;
}
}

OSVM_VM_CORE_PUBLIC void *
osvm_malloc(size_t size)
{
Expand Down Expand Up @@ -552,7 +670,18 @@ osvm_loadDefaultImage(OSVMInstanceHandle vmHandle)

/* If the image name is empty, try to load the default image. */
if(!shortImageName[0])
strcpy(shortImageName, DEFAULT_IMAGE_NAME);
{
char *startupImage;
if(osvm_findStartupImage(vmPath, &startupImage))
{
strcpy(shortImageName, startupImage);
osvm_free(startupImage);
}
else
{
return OSVM_ERROR_FAILED_TO_FIND_IMAGE;
}
}

/* Try to load the image as was passed. */
sprintf(tempImageNameAttempt, "%s", shortImageName);
Expand Down
4 changes: 4 additions & 0 deletions platforms/minheadless/mac/sqMain.m
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ - (void) executeVMProcess
int
main(int argc, const char **argv)
{
// If there is a startup image, then we should just use it.
if(osvm_findStartupImage(argv[0], NULL))
return osvm_main(argc, argv);

// In OS X, the user may want to drop an image file to the VM application.
// Dropped image files are treated as events, whose reception is only
// obtained through the usage of an AppDelegate, which is tied to a
Expand Down
13 changes: 13 additions & 0 deletions platforms/minheadless/windows/sqWin32Directory.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,3 +488,16 @@ sqInt dir_Delete(char *pathString, sqInt pathLength) {
if (hasCaseSensitiveDuplicate(win32Path)) return false;
return RemoveDirectoryW(win32Path) == 0 ? false : true;
}

int osvm_isFile(const char *path)
{
/* TODO: Implement this */
return 0;
}

int
osvm_findImagesInFolder(const char *searchPath, char *imagePathBuffer, size_t imagePathBufferSize)
{
/* TODO: Implmenent this */
return 0;
}
4 changes: 4 additions & 0 deletions platforms/minheadless/windows/sqWin32Main.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
static WCHAR openImageDialogResultBuffer[MAX_PATH + 1];
static int mainEntryPoint(int argc, const char **argv)
{
// If there is a startup image, then we should just use it.
if(osvm_findStartupImage(argv[0], NULL))
return osvm_main(argc, argv);

// Try to find a explicit image on the command line.
int hasImageArgument = 0;
for(int i = 1; i < argc; ++i)
Expand Down

0 comments on commit adba21b

Please sign in to comment.