On 09-Feb-16, Bram Moolenaar wrote:
>
> Olaf Dabrunz wrote:
>
> > > > On 08-Feb-16, Bram Moolenaar wrote:
> > > > > Some parts that we still need that require some thougths:
> > > > >
> > > > > - Communicating over a socket requires knowing the port number. For a
> > > > > deamon this would be a known number. For a server started by Vim
> > > > > it's
> > > > > best to let the server pick an available port. Then how does it
> > > > > tell
> > > > > Vim what port it picked? In test_channel we write the port number
> > > > > in
> > > > > a file. That's not ideal, but perhaps there is no better solution.
> > > > > Having Vim pick a free port and pass it to the server has race
> > > > > conditions
> > > > > (but it might still be an acceptable solution).
> > > >
> > > > To avoid the race, Vim could open the server's listening socket before
> > > > forking off the server, then close the socket descriptor on Vim's side.
> > >
> > > I don't think that works. If Vim keeps the socket open the server can't
> > > open it again, gives an "already in use" error.
> >
> > James already answered it, more concisely.
> >
> > My mid-air collision version, and longer...:
> >
> > The socket descriptor opened in Vim will be inherited to the child
> > process, the server. The child process / server does not need to
> > re-open it, it simply uses the already open descriptor. (Trying to
> > re-open the socket would indeed give "already in use".)
> >
> > The parent process (Vim) closes its copy of the socket descriptor after
> > the fork because it does not need the listening socket, and because the
> > socket should really shut down whenever the child (the server) closes it.
>
> Hmm, OK. But that only works for a process that was specifically
> written to do this. Not something that takes a --port argument.
>
> Also, how does the child process know which file descriptor has the
> socket? For example, how would this work with the demo server?
The server could take a --socket-fd <nr> argument. If there is an open
socket on that file descriptor, then it can use that.
struct stat statbuf;
int fd;
// get fd from argv
fstat(fd, &statbuf);
if (S_ISSOCK(statbuf.st_mode))
...;
Some tools already use a --<something>-fd <nr> option for file
descriptors, so there is some precedent here.
> Does this work for MS-Windows? Probably not, since it doesn't use
> fork().
Not an expert there. According to the information I gathered [1] this
used to work (across CreateProcess(), instead of fork()), and well
enough on WinNT/2000 [2], but cannot be relied upon, because MS broke it
[3, 1].
A solution could be to pass the socket *after* creating the child, by
using WSADuplicateSocket() [4], but this requires some other form of IPC
(e.g. a named pipe) between parent and child to pass the socket over it.
I think this could better be answered by someone who has experience with
socket passing on Windows.
[1]
http://stackoverflow.com/questions/11847793/are-tcp-socket-handles-inheritable
[2] https://support.microsoft.com/en-us/kb/150523
[3]
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724251(v=vs.85).aspx
(look for "socket")
[4]
https://msdn.microsoft.com/en-us/library/windows/desktop/ms741565(v=vs.85).aspx
> > Inheriting the descriptor of the listening socket is done regularly in
> > pre-forked multiprocess servers.
> >
> > The "prefork" bullet summarizes it:
> >
> > http://freeprogrammersblog.vhex.net/post/linux-39-introduced-new-way-of-writing-socket-servers/2
> >
> > > > > One problem that I haven't figured out yet: When starting a job using
> > > > > a
> > > > > shell, we get the PID of the shell. So we can kill the shell, but not
> > > > > the process that it started.
> > > >
> > > > Put the shell in a new session with setsid(). Killing all processes in
> > > > the session is done by sending the signal to the session leader (here:
> > > > the shell).
> > > >
> > > > Similar to daemon-izing a job.
> > > >
> > > > http://www.win.tue.nl/~aeb/linux/lk/lk-10.html#ss10.3
> > >
> > > Unfortunately that doesn't work. I used that in the test at first:
> > >
> > > let job = job_start(['/bin/sh', '-c', 'python test_channel.py
> > > </dev/null >/dev/null'])
> > > call getchar()
> > > call job_stop(job)
> > >
> > > While it's waiting for a character, check the processes. You should see
> > > both the shell and the python process. After pressing Enter the shell
> > > is gone but the python process keeps running. At least on my Ubuntu
> > > system.
> >
> > Ah right, you already use this in 7.4.1274.
> >
> > To correct myself: kill the negative of the PID of the session leader,
> > this sends the signal to all processes in its process group (!), see
> > kill(2):
> >
> > mch_stop_job():
> >
> > sig = atoi((char *)how);
> > else
> > return FAIL;
> > - kill(job->jv_pid, sig);
> > + kill(-job->jv_pid, sig);
> > return OK;
> > }
> > #endif
>
> Ah, forgot about that way. It's actually in os_unix.c.
>
> > This also triggers a sort of chain reaction that should bring down the
> > other process groups in the session (if any), unless they ignore SIGHUP:
> >
> > When the session leader exits, all processes in the foreground
> > process receive a SIGHUP.
> >
> > When the parent (typically the session leader) of a background
> > process group with at least one stopped process exits, all processes
> > in that background process group receive a SIGHUP. (And a SIGCONT,
> > which makes them continue running in the background in case they
> > ignore SIGHUP.)
> >
> > See more details in
> > - http://www.win.tue.nl/~aeb/linux/lk/lk-10.html#ss10.3
> > - man 2 setpgid
>
> So, should we do this always or make it an option? I think we should
> make this the default and have an option to only kill the process
> itself. Although the child of the child could use setsid() if it
> doesn't want to be killed.
I also think it should be the default. And probably it is overkill to
have an option that only kills the PID, because as you say, a child of a
child can use setsid() to avoid being killed.
But starting the server with "exec" when started from a shell should be
documented, as the server may otherwise not get killed (mentioned by
Gary and in one of my other mails).
--
Olaf Dabrunz (oda <at> fctrace.org)
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.