summaryrefslogtreecommitdiff
path: root/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'process.c')
-rw-r--r--process.c164
1 files changed, 34 insertions, 130 deletions
diff --git a/process.c b/process.c
index 5fbc9be022..19f3172cb8 100644
--- a/process.c
+++ b/process.c
@@ -110,11 +110,11 @@ int initgroups(const char *, rb_gid_t);
#include "internal/thread.h"
#include "internal/variable.h"
#include "internal/warnings.h"
-#include "rjit.h"
#include "ruby/io.h"
#include "ruby/st.h"
#include "ruby/thread.h"
#include "ruby/util.h"
+#include "ractor_core.h"
#include "vm_core.h"
#include "vm_sync.h"
#include "ruby/ractor.h"
@@ -875,109 +875,6 @@ pst_equal(VALUE st1, VALUE st2)
/*
* call-seq:
- * stat & mask -> integer
- *
- * This method is deprecated as #to_i value is system-specific; use
- * predicate methods like #exited? or #stopped?, or getters like #exitstatus
- * or #stopsig.
- *
- * Returns the logical AND of the value of #to_i with +mask+:
- *
- * `cat /nop`
- * stat = $? # => #<Process::Status: pid 1155508 exit 1>
- * sprintf('%x', stat.to_i) # => "100"
- * stat & 0x00 # => 0
- *
- * ArgumentError is raised if +mask+ is negative.
- */
-
-static VALUE
-pst_bitand(VALUE st1, VALUE st2)
-{
- int status = PST2INT(st1);
- int mask = NUM2INT(st2);
-
- if (mask < 0) {
- rb_raise(rb_eArgError, "negative mask value: %d", mask);
- }
-#define WARN_SUGGEST(suggest) \
- rb_warn_deprecated_to_remove_at(3.5, "Process::Status#&", suggest)
-
- switch (mask) {
- case 0x80:
- WARN_SUGGEST("Process::Status#coredump?");
- break;
- case 0x7f:
- WARN_SUGGEST("Process::Status#signaled? or Process::Status#termsig");
- break;
- case 0xff:
- WARN_SUGGEST("Process::Status#exited?, Process::Status#stopped? or Process::Status#coredump?");
- break;
- case 0xff00:
- WARN_SUGGEST("Process::Status#exitstatus or Process::Status#stopsig");
- break;
- default:
- WARN_SUGGEST("other Process::Status predicates");
- break;
- }
-#undef WARN_SUGGEST
- status &= mask;
-
- return INT2NUM(status);
-}
-
-
-/*
- * call-seq:
- * stat >> places -> integer
- *
- * This method is deprecated as #to_i value is system-specific; use
- * predicate methods like #exited? or #stopped?, or getters like #exitstatus
- * or #stopsig.
- *
- * Returns the value of #to_i, shifted +places+ to the right:
- *
- * `cat /nop`
- * stat = $? # => #<Process::Status: pid 1155508 exit 1>
- * stat.to_i # => 256
- * stat >> 1 # => 128
- * stat >> 2 # => 64
- *
- * ArgumentError is raised if +places+ is negative.
- */
-
-static VALUE
-pst_rshift(VALUE st1, VALUE st2)
-{
- int status = PST2INT(st1);
- int places = NUM2INT(st2);
-
- if (places < 0) {
- rb_raise(rb_eArgError, "negative shift value: %d", places);
- }
-#define WARN_SUGGEST(suggest) \
- rb_warn_deprecated_to_remove_at(3.5, "Process::Status#>>", suggest)
-
- switch (places) {
- case 7:
- WARN_SUGGEST("Process::Status#coredump?");
- break;
- case 8:
- WARN_SUGGEST("Process::Status#exitstatus or Process::Status#stopsig");
- break;
- default:
- WARN_SUGGEST("other Process::Status attributes");
- break;
- }
-#undef WARN_SUGGEST
- status >>= places;
-
- return INT2NUM(status);
-}
-
-
-/*
- * call-seq:
* stopped? -> true or false
*
* Returns +true+ if this process is stopped,
@@ -1678,8 +1575,8 @@ after_exec(void)
static void
before_fork_ruby(void)
{
- rb_gc_before_fork();
before_exec();
+ rb_gc_before_fork();
}
static void
@@ -2738,7 +2635,7 @@ rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, VAL
}
rb_str_buf_cat(argv_str, (char *)&null, sizeof(null)); /* terminator for execve. */
eargp->invoke.cmd.argv_str =
- rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(argv_str);
+ rb_imemo_tmpbuf_new_from_an_RString(argv_str);
}
RB_GC_GUARD(execarg_obj);
}
@@ -2829,7 +2726,7 @@ open_func(void *ptr)
static void
rb_execarg_allocate_dup2_tmpbuf(struct rb_execarg *eargp, long len)
{
- VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
+ VALUE tmpbuf = rb_imemo_tmpbuf_new();
rb_imemo_tmpbuf_set_ptr(tmpbuf, ruby_xmalloc(run_exec_dup2_tmpbuf_size(len)));
eargp->dup2_tmpbuf = tmpbuf;
}
@@ -2933,7 +2830,7 @@ rb_execarg_parent_start1(VALUE execarg_obj)
p = NULL;
rb_str_buf_cat(envp_str, (char *)&p, sizeof(p));
eargp->envp_str =
- rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(envp_str);
+ rb_imemo_tmpbuf_new_from_an_RString(envp_str);
eargp->envp_buf = envp_buf;
/*
@@ -3060,7 +2957,7 @@ NORETURN(static VALUE f_exec(int c, const VALUE *a, VALUE _));
* - Invoking the executable at +exe_path+.
*
* This method has potential security vulnerabilities if called with untrusted input;
- * see {Command Injection}[rdoc-ref:command_injection.rdoc].
+ * see {Command Injection}[rdoc-ref:security/command_injection.rdoc].
*
* The new process is created using the
* {exec system call}[https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/execve.html];
@@ -4114,7 +4011,10 @@ retry_fork_async_signal_safe(struct rb_process_status *status, int *ep,
while (1) {
prefork();
disable_child_handler_before_fork(&old);
-#ifdef HAVE_WORKING_VFORK
+
+ // Older versions of ASAN does not work with vfork
+ // See https://github.com/google/sanitizers/issues/925
+#if defined(HAVE_WORKING_VFORK) && !defined(RUBY_ASAN_ENABLED)
if (!has_privilege())
pid = vfork();
else
@@ -4202,7 +4102,7 @@ fork_check_err(struct rb_process_status *status, int (*chfunc)(void*, char *, si
* The "async_signal_safe" name is a lie, but it is used by pty.c and
* maybe other exts. fork() is not async-signal-safe due to pthread_atfork
* and future POSIX revisions will remove it from a list of signal-safe
- * functions. rb_waitpid is not async-signal-safe since RJIT, either.
+ * functions. rb_waitpid is not async-signal-safe.
* For our purposes, we do not need async-signal-safety, here
*/
rb_pid_t
@@ -4224,9 +4124,13 @@ rb_fork_async_signal_safe(int *status,
rb_pid_t
rb_fork_ruby(int *status)
{
+ if (UNLIKELY(!rb_ractor_main_p())) {
+ rb_raise(rb_eRactorIsolationError, "can not fork from non-main Ractors");
+ }
+
struct rb_process_status child = {.status = 0};
rb_pid_t pid;
- int try_gc = 1, err;
+ int try_gc = 1, err = 0;
struct child_handler_disabler_state old;
do {
@@ -4236,8 +4140,10 @@ rb_fork_ruby(int *status)
rb_thread_acquire_fork_lock();
disable_child_handler_before_fork(&old);
- child.pid = pid = rb_fork();
- child.error = err = errno;
+ RB_VM_LOCKING() {
+ child.pid = pid = rb_fork();
+ child.error = err = errno;
+ }
disable_child_handler_fork_parent(&old); /* yes, bad name */
if (
@@ -4736,7 +4642,7 @@ rb_spawn(int argc, const VALUE *argv)
* - Invoking the executable at +exe_path+.
*
* This method has potential security vulnerabilities if called with untrusted input;
- * see {Command Injection}[rdoc-ref:command_injection.rdoc].
+ * see {Command Injection}[rdoc-ref:security/command_injection.rdoc].
*
* Returns:
*
@@ -4916,7 +4822,7 @@ rb_f_system(int argc, VALUE *argv, VALUE _)
* - Invoking the executable at +exe_path+.
*
* This method has potential security vulnerabilities if called with untrusted input;
- * see {Command Injection}[rdoc-ref:command_injection.rdoc].
+ * see {Command Injection}[rdoc-ref:security/command_injection.rdoc].
*
* Returns the process ID (pid) of the new process,
* without waiting for it to complete.
@@ -6017,7 +5923,7 @@ rb_getpwdiruid(void)
* The Process::Sys module contains UID and GID
* functions which provide direct bindings to the system calls of the
* same names instead of the more-portable versions of the same
- * functionality found in the Process,
+ * functionality found in the +Process+,
* Process::UID, and Process::GID modules.
*/
@@ -8324,7 +8230,7 @@ ruby_real_ms_time(void)
* - +:microsecond+: Number of microseconds as an integer.
* - +:millisecond+: Number of milliseconds as an integer.
* - +:nanosecond+: Number of nanoseconds as an integer.
- * - +::second+: Number of seconds as an integer.
+ * - +:second+: Number of seconds as an integer.
*
* Examples:
*
@@ -8856,19 +8762,19 @@ static VALUE rb_mProcID_Syscall;
static VALUE
proc_warmup(VALUE _)
{
- RB_VM_LOCK_ENTER();
- rb_gc_prepare_heap();
- RB_VM_LOCK_LEAVE();
+ RB_VM_LOCKING() {
+ rb_gc_prepare_heap();
+ }
return Qtrue;
}
/*
* Document-module: Process
*
- * \Module +Process+ represents a process in the underlying operating system.
+ * Module +Process+ represents a process in the underlying operating system.
* Its methods support management of the current process and its child processes.
*
- * == \Process Creation
+ * == Process Creation
*
* Each of the following methods executes a given command in a new process or subshell,
* or multiple commands in new processes and/or subshells.
@@ -8881,11 +8787,11 @@ proc_warmup(VALUE _)
*
* In addition:
*
- * - \Method Kernel#system executes a given command-line (string) in a subshell;
+ * - Method Kernel#system executes a given command-line (string) in a subshell;
* returns +true+, +false+, or +nil+.
- * - \Method Kernel#` executes a given command-line (string) in a subshell;
+ * - Method Kernel#` executes a given command-line (string) in a subshell;
* returns its $stdout string.
- * - \Module Open3 supports creating child processes
+ * - Module Open3 supports creating child processes
* with access to their $stdin, $stdout, and $stderr streams.
*
* === Execution Environment
@@ -9115,7 +9021,7 @@ proc_warmup(VALUE _)
*
* 0644
*
- * ==== \Process Groups (+:pgroup+ and +:new_pgroup+)
+ * ==== Process Groups (+:pgroup+ and +:new_pgroup+)
*
* By default, the new process belongs to the same
* {process group}[https://en.wikipedia.org/wiki/Process_group]
@@ -9249,7 +9155,7 @@ proc_warmup(VALUE _)
* - ::waitall: Waits for all child processes to exit;
* returns their process IDs and statuses.
*
- * === \Process Groups
+ * === Process Groups
*
* - ::getpgid: Returns the process group ID for a process.
* - ::getpriority: Returns the scheduling priority
@@ -9346,8 +9252,6 @@ InitVM_process(void)
rb_define_singleton_method(rb_cProcessStatus, "wait", rb_process_status_waitv, -1);
rb_define_method(rb_cProcessStatus, "==", pst_equal, 1);
- rb_define_method(rb_cProcessStatus, "&", pst_bitand, 1);
- rb_define_method(rb_cProcessStatus, ">>", pst_rshift, 1);
rb_define_method(rb_cProcessStatus, "to_i", pst_to_i, 0);
rb_define_method(rb_cProcessStatus, "to_s", pst_to_s, 0);
rb_define_method(rb_cProcessStatus, "inspect", pst_inspect, 0);