00001
00002 #if defined(__sun)
00003 #define _POSIX_PTHREAD_SEMANTICS
00004 #endif
00005
00006 #include "slate.hpp"
00007
00008 void dir_module_init(struct object_heap* oh) {
00009 oh->dir_index_size = SLATE_DIRECTORIES_MAXIMUM;
00010 oh->dir_index = (DIR**)calloc(oh->dir_index_size, sizeof(DIR*));
00011 }
00012
00013 bool_t dir_handle_isvalid(struct object_heap* oh, word_t dir) {
00014 return (0 <= dir && dir < oh->dir_index_size && oh->dir_index[dir] != NULL);
00015 }
00016
00017 static int dir_allocate(struct object_heap* oh) {
00018 int i;
00019 for (i = 0; i < SLATE_DIRECTORIES_MAXIMUM; i++) {
00020 if (oh->dir_index[i] == NULL)
00021 return i;
00022 }
00023 return -EMFILE;
00024 }
00025
00026 int dir_open(struct object_heap* oh, struct ByteArray *dirName) {
00027 int dirHandle = dir_allocate(oh);
00028 if (dirHandle < 0) {
00029 return dirHandle;
00030 } else {
00031 size_t nameLen = payload_size((struct Object *) dirName);
00032 char *name = (char*)malloc(nameLen + 1);
00033 if (name == NULL) {
00034 return -errno;
00035 } else {
00036 memcpy(name, dirName->elements, nameLen);
00037 name[nameLen] = '\0';
00038 oh->dir_index[dirHandle] = opendir(name);
00039 if (oh->dir_index[dirHandle] == NULL) {
00040 int savedErrno = errno;
00041 free(name);
00042 return -savedErrno;
00043 } else {
00044 free(name);
00045 return dirHandle;
00046 }
00047 }
00048 }
00049 }
00050
00051 int dir_close(struct object_heap* oh, int dirHandle) {
00052 if (oh->dir_index[dirHandle] != NULL) {
00053 closedir(oh->dir_index[dirHandle]);
00054 oh->dir_index[dirHandle] = NULL;
00055 return 0;
00056 } else {
00057 return -EINVAL;
00058 }
00059 }
00060
00061 int dir_read(struct object_heap* oh, int dirHandle, struct ByteArray *entNameBuffer) {
00062 struct dirent ent;
00063 struct dirent *result = &ent;
00064 int resultCode, entLen;
00065
00066 if (dirHandle < 0)
00067 return -EINVAL;
00068
00069 #if defined(WIN32) || defined(__CYGWIN__)
00070 result = readdir(oh->dir_index[dirHandle]);
00071 resultCode = errno;
00072 #else
00073 resultCode = readdir_r(oh->dir_index[dirHandle], result, &result);
00074 #endif
00075 if (resultCode != 0) {
00076
00077 assert(resultCode >= 0);
00078 return -resultCode;
00079 }
00080
00081 if (result == NULL) {
00082
00083 return 0;
00084 }
00085
00086 entLen = strlen(result->d_name);
00087 if (entLen == 0) {
00088
00089 return -ENOENT;
00090 }
00091
00092 assert(payload_size((struct Object *) entNameBuffer) >= entLen);
00093 memcpy(entNameBuffer->elements, result->d_name, entLen);
00094 return entLen;
00095 }
00096
00097 int dir_getcwd(struct ByteArray *pathBuffer) {
00098 #ifdef WIN32
00099 return GetCurrentDirectory((DWORD)payload_size((struct Object *) pathBuffer), pathBuffer->elements);
00100 #else
00101 return ((getcwd((char *)pathBuffer->elements, byte_array_size(pathBuffer)) == NULL)
00102 ? -errno : strlen((const char *)pathBuffer->elements));
00103 #endif
00104 }
00105
00106 int dir_setcwd(struct ByteArray *newpath) {
00107 word_t pathLen = byte_array_size(newpath);
00108 char *path = (char*)malloc(pathLen + 1);
00109 #ifdef WIN32
00110 if (path == NULL)
00111 return GetLastError();
00112 pathLen = extractCString(newpath, path, sizeof(path));
00113
00114 if (pathLen < 0)
00115 return SLATE_ERROR_RETURN;
00116
00117 return SetCurrentDirectory (path);
00118 #else
00119 if (path == NULL)
00120 return -errno;
00121 memcpy(path, newpath->elements, pathLen);
00122 path[pathLen] = '\0';
00123 if (chdir(path) == -1) {
00124 int savedErrno = errno;
00125 free(path);
00126 return -savedErrno;
00127 } else {
00128 free(path);
00129 return 0;
00130 }
00131 #endif
00132 }
00133
00134
00135 bool_t dir_make(struct object_heap* oh, char* dir) {
00136 #ifdef WIN32
00137 return FALSE;
00138 #else
00139 return (mkdir(dir, 0777) == 0 ? TRUE : FALSE);
00140 #endif
00141 }
00142
00143 bool_t dir_delete(struct object_heap* oh, char* dir) {
00144 #ifdef WIN32
00145 return FALSE;
00146 #else
00147 return (rmdir(dir) == 0 ? TRUE : FALSE);
00148 #endif
00149 }
00150
00151 word_t slate_direntry_type(unsigned char d_type) {
00152
00153 return d_type;
00154 }
00155
00156 #if 0
00157
00158 struct Object* dir_contents(struct object_heap* oh, char* dirpath) {
00159 #ifdef WIN32
00160 return FALSE;
00161 #else
00162 DIR* dir;
00163 int count, i;
00164 word_t lenfilename;
00165 struct dirent* direntry;
00166 struct OopArray* array;
00167
00168 dir = opendir(dirpath);
00169 if (dir == NULL) {
00170 return oh->cached.nil;
00171 }
00172
00173 count = 0;
00174 while ((direntry = readdir(dir))) count++;
00175 rewinddir(dir);
00176 i = 0;
00177
00178 array = heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), count);
00179 heap_fixed_add(oh, (struct Object*)array);
00180
00181 while ((direntry = readdir(dir)) && i < count) {
00182 array->elements[i] = (struct Object*) heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), 2);
00183 heap_store_into(oh, (struct Object*)array, (struct Object*)array->elements[i]);
00184 ((struct OopArray*)array->elements[i])->elements[0] = smallint_to_object(slate_direntry_type(direntry->d_type));
00185 heap_store_into(oh, (struct Object*)array->elements[i], (struct Object*)((struct OopArray*)array->elements[i])->elements[1]);
00186 lenfilename = strlen(direntry->d_name);
00187 ((struct OopArray*)array->elements[i])->elements[1] = (struct Object*) heap_clone_byte_array_sized(oh, get_special(oh, SPECIAL_OOP_BYTE_ARRAY_PROTO), lenfilename);
00188 copy_bytes_into((byte_t*)direntry->d_name, lenfilename, ((struct ByteArray*)((struct OopArray*)array->elements[i])->elements[1])->elements);
00189 i++;
00190 }
00191
00192 closedir(dir);
00193
00194 heap_fixed_remove(oh, (struct Object*)array);
00195
00196 return (struct Object*)array;
00197 #endif
00198 }
00199 #endif
00200
00201 bool_t dir_rename_to(struct object_heap* oh, char* src, char* dest) {
00202 #ifdef WIN32
00203 return FALSE;
00204 #else
00205 return (rename(src, dest) == 0 ? TRUE : FALSE);
00206 #endif
00207 }