summaryrefslogtreecommitdiff
path: root/process.c
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2021-10-25 20:47:19 +0900
committerGitHub <noreply@github.com>2021-10-25 20:47:19 +0900
commit13068ebe32a7b8a1a9bd4fc2d5f157880b374e1d (patch)
tree63db2798edf5744f64f9a3e425cd994fd5d3f7bd /process.c
parent1eac38c6093a03688c2f046cfb6a16028b9395f5 (diff)
process.c: Add Process._fork (#5017)
* process.c: Add Process._fork This API is supposed for application monitoring libraries to hook fork event. [Feature #17795] Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Notes
Notes: Merged-By: mame <mame@ruby-lang.org>
Diffstat (limited to 'process.c')
-rw-r--r--process.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/process.c b/process.c
index 5e37a29460..6b83767738 100644
--- a/process.c
+++ b/process.c
@@ -103,6 +103,7 @@ int initgroups(const char *, rb_gid_t);
#include "internal/error.h"
#include "internal/eval.h"
#include "internal/hash.h"
+#include "internal/numeric.h"
#include "internal/object.h"
#include "internal/process.h"
#include "internal/thread.h"
@@ -4345,11 +4346,42 @@ rb_fork_ruby(int *status)
return pid;
}
+rb_pid_t
+rb_call_proc__fork(void)
+{
+ VALUE pid = rb_funcall(rb_mProcess, rb_intern("_fork"), 0);
+
+ return NUM2PIDT(pid);
+}
#endif
#if defined(HAVE_WORKING_FORK) && !defined(CANNOT_FORK_WITH_PTHREAD)
/*
* call-seq:
+ * Process._fork -> integer
+ *
+ * An internal API for fork. Do not call this method directly.
+ * Currently, this is called via +Kernel.#fork+, +Process.fork+, and
+ * +popen+ with +"-"+.
+ *
+ * This method is not for casual code but for application monitoring
+ * libraries. You can add custom code before and after fork events
+ * by overriding this method.
+ */
+VALUE
+rb_proc__fork(VALUE _obj)
+{
+ rb_pid_t pid = rb_fork_ruby(NULL);
+
+ if (pid == -1) {
+ rb_sys_fail("fork(2)");
+ }
+
+ return PIDT2NUM(pid);
+}
+
+/*
+ * call-seq:
* Kernel.fork [{ block }] -> integer or nil
* Process.fork [{ block }] -> integer or nil
*
@@ -4378,24 +4410,21 @@ rb_f_fork(VALUE obj)
{
rb_pid_t pid;
- switch (pid = rb_fork_ruby(NULL)) {
- case 0:
+ pid = rb_call_proc__fork();
+
+ if (pid == 0) {
if (rb_block_given_p()) {
int status;
rb_protect(rb_yield, Qundef, &status);
ruby_stop(status);
}
return Qnil;
-
- case -1:
- rb_sys_fail("fork(2)");
- return Qnil;
-
- default:
- return PIDT2NUM(pid);
}
+
+ return PIDT2NUM(pid);
}
#else
+#define rb_proc__fork rb_f_notimplement
#define rb_f_fork rb_f_notimplement
#endif
@@ -8700,6 +8729,7 @@ InitVM_process(void)
rb_define_singleton_method(rb_mProcess, "exit", f_exit, -1);
rb_define_singleton_method(rb_mProcess, "abort", f_abort, -1);
rb_define_singleton_method(rb_mProcess, "last_status", proc_s_last_status, 0);
+ rb_define_singleton_method(rb_mProcess, "_fork", rb_proc__fork, 0);
rb_define_module_function(rb_mProcess, "kill", proc_rb_f_kill, -1);
rb_define_module_function(rb_mProcess, "wait", proc_m_wait, -1);