ruby-changes:39593
From: nobu <ko1@a...>
Date: Tue, 25 Aug 2015 06:35:00 +0900 (JST)
Subject: [ruby-changes:39593] nobu:r51674 (trunk): win32.c: symlink
nobu 2015-08-25 06:34:45 +0900 (Tue, 25 Aug 2015) New Revision: 51674 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51674 Log: win32.c: symlink * win32/win32.c (w32_symlink): implement symlink(). Modified files: trunk/ChangeLog trunk/configure.in trunk/file.c trunk/include/ruby/win32.h trunk/win32/Makefile.sub trunk/win32/win32.c Index: include/ruby/win32.h =================================================================== --- include/ruby/win32.h (revision 51673) +++ include/ruby/win32.h (revision 51674) @@ -289,6 +289,8 @@ extern int rb_w32_ulink(const char *, co https://github.com/ruby/ruby/blob/trunk/include/ruby/win32.h#L289 extern ssize_t readlink(const char *, char *, size_t); extern ssize_t rb_w32_ureadlink(const char *, char *, size_t); extern ssize_t rb_w32_wreadlink(const WCHAR *, WCHAR *, size_t); +extern int symlink(const char *src, const char *link); +extern int rb_w32_usymlink(const char *src, const char *link); extern int gettimeofday(struct timeval *, struct timezone *); extern int clock_gettime(clockid_t, struct timespec *); extern int clock_getres(clockid_t, struct timespec *); Index: configure.in =================================================================== --- configure.in (revision 51673) +++ configure.in (revision 51674) @@ -1108,6 +1108,7 @@ main() https://github.com/ruby/ruby/blob/trunk/configure.in#L1108 ac_cv_func_finite=yes ac_cv_func_link=yes ac_cv_func_readlink=yes + ac_cv_func_symlink=yes ac_cv_lib_crypt_crypt=no ac_cv_func_getpgrp_void=no ac_cv_func_memcmp_working=yes Index: ChangeLog =================================================================== --- ChangeLog (revision 51673) +++ ChangeLog (revision 51674) @@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Aug 25 06:34:43 2015 Nobuyoshi Nakada <nobu@r...> + + * win32/win32.c (w32_symlink): implement symlink(). + Mon Aug 24 16:01:19 2015 Nobuyoshi Nakada <nobu@r...> * encoding.c (rb_locale_encindex): find encoding index without Index: win32/win32.c =================================================================== --- win32/win32.c (revision 51673) +++ win32/win32.c (revision 51674) @@ -210,6 +210,7 @@ static struct { https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L210 { ERROR_OPERATION_ABORTED, EINTR }, { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }, { ERROR_MOD_NOT_FOUND, ENOENT }, + { ERROR_PRIVILEGE_NOT_HELD, EACCES, }, { WSAEINTR, EINTR }, { WSAEBADF, EBADF }, { WSAEACCES, EACCES }, @@ -4815,6 +4816,68 @@ readlink(const char *path, char *buf, si https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L4816 return w32_readlink(filecp(), path, buf, bufsize); } +#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY +#define SYMBOLIC_LINK_FLAG_DIRECTORY (0x1) +#endif + +/* License: Ruby's */ +static int +w32_symlink(UINT cp, const char *src, const char *link) +{ + int atts, len1, len2; + VALUE buf; + WCHAR *wsrc, *wlink; + DWORD flag = 0; + BOOLEAN ret; + + typedef DWORD (WINAPI *create_symbolic_link_func)(WCHAR*, WCHAR*, DWORD); + static create_symbolic_link_func create_symbolic_link = + (create_symbolic_link_func)-1; + + if (create_symbolic_link == (create_symbolic_link_func)-1) { + create_symbolic_link = (create_symbolic_link_func) + get_proc_address("kernel32", "CreateSymbolicLinkW", NULL); + } + if (!create_symbolic_link) { + errno = ENOSYS; + return -1; + } + + len1 = MultiByteToWideChar(cp, 0, src, -1, NULL, 0); + len2 = MultiByteToWideChar(cp, 0, link, -1, NULL, 0); + wsrc = ALLOCV_N(WCHAR, buf, len1+len2); + wlink = wsrc + len1; + MultiByteToWideChar(cp, 0, src, -1, wsrc, len1); + MultiByteToWideChar(cp, 0, link, -1, wlink, len2); + + atts = GetFileAttributesW(wsrc); + if (atts != -1 && atts & FILE_ATTRIBUTE_DIRECTORY) + flag = SYMBOLIC_LINK_FLAG_DIRECTORY; + ret = create_symbolic_link(wlink, wsrc, flag); + ALLOCV_END(buf); + + if (!ret) { + int e = GetLastError(); + errno = map_errno(e); + return -1; + } + return 0; +} + +/* License: Ruby's */ +int +rb_w32_usymlink(const char *src, const char *link) +{ + return w32_symlink(CP_UTF8, src, link); +} + +/* License: Ruby's */ +int +symlink(const char *src, const char *link) +{ + return w32_symlink(filecp(), src, link); +} + /* License: Ruby's */ int wait(int *status) Index: win32/Makefile.sub =================================================================== --- win32/Makefile.sub (revision 51673) +++ win32/Makefile.sub (revision 51674) @@ -719,6 +719,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/ https://github.com/ruby/ruby/blob/trunk/win32/Makefile.sub#L719 #define HAVE_FCNTL 1 #define HAVE_LINK 1 #define HAVE_READLINK 1 +#define HAVE_SYMLINK 1 #define HAVE__SETJMP 1 #define HAVE_TELLDIR 1 #define HAVE_SEEKDIR 1 Index: file.c =================================================================== --- file.c (revision 51673) +++ file.c (revision 51674) @@ -111,6 +111,8 @@ int flock(int, int); https://github.com/ruby/ruby/blob/trunk/file.c#L111 #define unlink(p) rb_w32_uunlink(p) #undef rename #define rename(f, t) rb_w32_urename((f), (t)) +#undef symlink +#define symlink(s, l) rb_w32_usymlink((s), (l)) #else #define STAT(p, s) stat((p), (s)) #endif -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/