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/