Commit 2a1e0d16 authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

refactor the windows portability code. addresses #1269

git-svn-id: file:///svn/toku/tokudb.1032b@8109 c7de825b-a66e-492c-adef-691d508d4ae1
parent 624b9272
...@@ -8,6 +8,21 @@ extern "C" { ...@@ -8,6 +8,21 @@ extern "C" {
//The DIR functions do not exist in windows, but the Linux API ends up //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. //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); DIR *opendir(const char *name);
struct dirent *readdir(DIR *dir); struct dirent *readdir(DIR *dir);
......
#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;
}
#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;
}
#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;
}
//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;
}
#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;
}
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <windows.h> #include <toku_pthread.h>
#include "toku_pthread.h"
struct q { struct q {
toku_pthread_mutex_t m; toku_pthread_mutex_t m;
......
...@@ -2,20 +2,20 @@ ...@@ -2,20 +2,20 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <windows.h> #include <unistd.h>
#include "toku_pthread.h" #include <toku_pthread.h>
static void *myfunc1(void *arg) { static void *myfunc1(void *arg) {
printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId()); printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId());
fflush(stdout); fflush(stdout);
Sleep(10*1000); sleep(10);
return arg; return arg;
} }
static void *myfunc2(void *arg) { static void *myfunc2(void *arg) {
printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId()); printf("%s %p %lu\n", __FUNCTION__, arg, GetCurrentThreadId());
fflush(stdout); fflush(stdout);
Sleep(10*1000); sleep(10);
return arg; return arg;
} }
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <unistd.h>
#include "toku_portability.h" #include <string.h>
#include "toku_os.h"
int verbose; int verbose;
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <string.h>
#include "toku_portability.h" #include <unistd.h>
#include "toku_os.h"
int verbose; int verbose;
......
...@@ -19,19 +19,6 @@ struct fileid { ...@@ -19,19 +19,6 @@ struct fileid {
uint64_t st_creat; 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) #if defined(__cplusplus)
}; };
......
...@@ -8,9 +8,11 @@ extern "C" { ...@@ -8,9 +8,11 @@ extern "C" {
#endif #endif
long int random(void); long int random(void);
void srandom(unsigned int seed); void srandom(unsigned int seed);
int unsetenv(const char *name);
int setenv(const char *name, const char *value, int overwrite);
#if defined(__cplusplus) #if defined(__cplusplus)
}; };
#endif #endif
......
...@@ -9,6 +9,8 @@ extern "C" { ...@@ -9,6 +9,8 @@ extern "C" {
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
int fsync(int fildes);
int int
ftruncate(int fildes, int64_t offset); ftruncate(int fildes, int64_t offset);
......
...@@ -20,96 +20,6 @@ ...@@ -20,96 +20,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <Crtdbg.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 int
toku_os_get_file_size(int fildes, int64_t *size) { toku_os_get_file_size(int fildes, int64_t *size) {
...@@ -234,28 +144,6 @@ toku_os_unlock_file(int fildes) { ...@@ -234,28 +144,6 @@ toku_os_unlock_file(int fildes) {
return r; 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 int
toku_os_mkdir(const char *pathname, mode_t mode) { toku_os_mkdir(const char *pathname, mode_t mode) {
int r = mkdir(pathname); int r = mkdir(pathname);
...@@ -264,27 +152,6 @@ toku_os_mkdir(const char *pathname, mode_t mode) { ...@@ -264,27 +152,6 @@ toku_os_mkdir(const char *pathname, mode_t mode) {
return r; 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, static void printfParameterHandler(const wchar_t* expression,
const wchar_t* function, const wchar_t* file, const wchar_t* function, const wchar_t* file,
unsigned int line, uintptr_t pReserved) { unsigned int line, uintptr_t pReserved) {
...@@ -325,79 +192,6 @@ toku_os_initialize_settings(int verbosity) { ...@@ -325,79 +192,6 @@ toku_os_initialize_settings(int verbosity) {
return r; 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 int
toku_os_is_absolute_name(const char* path) { toku_os_is_absolute_name(const char* path) {
return (path[0] == '\\' || return (path[0] == '\\' ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment