Skip to content

Commit

Permalink
faSupport: initial commit for windows testing
Browse files Browse the repository at this point in the history
  • Loading branch information
akgrant committed Sep 15, 2018
1 parent 905fbb6 commit a229a95
Show file tree
Hide file tree
Showing 6 changed files with 644 additions and 163 deletions.
32 changes: 32 additions & 0 deletions platforms/Cross/plugins/FileAttributesPlugin/faConstants.h
@@ -0,0 +1,32 @@
/*
* faConstants.h
*
* File Attributes constants
*
* Note that these must be kept in sync with their definition in
* FileAttributesPlugin errors protocol.
*
*/
#define FA_SUCCESS 0

#define FA_STRING_TOO_LONG -1
#define FA_STAT_FAILED -2
#define FA_CANT_STAT_PATH -3
#define FA_GET_ATTRIBUTES_FAILED -4
#define FA_TIME_CONVERSION_FAILED -5
#define FA_INVALID_ARGUMENTS -6
#define FA_CORRUPT_VALUE -7
#define FA_CANT_READ_LINK -8
#define FA_CANT_OPEN_DIR -9
#define FA_CANT_ALLOCATE_MEMORY -10
#define FA_INVALID_REQUEST -11
#define FA_UNABLE_TO_CLOSE_DIR -12
#define FA_UNSUPPORTED_OPERATION -13
#define FA_UNEXPECTED_ERROR -14
#define FA_INTERPRETER_ERROR -15 /* Actual error flagged in interpreterProxy */
#define FA_CANT_READ_DIR -16



#define FA_NO_MORE_DATA 1

114 changes: 114 additions & 0 deletions platforms/unix/plugins/FileAttributesPlugin/faSupport.c
@@ -0,0 +1,114 @@
/*
* faSupport.c - Unix support routines for the FileAttributesPlugin
*
* Author: akgrant@gmail.com
*/
#include <dirent.h>
#include <errno.h>

#include "sq.h"
#include "faSupport.h"



/*
* faOpenDirectory
*
* Open the supplied directory for iteration and return the first entry.
*
* '.' and '..' are never returned.
*
* The root directory must be represented as '/', and not an empty string.
*
* If there are no entries, close the directory and return FA_NO_MORE_DATA
*/

sqInt faOpenDirectory(osdir *dirState)
{
sqInt pathLength;
sqInt status;
DIR *dir;


/* Open the directory */
dir = opendir(dirState->path);
if (dir == NULL)
return FA_CANT_OPEN_DIR;

dirState->platformDir = (void *)dir;
fprintf(stderr, "faOpenDirectory: osdir * %p, DIR * %p\n", dirState, dir);
fflush(stderr);
return faReadDirectory(dirState);
}




/*
* faReadDirectory
*
* Read the next entry from the already opened directory (dirState)
*
* If there are no entries, return FA_NO_MORE_DATA
*/

sqInt faReadDirectory(osdir *dirState)
{
sqInt haveEntry;
struct dirent *entry;
sqInt entry_length;
DIR *dirPtr;
sqInt status;

dirPtr = (DIR *)dirState->platformDir;
fprintf(stderr, "faReadDirectory: osdir * %p, DIR * %p\n", dirState, dirPtr);
fflush(stderr);
haveEntry = 0;
errno = 0;
do {
entry = readdir(dirPtr);
if (entry == NULL)
if (errno == 0)
return FA_NO_MORE_DATA;
else
return FA_CANT_READ_DIR;
if ((!(entry->d_name[0] == '.' && entry->d_name[1] == 0)) && strcmp(entry->d_name, ".."))
haveEntry = 1;
} while (!haveEntry);

entry_length = strlen(entry->d_name);
if (entry_length > dirState->max_file_len)
return FA_STRING_TOO_LONG;

fprintf(stderr, "read: %s\n", entry->d_name);
fflush(stderr);

strncpy(dirState->path_file, entry->d_name, dirState->max_file_len);

return FA_SUCCESS;
}



/*
* faCloseDirectory(void *dirStateId)
*
* Close the supplied directory.
*/

sqInt faCloseDirectory(osdir *dirState)
{
DIR *dirPtr;
sqInt status;

dirPtr = (DIR *)dirState->platformDir;
fprintf(stderr, "faCloseDirectory: osdir * %p, DIR * %p\n", dirState, dirPtr);
fflush(stderr);
status = closedir(dirPtr);
if (status) return FA_UNABLE_TO_CLOSE_DIR;
dirState->platformDir = 0;

return FA_SUCCESS;
}


36 changes: 36 additions & 0 deletions platforms/unix/plugins/FileAttributesPlugin/faSupport.h
@@ -0,0 +1,36 @@


/* REQUIRED: c file must have included standard squeak definitions */
#include "faConstants.h"

/*
* typedef osdir
*
* This holds the current state for retrieving all the children of a
* directory.
*
* The directory (path) being enumerated and the current file name are stored
* in a single string (path) to simplify stat()ing the file.
*
* platformDir - platform specific data for directory enumeration.
* path_len - length of the name of the path being enumerated.
* path_file - points to the file name of the current entry.
* This is set to the byte after the directory name
* and is used to stat() each file.
* max_file_len - The space remaining after the path for the file name.
* path - The directory name being enumerated, with platform specific
* encoding.
*/
typedef struct dirptrstruct {
void *platformDir;
sqInt path_len;
char *path_file;
sqInt max_file_len;
char path[PATH_MAX+4];
} osdir;


sqInt faOpenDirectory(osdir *dirState);
sqInt faReadDirectory(osdir *dirState);
sqInt faCloseDirectory(osdir *dirState);

135 changes: 135 additions & 0 deletions platforms/win32/plugins/FileAttributesPlugin/faSupport.c
@@ -0,0 +1,135 @@
/*
* faSupport.c - Windows support routines for the FileAttributesPlugin
*
* Author: akgrant@gmail.com
*/
#include <windows.h>

#include "sq.h"
#include "faSupport.h"




sqInt faCheckFindData(osdir *dirState, sqInt closeFind)
{
while (1) {
/* check for '.' or '..' directories */
if (dirState->findData.cFileName[0] == L'.')
if (dirState->findData.cFileName[1] == 0 ||
(dirState->findData.cFileName[1] == L'.' &&
dirState->findData.cFileName[2] == 0)) {
if (!FindNextFileW(dirState->directoryHandle, &dirState->findData)) {
if (closeFind)
FindClose(dirState->directoryHandle);
return NO_MORE_DATA;
} else
break;
}

/* convert to UTF-8 */
sz = WideCharToMultiByte(CP_UTF8,
0,
dirState->findData.cFileName,
-1,
dirState->path_file,
dirState->max_file_len,
NULL,
NULL);
if (!sz)
return FA_CANT_READ_DIR;

return FA_SUCCESS;
}



/*
* faOpenDirectory(char *pathString)
*
* Open the supplied directory for iteration and return the first entry.
*
* '.' and '..' are never returned.
*
* On Windows pathString cannot be empty, i.e. the root directory should be
* handled separately.
*
* If there are no entries, close the directory and return FA_NO_MORE_DATA
*/

sqInt faOpenDirectory(osdir *dirState)
{
WCHAR *widePathString;
sqInt sz;
sqInt patternLength;
DWORD ffError;


/* Ensure wildcard pattern in dirState->path (which must already end in a path separator). */
if (dirState->path_len == 0)
return FA_INVALID_ARGUMENTS;
patternLength = dirState->path_len;
pattern[patternLength++] = '*';
pattern[patternLength] = 0;

/* convert the path name into a wide null-terminated C string */
ALLOC_WIN32_PATH(widePathString, dirState->path, patternLength);

/* remove the wildcard pattern from dirState->path (but leave the trailing
* delimeter */
dirState->path[dirState->path_len] = 0;

dirState->directoryHandle = FindFirstFileW(widePathString, &dirState->findData);
if (dirState->directoryHandle == INVALID_HANDLE_ERROR) {
ffError = GetLastError();
if (ffError == ERROR_NO_MORE_FILES)
return FA_NO_MORE_DATA;
return FA_CANT_OPEN_DIR;
}

return faCheckFindData(dirState, 1);
}



/*
* faReadDirectory(osdir *dirState)
*
* Return the next entry for the already opened directory identified by
* dirStateId.
*
* Return FA_NO_MORE_DATA after the last file.
*/

sqInt faReadDirectory(osdir *dirState)
{
DWORD ffError;


if (!FindNextFileW(dirState->directoryHandle, &dirState->findData))
return FA_NO_MORE_DATA;

return faCheckFindData(dirState, 0);
}



/*
* faCloseDirectory(void *dirStateId)
*
* Close the supplied directory.
*/

sqInt faCloseDirectory(osdir *dirState)
{
sqInt status;

status = FindClose(dirState->directoryHandle);
dirState->directoryHandle = 0;
if (status)
return FA_SUCCESS;
else
return FA_UNABLE_TO_CLOSE_DIR;
}


37 changes: 37 additions & 0 deletions platforms/win32/plugins/FileAttributesPlugin/faSupport.h
@@ -0,0 +1,37 @@


/* REQUIRED: c file must have included standard squeak definitions */
#include "faConstants.h"

/*
* typedef osdir
*
* This holds the current state for retrieving all the children of a
* directory.
*
* The directory (path) being enumerated and the current file name are stored
* in a single string (path) to simplify stat()ing the file.
*
* platformDir - platform specific data for directory enumeration.
* path_len - length of the name of the path being enumerated.
* path_file - points to the file name of the current entry.
* This is set to the byte after the directory name
* and is used to stat() each file.
* max_file_len - The space remaining after the path for the file name.
* path - The directory name being enumerated, with UTF8 encoding.
*/
typedef struct dirptrstruct {
sqInt path_len;
char *path_file;
sqInt max_file_len;
char path[PATH_MAX+4];
HANDLE directoryHandle;
WIN32_FIND_DATAW findData;
} osdir;

#define PATH_SEPARATOR '\\'

sqInt faOpenDirectory(osdir *dirState);
sqInt faReadDirectory(osdir *dirState);
sqInt faCloseDirectory(osdir *dirState);

0 comments on commit a229a95

Please sign in to comment.