# Possible bug in rb\_detach\_process()

**URL:** <https://www.ruby-forum.com/t/possible-bug-in-rb-detach-process/89111>\
**Category:** Development\
**Created:** [March 17, 2007, 10:37am UTC](https://www.ruby-forum.com/t/possible-bug-in-rb-detach-process/89111 "2007-03-17T10:37:47Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![kubo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/8edcca/32.png) [@kubo](https://www.ruby-forum.com/u/kubo)\
**Post date:** [March 17, 2007, 10:37am UTC](https://www.ruby-forum.com/t/possible-bug-in-rb-detach-process/89111/1 "2007-03-17T10:37:47Z")

</div>

e$B5WJ]$G$9!#e(B

waitpid  
e$B4X78$G$A$i$[$i%=!\<%9$r8+$F$$$?$N$G$9$,!"0J2\<$NItJ,$OLdBj$G$O$Je(B  
e$B$$$G$7$g$&$+!)e(B

static VALUE  
detach\_process\_watcher(int \*pid\_p)  
{  
rb\_pid\_t cpid;  
int status;

```
for (;;) {
    cpid = rb_waitpid(*pid_p, &status, WNOHANG);
    if (cpid != 0) return rb_last_status_get();
    rb_thread_sleep(1);
}

```

}

VALUE  
rb\_detach\_process(rb\_pid\_t pid)  
{  
return rb\_thread\_create(detach\_process\_watcher, (void\*)&pid);  
}

detach\_process\_watcher() e$B$KEO$5$l$k0z?t$O!"e(Brb\_detach\_process  
e$B$N%9%l%Ce(B  
e$B%I$N%9%?%C%/\>e$NCM$K$J$C$F$$$^$9!#e(Brb\_waitpid()  
e$B$,\<B9T$5$l$kA0$Ke(B  
rb\_detach\_process  
e$B$N%9%l%C%I$,F0$$$F%9%?%C%/\>e$NCM$,=q$-JQ$o$C$?$i!"e(B  
rb\_waitpid() e$B$KEO$5$l$ke(B pid e$B$O$o$1$N$o$+$i$J$$CM$K$J$j$^$9!#e(B

e$B@5$7$/$O$3$&!)e(B

static VALUE  
detach\_process\_watcher(void \*arg) \<- int \*pid\_p e$B$re(B void _arg  
e$B$Ke(B  
{  
rb\_pid\_t pid = (int)arg; \<- void_ e$B$re(B rb\_pid\_t  
e$B$KLa$9!#e(B  
rb\_pid\_t cpid;  
int status;

```
for (;;) {
    cpid = rb_waitpid(pid, &status, WNOHANG); <- *pid_p e$B$re(B 

```

pid e$B$Ke(B  
if (cpid != 0) return rb\_last\_status\_get();  
rb\_thread\_sleep(1);  
}  
}

VALUE  
rb\_detach\_process(rb\_pid\_t pid)  
{  
return rb\_thread\_create(detach\_process\_watcher, (void\*)pid); \<- &pid  
e$B$re(B pid e$B$Ke(B  
}

---

<div class="post-metadata">

**Author:** ![kubo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/8edcca/32.png) [@kubo](https://www.ruby-forum.com/u/kubo)\
**Post date:** [March 19, 2007, 5:53pm UTC](https://www.ruby-forum.com/t/possible-bug-in-rb-detach-process/89111/2 "2007-03-19T17:53:27Z")

</div>

e$B$J$+$@$G$9!#e(B

At Sat, 17 Mar 2007 18:36:07 +0900,  
KUBO Takehiro wrote in [ruby-dev:30618]:

> detach\_process\_watcher() e$B$KEO$5$l$k0z?t$O!"e(Brb\_detach\_process e$B$N%9%l%Ce(B  
> e$B%I$N%9%?%C%/\>e$NCM$K$J$C$F$$$^$9!#e(Brb\_waitpid() e$B$,\<B9T$5$l$kA0$Ke(B  
> rb\_detach\_process e$B$N%9%l%C%I$,F0$$$F%9%?%C%/\>e$NCM$,=q$-JQ$o$C$?$i!"e(B  
> rb\_waitpid() e$B$KEO$5$l$ke(B pid e$B$O$o$1$N$o$+$i$J$$CM$K$J$j$^$9!#e(B

e$B$?$7$+$K!#e(B

> ```
> cpid = rb_waitpid(pid, &status, WNOHANG); <- *pid_p e$B$re(B pid e$B$Ke(B
> if (cpid != 0) return rb_last_status_get();
> rb_thread_sleep(1);
> 
> ```

1.9e$B$G$Oe(Bpollinge$B$OITMW$K$J$C$?$O$:$G$9!#e(B

e$B$3$N:]$J$N$G!"e(B1.8e$B$G$be(Bwatche$B%9%l%C%I$+$ie(Bexit  
statuse$B$r$+$($9$h$&$Ke(B  
e$B$7$^$;$s$+!#e(B

- process.c (detach\_process\_watcher): should not pass the pointer  
to an auto variable to the thread to be created. pointed and  
fix by KUBO Takehiro [ruby-dev:30618]

- process.c (detach\_process\_watcher): now returns the exit status  
of the detached process.

# Index: trunk/process.c

— trunk/process.c (revision 12102)  
+++ trunk/process.c (working copy)  
@@ -861,14 +861,13 @@ proc\_waitall(void)

static VALUE  
-detach\_process\_watcher(int \*pid\_p)  
+detach\_process\_watcher(void \*arg)  
{

- rb\_pid\_t cpid;

- rb\_pid\_t cpid, pid = (rb\_pid\_t)arg;  
int status;

- for (;😉 {
- cpid = rb\_waitpid(\*pid\_p, &status, WNOHANG);
- if (cpid != 0) return rb\_last\_status\_get();
- rb\_thread\_sleep(1);

- while ((cpid = rb\_waitpid(pid, &status, 0)) == 0) {
- /\* wait while alive \*/  
}
- return rb\_last\_status\_get();  
}

@@ -876,5 +875,5 @@ VALUE  
rb\_detach\_process(rb\_pid\_t pid)  
{

- return rb\_thread\_create(detach\_process\_watcher, (void\*)&pid);

- return rb\_thread\_create(detach\_process\_watcher, (void\*)pid);  
}

@@ -892,6 +891,5 @@ rb\_detach\_process(rb\_pid\_t pid)

- process _pid_ when it terminates. Use `detach`
- only when you do not intent to explicitly wait for the child to

- 
  - terminate. `detach` only checks the status

- 
  - periodically (currently once each second).

- 
  - terminate.
  - 
  - The waiting thread returns the exit status of the detached process  
Index: stable/process.c  
===================================================================  
— stable/process.c (revision 12102)  
+++ stable/process.c (working copy)  
@@ -839,14 +839,13 @@ proc\_waitall()

static VALUE  
-detach\_process\_watcher(pid\_p)

- int \*pid\_p;  
+detach\_process\_watcher(arg)

- void \*arg;  
{

- int cpid, status;

- int pid = (int)arg, status;

- for (;😉 {
- cpid = rb\_waitpid(\*pid\_p, &status, WNOHANG);
- if (cpid != 0) return Qnil;

- while (rb\_waitpid(pid, &status, WNOHANG) == 0) {  
rb\_thread\_sleep(1);  
}
- return rb\_last\_status;  
}

@@ -855,5 +854,5 @@ rb\_detach\_process(pid)  
int pid;  
{

- return rb\_thread\_create(detach\_process\_watcher, (void\*)&pid);

- return rb\_thread\_create(detach\_process\_watcher, (void\*)pid);  
}

@@ -874,4 +873,9 @@ rb\_detach\_process(pid)

- periodically (currently once each second).
- 

- 
  - The waiting thread returns the exit status of the detached process

- 
  - when it terminates, so you can use `Thread#join` to

- 
  - know the result. If specified _pid_ is not a valid child process

- 
  - ID, the thread returns +nil+ immediately.

- 
  - 
  - In this first example, we don’t reap the first child process, so
  - it appears as a zombie in the process status display.
