# # # add_file "unix/daemon.cc" # content [f10672e1d501272a8c4c5027ed639f7de10d0ab8] # # add_file "unix/daemon.hh" # content [652cb59f39274c1ea11712328643b0b23716a376] # # add_file "win32/daemon.cc" # content [fb371c2e81b38830feac7641c237903eb4c5c785] # # add_file "win32/daemon.hh" # content [652cb59f39274c1ea11712328643b0b23716a376] # # patch "Makefile.am" # from [7a289c286cb568f7d14c83d24c94a7acec59673f] # to [232ec95b0d3a71ffc4f47fae1fb8364d512ee388] # # patch "cmd_netsync.cc" # from [f4a2db3f6b8328be21ec35f193179c22a7701890] # to [bcf169ee5b4a5755f5c46f8621e750bdbc9ba3ba] # # patch "configure.ac" # from [a100a56bd096ec316643df4f2e0a8d0fb78ca6e0] # to [7b692d1a4c042e4bb273eaec736c8970eae703c3] # # patch "monotone.texi" # from [993c049a3eafadf83595962ac7987472ccae8188] # to [42378e9e8558c9a8bb77163302c3cf295df0f7b4] # # patch "platform.hh" # from [5416e93a52cebdf882b7a6692b89e3b2aacb7562] # to [11e928dd5c3c5538e69634d10434529773518daf] # # patch "tests/persistent_netsync_server_-_daemon/__driver__.lua" # from [6efa25b23dc88ad6e22d89fdd6ba561b9ea9c419] # to [b185ecc4a0bd8e26a2aa8a3b25554cf901831e49] # ============================================================ --- unix/daemon.cc f10672e1d501272a8c4c5027ed639f7de10d0ab8 +++ unix/daemon.cc f10672e1d501272a8c4c5027ed639f7de10d0ab8 @@ -0,0 +1,114 @@ +/* +** daemon() -- daemonize current process, fallback for daemon(3) +** Copyright (c) 1999-2005 Ralf S. Engelschall +** Copyright (c) 2007 Ben Walton +** +** Imported to monotone with Ralf's permission as per: +** http://www.nabble.com/forum/ViewPost.jtp?post=12613057&framed=y +** +** This program is made available under the GNU GPL version 2.0 or +** greater. See the accompanying file COPYING for details. +** +** This program is distributed WITHOUT ANY WARRANTY; without even the +** implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +** PURPOSE. +*/ + +#include + +#ifdef HAVE_DAEMON +int mtn_daemon(int nochdir, int noclose) +{ + return(daemon(nochdir, noclose)); +} +#else + +#include +#include +#include +#include +#include + +int mtn_daemon(int nochdir, int noclose) +{ + int fd; + int rc; + + /* ignore tty related signals */ +#ifdef SIGTTOU + signal(SIGTTOU, SIG_IGN); +#endif +#ifdef SIGTTIN + signal(SIGTTIN, SIG_IGN); +#endif +#ifdef SIGTSTP + signal(SIGTSTP, SIG_IGN); +#endif + + /* fork so the parent can exit, this returns control to the command line + or shell invoking your program. This step is required so that the new + process is guaranteed not to be a process group leader (The next step, + setsid, would fail if you're a process group leader). */ + rc = fork(); + switch (rc) { + case -1: return -1; + case 0: break; + default: _exit(0); /* exit original process */ + } + + /* setsid to become a process group and session group leader. Since a + controlling terminal is associated with a session, and this new session + has not yet acquired a controlling terminal our process now has no + controlling terminal, which is a Good Thing for daemons. */ +#ifdef HAVE_SETSID + if (setsid() == -1) + return -1; +#else + if (setpgid(0, getpid()) == -1) + return -1; +#ifndef _PATH_TTY +#define _PATH_TTY "/dev/tty" +#endif + if ((fd = open(_PATH_TTY, O_RDWR)) == -1) + return -1; + ioctl(fd, TIOCNOTTY, NULL); + close(fd); +#endif + + /* fork again so the parent (the session group leader) can exit. This + means that we, as a non-session group leader, can never regain a + controlling terminal. */ + rc = fork(); + switch (rc) { + case -1: return -1; + case 0: break; + default: _exit(0); /* exit original process */ + } + + /* change to root directory ensure that our process doesn't keep + any directory in use. Failure to do this could make it so that + an administrator couldn't unmount a filesystem, because it was + our current directory. [Equivalently, we could change to any + directory containing files important to the daemon's operation.] */ + if (!nochdir) + chdir("/"); + + /* give us complete control over the permissions of anything we + write. We don't know what umask we may have inherited. + [This step is optional] */ + umask(0); + + /* close fds 0, 1, and 2. This releases the standard in, out, and + error we inherited from our parent process. We have no way of + knowing where these fds might have been redirected to. */ + if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + if (fd > 2) + close(fd); + } + + return 0; +} +#endif ============================================================ --- unix/daemon.hh 652cb59f39274c1ea11712328643b0b23716a376 +++ unix/daemon.hh 652cb59f39274c1ea11712328643b0b23716a376 @@ -0,0 +1,15 @@ +#ifndef __DAEMON_HH__ +#define __DAEMON_HH__ + +// Copyright (C) 2007 Ben Walton +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +int mtn_daemon(int nochdir, int noclose); + +#endif //__DAEMON_HH__ ============================================================ --- win32/daemon.cc fb371c2e81b38830feac7641c237903eb4c5c785 +++ win32/daemon.cc fb371c2e81b38830feac7641c237903eb4c5c785 @@ -0,0 +1,22 @@ +/* +** daemon() -- daemonize current process, fallback for daemon(3) +** Copyright (c) 2007 Ben Walton +** +** This is the windows version, which 'does nothing.' See unix/daemon.cc +** for Ralf's original daemon(3) workalike code. +** +** Licensed for use under the GPL (v2 or greater). See COPYING for +** details. +*/ + + +int mtn_daemon(int nochdir, int noclose) +{ +#ifndef HAVE_DAEMON + //if we don't have a real daemon(3) available, we'll no-op + return 0; +#else + //otherwise, use the system version + return (daemon(nochdir, noclose)); +#endif +} ============================================================ --- win32/daemon.hh 652cb59f39274c1ea11712328643b0b23716a376 +++ win32/daemon.hh 652cb59f39274c1ea11712328643b0b23716a376 @@ -0,0 +1,15 @@ +#ifndef __DAEMON_HH__ +#define __DAEMON_HH__ + +// Copyright (C) 2007 Ben Walton +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +int mtn_daemon(int nochdir, int noclose); + +#endif //__DAEMON_HH__ ============================================================ --- Makefile.am 7a289c286cb568f7d14c83d24c94a7acec59673f +++ Makefile.am 232ec95b0d3a71ffc4f47fae1fb8364d512ee388 @@ -277,14 +277,16 @@ UNIX_PLATFORM_SOURCES = \ unix/process.cc unix/terminal.cc unix/inodeprint.cc \ unix/fs.cc unix/make_io_binary.cc unix/os_strerror.cc \ unix/cputime.cc unix/ssh_agent_platform.cc \ - unix/ssh_agent_platform.hh unix/tester-plaf.cc + unix/ssh_agent_platform.hh unix/tester-plaf.cc \ + unix/daemon.hh unix/daemon.cc WIN32_PLATFORM_SOURCES = \ win32/read_password.cc win32/get_system_flavour.cc \ win32/process.cc win32/terminal.cc win32/inodeprint.cc \ win32/fs.cc win32/make_io_binary.cc win32/os_strerror.cc \ win32/cputime.cc win32/ssh_agent_platform.cc \ - win32/ssh_agent_platform.hh win32/tester-plaf.cc + win32/ssh_agent_platform.hh win32/tester-plaf.cc \ + win32/daemon.hh win32/daemon.cc # these files contain unit tests UNIT_TEST_SOURCES = \ ============================================================ --- cmd_netsync.cc f4a2db3f6b8328be21ec35f193179c22a7701890 +++ cmd_netsync.cc bcf169ee5b4a5755f5c46f8621e750bdbc9ba3ba @@ -516,7 +516,7 @@ CMD_NO_WORKSPACE(serve, "serve", "", CMD //has a chance to do manual/interactive entry of the passphrase if they //so desire. if (app.opts.daemon) - E(daemon(0, 0) == 0, + E(mtn_daemon(0, 0) == 0, F("call to daemon failed!")); //do this after the call to daemon (if the option is used) so that we ============================================================ --- configure.ac a100a56bd096ec316643df4f2e0a8d0fb78ca6e0 +++ configure.ac 7b692d1a4c042e4bb273eaec736c8970eae703c3 @@ -120,7 +120,7 @@ AC_CHECK_FUNCS([atexit memset mkstemp st AC_FUNC_ICONV_TRANSLIT AC_CHECK_FUNCS([atexit memset mkstemp strptime lrint \ __cxa_current_exception_type __cxa_demangle \ - putenv setenv unsetenv dirfd fstatat mkdtemp]) + putenv setenv unsetenv dirfd fstatat mkdtemp daemon]) # simple library checks AC_SEARCH_LIBS([deflate], [z], , AC_MSG_FAILURE([zlib is required])) ============================================================ --- monotone.texi 993c049a3eafadf83595962ac7987472ccae8188 +++ monotone.texi 42378e9e8558c9a8bb77163302c3cf295df0f7b4 @@ -4725,7 +4725,9 @@ @section Network If a @option{--daemon} option is specified, the command @command{serve} will detach itself from the controlling terminal and run in the background. This -option requires the use of the @option{--pid-file} option. +option requires the use of the @option{--pid-file} option. This option is +honoured on Windows, but will only have effect if there is support for the +required calls in the target platform. If a @option{--pid-file} option is specified, the command @command{serve} will create the specified file and record the process ============================================================ --- platform.hh 5416e93a52cebdf882b7a6692b89e3b2aacb7562 +++ platform.hh 11e928dd5c3c5538e69634d10434529773518daf @@ -150,10 +150,13 @@ std::string get_locale_dir(); #ifdef WIN32_PLATFORM #include "win32/ssh_agent_platform.hh" +#include "win32/daemon.hh" #else #include "unix/ssh_agent_platform.hh" +#include "unix/daemon.hh" #endif + // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- tests/persistent_netsync_server_-_daemon/__driver__.lua 6efa25b23dc88ad6e22d89fdd6ba561b9ea9c419 +++ tests/persistent_netsync_server_-_daemon/__driver__.lua b185ecc4a0bd8e26a2aa8a3b25554cf901831e49 @@ -1,4 +1,4 @@ - +skip_if(ostype == "Windows") include("/common/netsync.lua") mtn_setup() netsync.setup() @@ -14,3 +14,4 @@ check({'kill', pid}, 0, false, false) --kill the process (if this fails, the pid wasn't --running in the background anyway) check({'kill', pid}, 0, false, false) +runcmd({'rm', './pid1'})