diff --git a/windows/dirent.h b/windows/dirent.h index ce5ea347722..8fb1a4c00ea 100644 --- a/windows/dirent.h +++ b/windows/dirent.h @@ -8,6 +8,21 @@ extern "C" { //The DIR functions do not exist in windows, but the Linux API ends up //just using a wrapper. We might convert these into an toku_os_* type api. +enum { + DT_UNKNOWN = 0, + DT_DIR = 4, + DT_REG = 8 +}; + +struct dirent { + char d_name[_MAX_PATH]; + unsigned char d_type; +}; + +struct __toku_windir; +typedef struct __toku_windir DIR; + + DIR *opendir(const char *name); struct dirent *readdir(DIR *dir); diff --git a/windows/dirs.c b/windows/dirs.c new file mode 100644 index 00000000000..1ea907625fd --- /dev/null +++ b/windows/dirs.c @@ -0,0 +1,95 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <assert.h> +#include <errno.h> +#include <direct.h> +#include <dirent.h> +#include <io.h> +#include <sys/stat.h> +#include <windows.h> + +struct __toku_windir { + struct dirent ent; + struct _finddatai64_t data; + intptr_t handle; + BOOL finished; +}; + +DIR* +opendir(const char *name) { + char *format = NULL; + DIR *result = malloc(sizeof(*result)); + int r; + if (!result) { + r = ENOMEM; + goto cleanup; + } + format = malloc(strlen(name)+2+1); //2 for /*, 1 for '\0' + if (!format) { + r = ENOMEM; + goto cleanup; + } + strcpy(format, name); + if (format[strlen(format)-1]=='/') format[strlen(format)-1]='\0'; + strcat(format, "/*"); + result->handle = _findfirsti64(format, &result->data); + // printf("%s:%d %p %d\n", __FILE__, __LINE__, result->handle, errno); fflush(stdout); + if (result->handle==-1L) { + if (errno==ENOENT) { + int64_t r_stat; + //ENOENT can mean a good directory with no files, OR + //a directory that does not exist. + struct _stat64 buffer; + format[strlen(format)-3] = '\0'; //Strip the "/*" + r_stat = _stati64(format, &buffer); + if (r_stat==0) { + //Empty directory. + result->finished = TRUE; + r = 0; + goto cleanup; + } + } + r = errno; + assert(r!=0); + goto cleanup; + } + result->finished = FALSE; + r = 0; +cleanup: + if (r!=0) { + if (result) free(result); + result = NULL; + } + if (format) free(format); + return result; +} + +struct dirent* +readdir(DIR *dir) { + struct dirent *result; + int r; + if (dir->finished) { + errno = ENOENT; + result = NULL; + goto cleanup; + } + assert(dir->handle!=-1L); + strcpy(dir->ent.d_name, dir->data.name); + if (dir->data.attrib&_A_SUBDIR) dir->ent.d_type=DT_DIR; + else dir->ent.d_type=DT_REG; + r = _findnexti64(dir->handle, &dir->data); + if (r==-1L) dir->finished = TRUE; + result = &dir->ent; +cleanup: + return result; +} + +int +closedir(DIR *dir) { + int r; + if (dir->handle==-1L) r = 0; + else r = _findclose(dir->handle); + free(dir); + return r; +} diff --git a/windows/env.c b/windows/env.c new file mode 100644 index 00000000000..53e21c8a867 --- /dev/null +++ b/windows/env.c @@ -0,0 +1,41 @@ +#include <windows.h> +#include <toku_stdlib.h> + +int +setenv(const char *name, const char *value, int overwrite) { + char buf[2]; //Need a dummy buffer + BOOL exists = TRUE; + int r = GetEnvironmentVariable(name, buf, sizeof(buf)); + if (r==0) { + r = GetLastError(); + if (r==ERROR_ENVVAR_NOT_FOUND) exists = FALSE; + else { + errno = r; + r = -1; + goto cleanup; + } + } + if (overwrite || !exists) { + r = SetEnvironmentVariable(name, value); + if (r==0) { + errno = GetLastError(); + r = -1; + goto cleanup; + } + } + r = 0; +cleanup: + return r; +} + +int +unsetenv(const char *name) { + int r = SetEnvironmentVariable(name, NULL); + if (r==0) { //0 is failure + r = -1; + errno = GetLastError(); + } + else r = 0; + return r; +} + diff --git a/windows/files.c b/windows/files.c new file mode 100644 index 00000000000..f121393c4ec --- /dev/null +++ b/windows/files.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <assert.h> +#include <stdint.h> +#include <unistd.h> +#include <windows.h> + +// Note: pread and pwrite are not thread safe on the same fildes as they +// rely on the file offset + +int64_t +pread(int fildes, void *buf, size_t nbyte, int64_t offset) { + int64_t r = _lseeki64(fildes, offset, SEEK_SET); + if (r>=0) { + assert(r==offset); + r = read(fildes, buf, nbyte); + } + // printf("%s: %d %p %u %I64d %I64d\n", __FUNCTION__, fildes, buf, nbyte, offset, r); fflush(stdout); + return r; +} + +int64_t +pwrite(int fildes, const void *buf, size_t nbyte, int64_t offset) { + int64_t r = _lseeki64(fildes, offset, SEEK_SET); + if (r>=0) { + assert(r==offset); + r = write(fildes, buf, nbyte); + } + // printf("%s: %d %p %u %I64d %I64d\n", __FUNCTION__, fildes, buf, nbyte, offset, r); fflush(stdout); + return r; +} + +int +fsync(int fd) { + int r = _commit(fd); + return r; +} + +int +ftruncate(int fd, int64_t offset) { + HANDLE h; + BOOL b; + int r; + + h = (HANDLE) _get_osfhandle(fd); + if (h == INVALID_HANDLE_VALUE) + return -1; + r = _lseeki64(fd, 0, SEEK_SET); + if (r != 0) + return -2; + b = SetEndOfFile(h); + if (!b) + return -3; + return 0; +} + diff --git a/windows/random.c b/windows/random.c new file mode 100644 index 00000000000..8417a882fbe --- /dev/null +++ b/windows/random.c @@ -0,0 +1,26 @@ +//rand_s requires _CRT_RAND_S be defined before including stdlib +#define _CRT_RAND_S + +#include <stdio.h> +#include <assert.h> +#include <stdint.h> +#include <toku_stdlib.h> +#include <windows.h> + +long int +random(void) { + u_int32_t r; + errno_t r_error = rand_s(&r); + assert(r_error==0); + //Should return 0 to 2**31-1 instead of 2**32-1 + r >>= 1; + return r; +} + +//TODO: Implement srandom to modify the way rand_s works (IF POSSIBLE).. or +//reimplement random. +void +srandom(unsigned int seed) { + seed = seed; +} + diff --git a/windows/sleep.c b/windows/sleep.c new file mode 100644 index 00000000000..d2618fa8ad5 --- /dev/null +++ b/windows/sleep.c @@ -0,0 +1,24 @@ +#include <windows.h> +#include <unistd.h> + +unsigned int +sleep(unsigned int seconds) { + unsigned int m = seconds / 1000000; + unsigned int n = seconds % 1000000; + unsigned int i; + for (i=0; i<m; i++) + Sleep(1000000*1000); + Sleep(n*1000); + return 0; +} + +int +usleep(unsigned int useconds) { + unsigned int m = useconds / 1000; + unsigned int n = useconds % 1000; + if (m == 0 && n > 0) + m = 1; + Sleep(m); + return 0; +} + diff --git a/windows/tests/test-pthread-cond.c b/windows/tests/test-pthread-cond.c index af48ec5eef2..1deb2406767 100644 --- a/windows/tests/test-pthread-cond.c +++ b/windows/tests/test-pthread-cond.c @@ -2,8 +2,7 @@ #include <stdlib.h> #include <errno.h> #include <assert.h> -#include <windows.h> -#include "toku_pthread.h" +#include <toku_pthread.h> struct q { toku_pthread_mutex_t m; diff --git a/windows/tests/test-pthread-create.c b/windows/tests/test-pthread-create.c index 551c10490d1..69c0b49c6cd 100644 --- a/windows/tests/test-pthread-create.c +++ b/windows/tests/test-pthread-create.c @@ -2,20 +2,20 @@ #include <stdlib.h> #include <errno.h> #include <assert.h> -#include <windows.h> -#include "toku_pthread.h" +#include <unistd.h> +#include <toku_pthread.h> static void *myfunc1(void *arg) { printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId()); fflush(stdout); - Sleep(10*1000); + sleep(10); return arg; } static void *myfunc2(void *arg) { printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId()); fflush(stdout); - Sleep(10*1000); + sleep(10); return arg; } diff --git a/windows/tests/test-sleep.c b/windows/tests/test-sleep.c index 52fc61ebf41..86ad34e020f 100644 --- a/windows/tests/test-sleep.c +++ b/windows/tests/test-sleep.c @@ -1,9 +1,8 @@ #include <stdio.h> #include <stdlib.h> #include <assert.h> -#include <fcntl.h> -#include "toku_portability.h" -#include "toku_os.h" +#include <unistd.h> +#include <string.h> int verbose; diff --git a/windows/tests/test-usleep.c b/windows/tests/test-usleep.c index cf269e9df0b..92c8a38682e 100644 --- a/windows/tests/test-usleep.c +++ b/windows/tests/test-usleep.c @@ -1,9 +1,8 @@ #include <stdio.h> #include <stdlib.h> #include <assert.h> -#include <fcntl.h> -#include "toku_portability.h" -#include "toku_os.h" +#include <string.h> +#include <unistd.h> int verbose; diff --git a/windows/toku_os_types.h b/windows/toku_os_types.h index 37e85e5efe0..a80f5074a77 100644 --- a/windows/toku_os_types.h +++ b/windows/toku_os_types.h @@ -19,19 +19,6 @@ struct fileid { uint64_t st_creat; }; -enum { - DT_UNKNOWN = 0, - DT_DIR = 4, - DT_REG = 8 -}; - -struct dirent { - char d_name[_MAX_PATH]; - unsigned char d_type; -}; - -struct __toku_windir; -typedef struct __toku_windir DIR; #if defined(__cplusplus) }; diff --git a/windows/toku_stdlib.h b/windows/toku_stdlib.h index 34d22d92855..d21d7789589 100644 --- a/windows/toku_stdlib.h +++ b/windows/toku_stdlib.h @@ -8,9 +8,11 @@ extern "C" { #endif long int random(void); - void srandom(unsigned int seed); +int unsetenv(const char *name); +int setenv(const char *name, const char *value, int overwrite); + #if defined(__cplusplus) }; #endif diff --git a/windows/unistd.h b/windows/unistd.h index b2d57b25b8e..d9ff8f5a605 100644 --- a/windows/unistd.h +++ b/windows/unistd.h @@ -9,6 +9,8 @@ extern "C" { #include <stdio.h> #include <stdint.h> +int fsync(int fildes); + int ftruncate(int fildes, int64_t offset); diff --git a/windows/windows.c b/windows/windows.c index 29b4bda1b37..dad3bde1ee3 100644 --- a/windows/windows.c +++ b/windows/windows.c @@ -20,96 +20,6 @@ #include <fcntl.h> #include <Crtdbg.h> -struct __toku_windir { - struct dirent ent; - struct _finddatai64_t data; - intptr_t handle; - BOOL finished; -}; - -DIR* -opendir(const char *name) { - char *format = NULL; - DIR *result = malloc(sizeof(*result)); - int r; - if (!result) { - r = ENOMEM; - goto cleanup; - } - format = malloc(strlen(name)+2+1); //2 for /*, 1 for '\0' - if (!format) { - r = ENOMEM; - goto cleanup; - } - strcpy(format, name); - if (format[strlen(format)-1]=='/') format[strlen(format)-1]='\0'; - strcat(format, "/*"); - result->handle = _findfirsti64(format, &result->data); - // printf("%s:%d %p %d\n", __FILE__, __LINE__, result->handle, errno); fflush(stdout); - if (result->handle==-1L) { - if (errno==ENOENT) { - int64_t r_stat; - //ENOENT can mean a good directory with no files, OR - //a directory that does not exist. - struct _stat64 buffer; - format[strlen(format)-3] = '\0'; //Strip the "/*" - r_stat = _stati64(format, &buffer); - if (r_stat==0) { - //Empty directory. - result->finished = TRUE; - r = 0; - goto cleanup; - } - } - r = errno; - assert(r!=0); - goto cleanup; - } - result->finished = FALSE; - r = 0; -cleanup: - if (r!=0) { - if (result) free(result); - result = NULL; - } - if (format) free(format); - return result; -} - -struct dirent* -readdir(DIR *dir) { - struct dirent *result; - int r; - if (dir->finished) { - errno = ENOENT; - result = NULL; - goto cleanup; - } - assert(dir->handle!=-1L); - strcpy(dir->ent.d_name, dir->data.name); - if (dir->data.attrib&_A_SUBDIR) dir->ent.d_type=DT_DIR; - else dir->ent.d_type=DT_REG; - r = _findnexti64(dir->handle, &dir->data); - if (r==-1L) dir->finished = TRUE; - result = &dir->ent; -cleanup: - return result; -} - -int -closedir(DIR *dir) { - int r; - if (dir->handle==-1L) r = 0; - else r = _findclose(dir->handle); - free(dir); - return r; -} - -int -fsync(int fildes) { - int r = _commit(fildes); - return r; -} int toku_os_get_file_size(int fildes, int64_t *size) { @@ -234,28 +144,6 @@ toku_os_unlock_file(int fildes) { return r; } -int64_t -pread(int fildes, void *buf, size_t nbyte, int64_t offset) { - int64_t r = _lseeki64(fildes, offset, SEEK_SET); - if (r>=0) { - assert(r==offset); - r = read(fildes, buf, nbyte); - } - // printf("%s: %d %p %u %I64d %I64d\n", __FUNCTION__, fildes, buf, nbyte, offset, r); fflush(stdout); - return r; -} - -int64_t -pwrite(int fildes, const void *buf, size_t nbyte, int64_t offset) { - int64_t r = _lseeki64(fildes, offset, SEEK_SET); - if (r>=0) { - assert(r==offset); - r = write(fildes, buf, nbyte); - } - // printf("%s: %d %p %u %I64d %I64d\n", __FUNCTION__, fildes, buf, nbyte, offset, r); fflush(stdout); - return r; -} - int toku_os_mkdir(const char *pathname, mode_t mode) { int r = mkdir(pathname); @@ -264,27 +152,6 @@ toku_os_mkdir(const char *pathname, mode_t mode) { return r; } -unsigned int -sleep(unsigned int seconds) { - unsigned int m = seconds / 1000000; - unsigned int n = seconds % 1000000; - unsigned int i; - for (i=0; i<m; i++) - Sleep(1000000*1000); - Sleep(n*1000); - return 0; -} - -int -usleep(unsigned int useconds) { - unsigned int m = useconds / 1000; - unsigned int n = useconds % 1000; - if (m == 0 && n > 0) - m = 1; - Sleep(m); - return 0; -} - static void printfParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) { @@ -325,79 +192,6 @@ toku_os_initialize_settings(int verbosity) { return r; } -long int -random(void) { - u_int32_t r; - errno_t r_error = rand_s(&r); - assert(r_error==0); - //Should return 0 to 2**31-1 instead of 2**32-1 - r >>= 1; - return r; -} - -//TODO: Implement srandom to modify the way rand_s works (IF POSSIBLE).. or -//reimplement random. -void -srandom(unsigned int seed) { - UNUSED_WARNING(seed); -} - -int -setenv(const char *name, const char *value, int overwrite) { - char buf[2]; //Need a dummy buffer - BOOL exists = TRUE; - int r = GetEnvironmentVariable(name, buf, sizeof(buf)); - if (r==0) { - r = GetLastError(); - if (r==ERROR_ENVVAR_NOT_FOUND) exists = FALSE; - else { - errno = r; - r = -1; - goto cleanup; - } - } - if (overwrite || !exists) { - r = SetEnvironmentVariable(name, value); - if (r==0) { - errno = GetLastError(); - r = -1; - goto cleanup; - } - } - r = 0; -cleanup: - return r; -} - -int -unsetenv(const char *name) { - int r = SetEnvironmentVariable(name, NULL); - if (r==0) { //0 is failure - r = -1; - errno = GetLastError(); - } - else r = 0; - return r; -} - -int -ftruncate(int fd, int64_t offset) { - HANDLE h; - BOOL b; - int r; - - h = (HANDLE) _get_osfhandle(fd); - if (h == INVALID_HANDLE_VALUE) - return -1; - r = _lseeki64(fd, 0, SEEK_SET); - if (r != 0) - return -2; - b = SetEndOfFile(h); - if (!b) - return -3; - return 0; -} - int toku_os_is_absolute_name(const char* path) { return (path[0] == '\\' ||