diff options
author | eutarass | 2009-08-24 18:36:43 +0000 |
---|---|---|
committer | eutarass | 2009-08-24 18:36:43 +0000 |
commit | c579d9e7e3a02cd87541110f819e6513cedcdbec (patch) | |
tree | 9013cf6af346c9d09592e363b19d76e78d5cb517 | |
parent | 6f6a8ba7a52de0af747fe9709b63d5d28c3bc988 (diff) | |
download | org.eclipse.tcf.agent-c579d9e7e3a02cd87541110f819e6513cedcdbec.tar.gz org.eclipse.tcf.agent-c579d9e7e3a02cd87541110f819e6513cedcdbec.tar.xz org.eclipse.tcf.agent-c579d9e7e3a02cd87541110f819e6513cedcdbec.zip |
TCF Agent: added UNICODE support in file names on Windows
-rw-r--r-- | filesystem.c | 4 | ||||
-rw-r--r-- | mdep.c | 149 | ||||
-rw-r--r-- | mdep.h | 72 |
3 files changed, 186 insertions, 39 deletions
diff --git a/filesystem.c b/filesystem.c index b7928bb4..d14af4a9 100644 --- a/filesystem.c +++ b/filesystem.c @@ -27,7 +27,7 @@ #include <assert.h> #include <fcntl.h> #include <sys/stat.h> -#ifndef _MSC_VER +#if !defined(WIN32) || defined(__CYGWIN__) # include <utime.h> # include <dirent.h> #endif @@ -948,7 +948,7 @@ static void command_mkdir(char * token, Channel * c) { if (attrs.flags & ATTR_PERMISSIONS) { mode = attrs.permissions; } -#if defined(_MSC_VER) || defined(_WRS_KERNEL) || defined(__MINGW32__) +#if defined(_WRS_KERNEL) if (mkdir(path) < 0) err = errno; #else if (mkdir(path, mode) < 0) err = errno; @@ -445,7 +445,7 @@ int inet_pton(int af, const char * src, void * dst) { #endif /* WIN32 */ -#if defined(_MSC_VER) || defined(__MINGW32__) +#if defined(WIN32) && !defined(__CYGWIN__) static __int64 file_time_to_unix_time(const FILETIME * ft) { __int64 res = (__int64)ft->dwHighDateTime << 32; @@ -478,7 +478,7 @@ void usleep(useconds_t useconds) { int truncate(const char * path, int64_t size) { int res = 0; - int f = _open(path, _O_RDWR | _O_BINARY); + int f = open(path, _O_RDWR | _O_BINARY, 0); if (f < 0) return -1; res = ftruncate(f, size); _close(f); @@ -545,10 +545,105 @@ ssize_t pwrite(int fd, const void * buf, size_t size, off_t offset) { return wr; } -#endif /* defined(_MSC_VER) || defined(__MINGW32__) */ +int utf8_stat(const char * name, struct utf8_stat * buf) { + struct _stati64 tmp; + wchar_t path[FILE_PATH_SIZE]; + if (!MultiByteToWideChar(CP_UTF8, 0, name, -1, path, sizeof(path))) { + set_win32_errno(GetLastError()); + return -1; + } + if (_wstati64(path, &tmp)) return -1; + buf->st_dev = tmp.st_dev; + buf->st_ino = tmp.st_ino; + buf->st_mode = tmp.st_mode; + buf->st_nlink = tmp.st_nlink; + buf->st_uid = tmp.st_uid; + buf->st_gid = tmp.st_gid; + buf->st_rdev = tmp.st_rdev; + buf->st_size = tmp.st_size; + buf->st_atime = tmp.st_atime; + buf->st_mtime = tmp.st_mtime; + buf->st_ctime = tmp.st_ctime; + return 0; +} + +int utf8_fstat(int fd, struct utf8_stat * buf) { + struct _stati64 tmp; + if (_fstati64(fd, &tmp)) return -1; + buf->st_dev = tmp.st_dev; + buf->st_ino = tmp.st_ino; + buf->st_mode = tmp.st_mode; + buf->st_nlink = tmp.st_nlink; + buf->st_uid = tmp.st_uid; + buf->st_gid = tmp.st_gid; + buf->st_rdev = tmp.st_rdev; + buf->st_size = tmp.st_size; + buf->st_atime = tmp.st_atime; + buf->st_mtime = tmp.st_mtime; + buf->st_ctime = tmp.st_ctime; + return 0; +} + +int utf8_open(const char * name, int flags, int perms) { + wchar_t path[FILE_PATH_SIZE]; + if (!MultiByteToWideChar(CP_UTF8, 0, name, -1, path, sizeof(path))) { + set_win32_errno(GetLastError()); + return -1; + } + return _wopen(path, flags, perms); +} -#if defined(_MSC_VER) -DIR * opendir(const char *path) { +int utf8_chmod(const char * name, int mode) { + wchar_t path[FILE_PATH_SIZE]; + if (!MultiByteToWideChar(CP_UTF8, 0, name, -1, path, sizeof(path))) { + set_win32_errno(GetLastError()); + return -1; + } + return _wchmod(path, mode); +} + +int utf8_remove(const char * name) { + wchar_t path[FILE_PATH_SIZE]; + if (!MultiByteToWideChar(CP_UTF8, 0, name, -1, path, sizeof(path))) { + set_win32_errno(GetLastError()); + return -1; + } + return _wremove(path); +} + +int utf8_rmdir(const char * name) { + wchar_t path[FILE_PATH_SIZE]; + if (!MultiByteToWideChar(CP_UTF8, 0, name, -1, path, sizeof(path))) { + set_win32_errno(GetLastError()); + return -1; + } + return _wrmdir(path); +} + +int utf8_mkdir(const char * name, int mode) { + wchar_t path[FILE_PATH_SIZE]; + if (!MultiByteToWideChar(CP_UTF8, 0, name, -1, path, sizeof(path))) { + set_win32_errno(GetLastError()); + return -1; + } + return _wmkdir(path); +} + +int utf8_rename(const char * name1, const char * name2) { + wchar_t path1[FILE_PATH_SIZE]; + wchar_t path2[FILE_PATH_SIZE]; + if (!MultiByteToWideChar(CP_UTF8, 0, name1, -1, path1, sizeof(path1))) { + set_win32_errno(GetLastError()); + return -1; + } + if (!MultiByteToWideChar(CP_UTF8, 0, name2, -1, path2, sizeof(path2))) { + set_win32_errno(GetLastError()); + return -1; + } + return _wrename(path1, path2); +} + +DIR * utf8_opendir(const char * path) { DIR * d = (DIR *)loc_alloc(sizeof(DIR)); if (!d) { errno = ENOMEM; return 0; } strcpy(d->path, path); @@ -557,23 +652,32 @@ DIR * opendir(const char *path) { return d; } -struct dirent * readdir(DIR *d) { +struct dirent * utf8_readdir(DIR * d) { static struct dirent de; + if (d->hdl < 0) { - d->hdl = _findfirsti64(d->path, &d->blk); + wchar_t path[FILE_PATH_SIZE]; + if (!MultiByteToWideChar(CP_UTF8, 0, d->path, -1, path, sizeof(path))) { + set_win32_errno(GetLastError()); + return 0; + } + d->hdl = _wfindfirsti64(path, &d->blk); if (d->hdl < 0) { if (errno == ENOENT) errno = 0; return 0; } } else { - int r = _findnexti64(d->hdl, &d->blk); + int r = _wfindnexti64(d->hdl, &d->blk); if (r < 0) { if (errno == ENOENT) errno = 0; return 0; } } - strcpy(de.d_name, d->blk.name); + if (!WideCharToMultiByte(CP_UTF8, 0, d->blk.name, -1, de.d_name, sizeof(de.d_name), NULL, NULL)) { + set_win32_errno(GetLastError()); + return 0; + } de.d_size = d->blk.size; de.d_atime = d->blk.time_access; de.d_ctime = d->blk.time_create; @@ -581,7 +685,7 @@ struct dirent * readdir(DIR *d) { return &de; } -int closedir(DIR * d) { +int utf8_closedir(DIR * d) { int r = 0; if (!d) { errno = EBADF; @@ -592,7 +696,7 @@ int closedir(DIR * d) { return r; } -#endif /* defined(_MSC_VER) */ +#endif /* defined(WIN32) && !defined(__CYGWIN__) */ #if defined(WIN32) @@ -804,16 +908,23 @@ void ini_mdep(void) { #if defined(WIN32) -char * canonicalize_file_name(const char * path) { - char buf[MAX_PATH]; - char * basename; +char * canonicalize_file_name(const char * name) { + DWORD len; int i = 0; - DWORD len = GetFullPathName(path, sizeof(buf), buf, &basename); + wchar_t buf[FILE_PATH_SIZE]; + wchar_t * basename; + wchar_t path[FILE_PATH_SIZE]; + char res[FILE_PATH_SIZE]; + if (!MultiByteToWideChar(CP_UTF8, 0, name, -1, path, sizeof(path))) { + set_win32_errno(GetLastError()); + return NULL; + } + len = GetFullPathNameW(path, sizeof(buf), buf, &basename); if (len == 0) { errno = ENOENT; return NULL; } - if (len > MAX_PATH - 1) { + if (len > FILE_PATH_SIZE - 1) { errno = ENAMETOOLONG; return NULL; } @@ -821,7 +932,11 @@ char * canonicalize_file_name(const char * path) { if (buf[i] == '\\') buf[i] = '/'; i++; } - return strdup(buf); + if (!WideCharToMultiByte(CP_UTF8, 0, buf, -1, res, sizeof(res), NULL, NULL)) { + set_win32_errno(GetLastError()); + return NULL; + } + return strdup(res); } #elif defined(_WRS_KERNEL) @@ -126,9 +126,6 @@ extern void usleep(useconds_t useconds); #define off_t __int64 #define lseek _lseeki64 -#define stat _stati64 -#define lstat _stati64 -#define fstat _fstati64 extern int truncate(const char * path, int64_t size); extern int ftruncate(int f, int64_t size); #define utimbuf _utimbuf @@ -146,24 +143,48 @@ extern int getegid(void); extern ssize_t pread(int fd, const void * buf, size_t size, off_t offset); extern ssize_t pwrite(int fd, const void * buf, size_t size, off_t offset); -#endif /* __CYGWIN__ */ - -#define MSG_MORE 0 - -extern const char * inet_ntop(int af, const void * src, char * dst, socklen_t size); -extern int inet_pton(int af, const char * src, void * dst); +/* UTF-8 support */ +struct utf8_stat { + dev_t st_dev; + ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + dev_t st_rdev; + int64_t st_size; + int64_t st_atime; + int64_t st_mtime; + int64_t st_ctime; +}; +#define stat utf8_stat +#define lstat utf8_stat +#define fstat utf8_fstat +#define open utf8_open +#define chmod utf8_chmod +#define remove utf8_remove +#define rmdir utf8_rmdir +#define mkdir utf8_mkdir +#define rename utf8_rename +extern int utf8_stat(const char * name, struct utf8_stat * buf); +extern int utf8_fstat(int fd, struct utf8_stat * buf); +extern int utf8_open(const char * name, int flags, int perms); +extern int utf8_chmod(const char * name, int mode); +extern int utf8_remove(const char * path); +extern int utf8_rmdir(const char * path); +extern int utf8_mkdir(const char * path, int mode); +extern int utf8_rename(const char * path1, const char * path2); -#if defined(_MSC_VER) /* - * readdir() emulation + * readdir() emulation with UTF-8 support */ -struct DIR { +struct UTF8_DIR { long hdl; - struct _finddatai64_t blk; + struct _wfinddatai64_t blk; char path[FILE_PATH_SIZE]; }; -struct dirent { +struct utf8_dirent { char d_name[FILE_PATH_SIZE]; int64_t d_size; time_t d_atime; @@ -171,13 +192,24 @@ struct dirent { time_t d_wtime; }; -typedef struct DIR DIR; +typedef struct UTF8_DIR UTF8_DIR; -extern DIR * opendir(const char * path); -extern int closedir(DIR * dir); -extern struct dirent * readdir(DIR * dir); +#define DIR UTF8_DIR +#define dirent utf8_dirent +#define opendir utf8_opendir +#define closedir utf8_closedir +#define readdir utf8_readdir -#endif /* _MSC_VER */ +extern DIR * utf8_opendir(const char * path); +extern int utf8_closedir(DIR * dir); +extern struct utf8_dirent * readdir(DIR * dir); + +#endif /* __CYGWIN__ */ + +#define MSG_MORE 0 + +extern const char * inet_ntop(int af, const void * src, char * dst, socklen_t size); +extern int inet_pton(int af, const char * src, void * dst); /* * PThreads emulation. @@ -235,7 +267,7 @@ extern int wsa_sendto(int socket, const void * buf, size_t size, int flags, #ifndef SHUT_RDWR #define SHUT_RDWR SD_BOTH -#endif SHUT_RDWR +#endif extern char * canonicalize_file_name(const char * path); |