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

ruby-changes:38896

From: ngoto <ko1@a...>
Date: Sat, 20 Jun 2015 02:49:47 +0900 (JST)
Subject: [ruby-changes:38896] ngoto:r50977 (trunk): * process.c (rb_execarg_parent_start1): new macro ALWAYS_NEED_ENVP

ngoto	2015-06-20 02:49:27 +0900 (Sat, 20 Jun 2015)

  New Revision: 50977

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50977

  Log:
    * process.c (rb_execarg_parent_start1): new macro ALWAYS_NEED_ENVP
      to generate envp_str anytime on Solaris 10 (or earlier version
      of Solaris) to avoid calling execv() which is async-signal unsafe
      on Solaris 10. [Bug #11265] [ruby-dev:49089]
          
    * process.c (exec_with_sh, proc_exec_cmd): On Solaris 10,
      because ALWAYS_NEED_ENVP is 1 and envp_str is always generated,
      execv() in exec_with_sh() and proc_exec_cmd() are never called.
      To guarantee this, execv() is replaced by a macro to print
      out error message on Solaris 10.
          
    * process.c (proc_exec_sh): Because proc_exec_sh() may be called
      by rb_proc_exec() with envp_str = Qfalse, execl() is replaced
      by a macro that calls execle() with "extern char **environ"
      traditional global variable on Solaris 10.
      TODO: This may be unsafe and sholud be changed
      in the future.
      Although rb_proc_exec() is not used from inside current version
      of ruby, it may be called by third-party extensions.

  Modified files:
    trunk/ChangeLog
    trunk/process.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50976)
+++ ChangeLog	(revision 50977)
@@ -1,3 +1,24 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Jun 20 02:03:53 2015  Naohisa Goto  <ngotogenome@g...>
+
+	* process.c (rb_execarg_parent_start1): new macro ALWAYS_NEED_ENVP
+	  to generate envp_str anytime on Solaris 10 (or earlier version
+	  of Solaris) to avoid calling execv() which is async-signal unsafe
+	  on Solaris 10. [Bug #11265] [ruby-dev:49089]
+
+	* process.c (exec_with_sh, proc_exec_cmd): On Solaris 10,
+	  because ALWAYS_NEED_ENVP is 1 and envp_str is always generated,
+	  execv() in exec_with_sh() and proc_exec_cmd() are never called.
+	  To guarantee this, execv() is replaced by a macro to print
+	  out error message on Solaris 10.
+
+	* process.c (proc_exec_sh): Because proc_exec_sh() may be called
+	  by rb_proc_exec() with envp_str = Qfalse, execl() is replaced
+	  by a macro that calls execle() with "extern char **environ"
+	  traditional global variable on Solaris 10.
+	  TODO: This may be unsafe and sholud be changed in the future.
+	  Although rb_proc_exec() is not used from inside current version
+	  of ruby, it may be called by third-party extensions.
+
 Sat Jun 20 01:10:13 2015  Kazuhiro NISHIYAMA  <zn@m...>
 
 	* NEWS: mention about $SAFE.
Index: process.c
===================================================================
--- process.c	(revision 50976)
+++ process.c	(revision 50977)
@@ -285,6 +285,15 @@ static ID id_hertz; https://github.com/ruby/ruby/blob/trunk/process.c#L285
 extern ID ruby_static_id_status;
 #define id_status ruby_static_id_status
 
+/* execv and execl are async-signal-safe since SUSv4 (POSIX.1-2008, XPG7) */
+#if defined(__sun) && !defined(_XPG7) /* Solaris 10, 9, ... */
+#define execv(path, argv) (rb_async_bug_errno("unreachable: async-signal-unsafe execv() is called", 0))
+#define execl(path, arg0, arg1, arg2, term) do { extern char **environ; execle((path), (arg0), (arg1), (arg2), (term), (environ)); } while (0)
+#define ALWAYS_NEED_ENVP 1
+#else
+#define ALWAYS_NEED_ENVP 0
+#endif
+
 /*#define DEBUG_REDIRECT*/
 #if defined(DEBUG_REDIRECT)
 
@@ -1201,7 +1210,7 @@ exec_with_sh(const char *prog, char **ar https://github.com/ruby/ruby/blob/trunk/process.c#L1210
     if (envp)
         execve("/bin/sh", argv, envp); /* async-signal-safe */
     else
-        execv("/bin/sh", argv); /* async-signal-safe */
+        execv("/bin/sh", argv); /* async-signal-safe (since SUSv4) */
 }
 
 #else
@@ -1261,7 +1270,7 @@ proc_exec_cmd(const char *prog, VALUE ar https://github.com/ruby/ruby/blob/trunk/process.c#L1270
     if (envp_str)
         execve(prog, argv, envp); /* async-signal-safe */
     else
-        execv(prog, argv); /* async-signal-safe */
+        execv(prog, argv); /* async-signal-safe (since SUSv4) */
     preserving_errno(try_with_sh(prog, argv, envp)); /* try_with_sh() is async-signal-safe. */
 # if defined(__EMX__) || defined(OS2)
     if (new_argv) {
@@ -1312,7 +1321,7 @@ proc_exec_sh(const char *str, VALUE envp https://github.com/ruby/ruby/blob/trunk/process.c#L1321
     if (envp_str)
         execle("/bin/sh", "sh", "-c", str, (char *)NULL, (char **)RSTRING_PTR(envp_str)); /* async-signal-safe */
     else
-        execl("/bin/sh", "sh", "-c", str, (char *)NULL); /* async-signal-safe */
+        execl("/bin/sh", "sh", "-c", str, (char *)NULL); /* async-signal-safe (since SUSv4) */
 #endif
     return -1;
 #endif	/* _WIN32 */
@@ -2360,7 +2369,7 @@ rb_execarg_parent_start1(VALUE execarg_o https://github.com/ruby/ruby/blob/trunk/process.c#L2369
 
     unsetenv_others = eargp->unsetenv_others_given && eargp->unsetenv_others_do;
     envopts = eargp->env_modification;
-    if (unsetenv_others || envopts != Qfalse) {
+    if (ALWAYS_NEED_ENVP || unsetenv_others || envopts != Qfalse) {
         VALUE envtbl, envp_str, envp_buf;
         char *p, *ep;
         if (unsetenv_others) {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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