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 vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.