[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]