It appears this was in fact the issue.

I added some code to print out the `FD_CLOEXEC` state. Files called via 
*syscall.Dupe2* end up with a *FD_CLOEXEC=0* whereas anything passed via 
*ExtraFiles* has a *FDCLOEXEC=1.*

Whoever said "This is impossible" thanks - you spurred me towards a 
wonderful discovery about what NOT to do :) 
On Monday, March 4, 2024 at 12:03:16 PM UTC-7 Jeff Stein wrote:

> I think I may have discovered the issue.
>
> I made a sys call to duplicate the file descriptor
>
> dupFd, err := syscall.Dup(int(file.Fd()))
> if err != nil {
> log.Printf("Error duplicating file descriptor: %v", err)
> return 0, ""
> }
>
> which likely reset the FD_CLOEXEC Flag:
>
> (from Advanced Programming in the Unix Environment) - section 3.12:
>
> *The new file descriptor returned by dup is guaranteed to be the 
> lowest-numbered available file descriptor. With dup2, we specify the value 
> of the new descriptor with the fd2 argument. If fd2 is already open, it is 
> first closed. If fd equals fd2, then dup2 returns fd2 without closing it. 
> Otherwise, the FD_CLOEXEC file descriptor flag is cleared for fd2, so 
> that fd2 is left open if the process calls exec.*
> Does this sound like what may have been happening?
>
> On Monday, March 4, 2024 at 9:04:31 AM UTC-7 Jeff Stein wrote:
>
>> OP here -> I'm going to put together some test apps - toss them on GitHub 
>> and make sure I actually know what I'm talking about :) 
>>
>> On Friday, March 1, 2024 at 7:57:15 PM UTC-7 Ian Lance Taylor wrote:
>>
>>> On Fri, Mar 1, 2024 at 6:17 PM Robert Engels <ren...@ix.netcom.com> 
>>> wrote: 
>>> > 
>>> > The could be calling fork() as in the system call - which copies all 
>>> file descriptors but I didn’t think Go processes could fork. 
>>> > 
>>> > Seems you would need to remap stdin and stdout in the fork to do 
>>> anything useful. 
>>> > 
>>> > This sounds very PHP - what goes around comes around. 
>>>
>>> Good point, I am assuming that the OP is using the os/exec package to 
>>> start up a new copy of the process. 
>>>
>>> A simple fork without an exec can't work in Go, or in any 
>>> multi-threaded program. 
>>>
>>> Ian 
>>>
>>>
>>> > > On Mar 1, 2024, at 8:01 PM, Ian Lance Taylor <ia...@golang.org> 
>>> wrote: 
>>> > > 
>>> > > On Fri, Mar 1, 2024 at 5:57 PM Jeff Stein <jeff...@gmail.com> 
>>> wrote: 
>>> > >> 
>>> > >> I'm struggling to understand if I'm able to do something. 
>>> > >> 
>>> > >> 
>>> > >> In my very odd use case we are writing a websever that handles 
>>> connections via a forked process. 
>>> > >> 
>>> > >> I have a listener process that listens for TCP connections. 
>>> > >> 
>>> > >> So each net.Conn that comes in we pull off its file descriptor: 
>>> > >> 
>>> > >> fd, err := conn.(*net.TCPConn).File() 
>>> > >> 
>>> > >> duplicate that file descriptor and then fork off a process passing 
>>> in that file descriptor. 
>>> > >> 
>>> > >> In my forked handler I'll reconstruct the HTTP connection and "do 
>>> stuff". 
>>> > >> 
>>> > >> The concern I'm having is that it appears when I fork a process I 
>>> inherit all of the parent file descriptors so if I have say 5 incoming 
>>> connections and then I fork my child process technically could write to a 
>>> different connection. 
>>> > >> 
>>> > >> I've played around with the various options: 
>>> > >> 
>>> > >> cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: false,} 
>>> > >> 
>>> > >> and using cmd.ExtraFiles 
>>> > >> 
>>> > >> No matter what I do I seem unable to limit the sub process to ONLY 
>>> using the specific File Descriptor I want it to have access to. 
>>> > >> 
>>> > >> I believe this is doable in C - but I'm not sure if I can do this 
>>> in GoLang as-is without mods . 
>>> > > 
>>> > > What you are describing shouldn't happen. A child process should 
>>> only 
>>> > > get the file descriptors explicitly passed via the os/exec.Cmd 
>>> fields 
>>> > > Stdin, Stdout, Stderr, and ExtraFiles. So tell us more: OS and 
>>> > > version of Go, and what is showing you that all file descriptors are 
>>> > > being passed down to the child. 
>>> > > 
>>> > > Ian 
>>> > > 
>>> > > -- 
>>> > > You received this message because you are subscribed to the Google 
>>> Groups "golang-nuts" group. 
>>> > > To unsubscribe from this group and stop receiving emails from it, 
>>> send an email to golang-nuts...@googlegroups.com. 
>>> > > To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/golang-nuts/CAOyqgcUb27YBCyE52QisHLyB9XPPpEycMxt4FrFJogGsFMiemQ%40mail.gmail.com.
>>>  
>>>
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/34b77595-6a2c-41f2-9ef7-9296c9c92176n%40googlegroups.com.

Reply via email to