#
# patch "ChangeLog"
# from [3c7f71137a4c3af460295b48b0c0ccca3bca2ffd]
# to [f42ed6126e6a9e97ed93ffdf3c2ba001960ab902]
#
# patch "app_state.cc"
# from [da30ae47064dd3743fd31e7ce99dcb9c7fdf7813]
# to [a97a7bf9127e66d1d8e7d0577cad1ed86a0dc42f]
#
# patch "app_state.hh"
# from [27b58d6683bc026b41c07308738952067bf82926]
# to [a5ac3a99f998fee5a71b4f6201e6d26b086c7589]
#
# patch "commands.cc"
# from [dcc5c1e01f50623e13f34fffd221f6eeaefbb42a]
# to [dffdd24d07b1048fa1e02fab7353926776987720]
#
# patch "configure.ac"
# from [91aa8dc3693ec6a89a6fb6c0a3e9f987d493d1e4]
# to [184cb4ceea71542da6bb7ae96548a3efbb8a4a6d]
#
# patch "lua.cc"
# from [42373a056c2983c5f3d6303eb33c8c8ed88b2aae]
# to [6d767a93a1f123c5ee86f3e1dd352da1beecbbf9]
#
# patch "monotone.cc"
# from [7001aaae35d22a6d78dbda8638d3635ca8d1081e]
# to [bdcc7b74c7406ae184eb45958ee49ef02980e4fd]
#
# patch "monotone.texi"
# from [2e63f434deec3b8378969cc7d63cda1c225f9d42]
# to [24da1d645f7fd93432c75fc244657f26501077fe]
#
# patch "options.hh"
# from [0b886b3cfe2da40ca5e217f15c59d6593dd1de11]
# to [de2a21d88f641eeb889184d57af3c433b91556ec]
#
# patch "platform.hh"
# from [1f01b1dee6b2c96235160d63197f92f740790f8d]
# to [5f5c469fcbb9f1748ed15af94855a4402b95f0c2]
#
# patch "tests/t_netsync_sigpipe.at"
# from [87b55c8ec8fb09e514b35368e851c477c726bdaa]
# to [773f9ac6d0592673c109f68618bcdbf0ff5a17f9]
#
# patch "tests/t_netsync_single.at"
# from [faa5253849ae86d140b67fb93609d191456b0ec3]
# to [d7b40fcf0529e589e987774f569edeae0889257f]
#
# patch "testsuite.at"
# from [a62d0f8215b1359408ce4621cbd50bae9a9c1c94]
# to [c367205bf28bd3358c49e3525815e48b134316fb]
#
# patch "unix/process.cc"
# from [3dfbca0b6549d1b91d19960ed704d6e4ed8ea042]
# to [0cfa3c05d2dc345fedae7351557b46a502d14c05]
#
# patch "win32/process.cc"
# from [8290190317b7b74e281eaa749b50393c32928928]
# to [a7d8affe8f0801f5220771f1022285936d48d1f7]
#
--- ChangeLog
+++ ChangeLog
@@ -1,5 +1,25 @@
2005-05-05 Matthew Gregan
+ * monotone.texi: Document --pid-file option for serve command.
+ * app_state.{cc,hh} (set_pidfile, pidfile): New function, new
+ member.
+ * commands.cc (pid_file): New class.
+ (CMD(serve)): Use pid_file.
+ * monotone.cc (coptions, cppmain): Add command-specific option
+ --pid-file.
+ * options.hh (OPT_PIDFILE): New option.
+ * {unix,win32}/process.cc (get_process_id): New function.
+ (process_{spawn,wait,kill}): Use pid_t.
+ * platform.hh (process_{spawn,wait,kill}): Use pid_t.
+ (get_process_id): New function
+ * configure.ac: Test for pid_t.
+ * lua.cc (monotone_{spawn,wait,kill}_for_lua): Use pid_t.
+ * testsuite.at: Update netsync kill functions to use pid file.
+ * tests/t_netsync_sigpipe.at: Update to use pid file.
+ * tests/t_netsync_single.at: Update to use pid file.
+
+2005-05-05 Matthew Gregan
+
* work.cc: Use attr_file_name rather than hardcoded strings.
2005-05-04 Brian Campbell
--- app_state.cc
+++ app_state.cc
@@ -294,6 +294,12 @@
}
void
+app_state::set_pidfile(utf8 const & p)
+{
+ pidfile = mkpath(p());
+}
+
+void
app_state::add_revision(utf8 const & selector)
{
revision_selectors.push_back(selector);
--- app_state.hh
+++ app_state.hh
@@ -42,6 +42,7 @@
file_path relative_directory;
bool found_working_copy;
long depth;
+ fs::path pidfile;
void allow_working_copy();
void require_working_copy();
@@ -67,6 +68,7 @@
void set_date(utf8 const & date);
void set_author(utf8 const & author);
void set_depth(long depth);
+ void set_pidfile(utf8 const & pidfile);
void add_revision(utf8 const & selector);
void set_stdhooks(bool b);
--- commands.cc
+++ commands.cc
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -275,6 +276,37 @@
process(app, string(#realcommand), args); \
}
+struct pid_file
+{
+ explicit pid_file(fs::path const & p)
+ : path(p)
+ {
+ if (path == "")
+ return;
+ N(!fs::exists(path), F("pid file '%s' already exists") % path.string());
+ file.open(path);
+ file << get_process_id();
+ file.flush();
+ P(F("pid file '%s' created for pid '%d'") % path.string() % get_process_id());
+ }
+
+ ~pid_file()
+ {
+ if (path == "")
+ return;
+ pid_t pid;
+ fs::ifstream(path) >> pid;
+ if (pid == get_process_id()) {
+ file.close();
+ fs::remove(path);
+ }
+ }
+
+private:
+ fs::ofstream file;
+ fs::path path;
+};
+
static void
maybe_update_inodeprints(app_state & app)
{
@@ -1989,11 +2021,13 @@
}
CMD(serve, "network", "ADDRESS[:PORTNUMBER] COLLECTION...",
- "listen on ADDRESS and serve COLLECTION to connecting clients", OPT_NONE)
+ "listen on ADDRESS and serve COLLECTION to connecting clients", OPT_PIDFILE)
{
if (args.size() < 2)
throw usage(name);
+ pid_file pid(app.pidfile);
+
rsa_keypair_id key;
N(guess_default_key(key, app), F("could not guess default signing key"));
app.signing_key = key;
--- configure.ac
+++ configure.ac
@@ -378,11 +378,26 @@
ac_cv_type_socklen_t=no)
])
if test $ac_cv_type_socklen_t = yes; then
- AC_DEFINE(HAVE_SOCKLEN_T, 1, [Define if platform has real socklen_t.])
+ AC_DEFINE(HAVE_SOCKLEN_T, 1, [Define if platform has socklen_t.])
fi
])
TYPE_SOCKLEN_T
+AC_DEFUN([TYPE_PID_T],
+[AC_CACHE_CHECK([for pid_t], ac_vs_type_pid_t,
+[
+ AC_TRY_COMPILE(
+ [#include ],
+ [pid_t pid = 42; return 0;],
+ ac_cv_type_pid_t=yes,
+ ac_cv_type_pid_t=no)
+])
+ if test $ac_cv_type_socklen_t = no; then
+ AC_DEFINE(pid_t, unsigned long, [pid_t substitute.])
+ fi
+])
+TYPE_PID_T
+
# Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_FUNC_STAT
--- lua.cc
+++ lua.cc
@@ -110,7 +110,8 @@
int n = lua_gettop(L);
const char *path = lua_tostring(L, -n);
char **argv = (char**)malloc((n+1)*sizeof(char*));
- int ret, i;
+ int i;
+ pid_t ret;
if (argv==NULL)
return 0;
argv[0] = (char*)path;
@@ -125,7 +126,7 @@
static int
monotone_wait_for_lua(lua_State *L)
{
- int pid = (int)lua_tonumber(L, -1);
+ pid_t pid = (pid_t)lua_tonumber(L, -1);
int res;
int ret;
ret = process_wait(pid, &res);
@@ -138,7 +139,7 @@
monotone_kill_for_lua(lua_State *L)
{
int n = lua_gettop(L);
- int pid = (int)lua_tonumber(L, -2);
+ pid_t pid = (pid_t)lua_tonumber(L, -2);
int sig;
if (n>1)
sig = (int)lua_tonumber(L, -1);
--- monotone.cc
+++ monotone.cc
@@ -47,6 +47,7 @@
{"date", 0, POPT_ARG_STRING, &argstr, OPT_DATE, "override date/time for commit", NULL},
{"author", 0, POPT_ARG_STRING, &argstr, OPT_AUTHOR, "override author for commit", NULL},
{"depth", 0, POPT_ARG_LONG, &arglong, OPT_DEPTH, "limit the log output to the given number of entries", NULL},
+ {"pid-file", 0, POPT_ARG_STRING, &argstr, OPT_PIDFILE, "record process id of server", NULL},
{ NULL, 0, 0, NULL, 0, NULL, NULL }
};
@@ -348,6 +349,10 @@
app.set_depth(arglong);
break;
+ case OPT_PIDFILE:
+ app.set_pidfile(string(argstr));
+ break;
+
case OPT_ARGFILE:
my_poptStuffArgFile(ctx(), utf8(string(argstr)));
break;
--- monotone.texi
+++ monotone.texi
@@ -3610,6 +3610,11 @@
these will clear your defaults, and cause them to be reset to the next
person you netsync with.
+If a option @option{--pid-file} is specified, the command
address@hidden will create the specified file and record the process
+identifier of the server in the file. This file can then be read to
+identify specific monotone server processes.
+
@end ftable
--- options.hh
+++ options.hh
@@ -28,4 +28,4 @@
#define OPT_DATE 19
#define OPT_AUTHOR 20
#define OPT_ALL_FILES 21
+#define OPT_PIDFILE 22
-
--- platform.hh
+++ platform.hh
@@ -12,6 +12,7 @@
#include
#include "vocab.hh"
+#include "config.h"
void read_password(std::string const & prompt, char * buf, size_t bufsz);
void get_system_flavour(std::string & ident);
@@ -20,9 +21,9 @@
// For LUA
int existsonpath(const char *exe);
int make_executable(const char *path);
-int process_spawn(const char * const argv[]);
-int process_wait(int pid, int *res);
-int process_kill(int pid, int signal);
+pid_t process_spawn(const char * const argv[]);
+int process_wait(pid_t pid, int *res);
+int process_kill(pid_t pid, int signal);
int process_sleep(unsigned int seconds);
// for term selection
@@ -42,4 +43,7 @@
// changed.
bool inodeprint_file(file_path const & file, hexenc & ip);
+// for netsync 'serve' pidfile support
+pid_t get_process_id();
+
#endif // __PLATFORM_HH__
--- tests/t_netsync_sigpipe.at
+++ tests/t_netsync_sigpipe.at
@@ -5,13 +5,9 @@
m4_define([NETSYNC_KILLPIPE], [
if test "$OSTYPE" == "msys"; then
- #ps |awk -- '{p=$NF;a=1;if(p=="COMMAND")next;pp=split(p,ps,"/");if(ps[[pp]]=="monotone")system("kill -PIPE " $a);}'
- # If we really wanted to do this on Windows, the above is correct. But
- # there is no SIGPIPE on Windows and hence we don't really need to test this
- # behaviour there. Hence, we just do nothing.
echo "No SIGPIPE on MinGW"
else
- killall -PIPE monotone 2>/dev/null
+ kill -PIPE `cat monotone_at.pid` 2>/dev/null
fi
])
--- tests/t_netsync_single.at
+++ tests/t_netsync_single.at
@@ -24,7 +24,7 @@
VER0=`BASE_REVISION`
NETSYNC_KILLHARD
- MONOTONE --rcfile=netsync.lua serve 127.0.0.1:$_PORT testbranch &
+ MONOTONE --rcfile=netsync.lua --pid-file=monotone_at.pid serve 127.0.0.1:$_PORT testbranch &
sleep 5
AT_CHECK(MONOTONE --rcfile=netsync.lua --db=test2.db pull 127.0.0.1:$_PORT testbranch, [], [ignore], [ignore])
NETSYNC_KILLHARD
--- testsuite.at
+++ testsuite.at
@@ -334,32 +334,25 @@
m4_define([MONOTONE3], MONOTONE --db=test3.db)
m4_define([NETSYNC_KILL], [
-if test "$OSTYPE" == "msys"; then
- ps |awk -- '{p=$NF;a=1;if(p=="COMMAND")next;pp=split(p,ps,"/");if(ps[[pp]]=="monotone")system("kill " $a);}'
- # MinGW has no killall. The weird a=1 thing is to avoid autotest treating $1 as its own parameter
-else
- killall monotone 2>/dev/null
-fi
+ kill `cat monotone_at.pid` 2>/dev/null
+ rm -f monotone_at.pid 2>/dev/null
])
m4_define([NETSYNC_KILLHARD], [
-if test "$OSTYPE" == "msys"; then
- ps |awk -- '{p=$NF;a=1;if(p=="COMMAND")next;pp=split(p,ps,"/");if(ps[[pp]]=="monotone")system("kill -KILL " $a);}'
-else
- killall -KILL monotone 2>/dev/null
-fi
+ kill -KILL `cat monotone_at.pid` 2>/dev/null
+ rm -f monotone_at.pid 2>/dev/null
])
# run as NETSYNC_SERVE_N_START(2|3, collection name)
# note that NETSYNC_SERVE_START is _not_ a special case of this macro.
m4_define([NETSYNC_SERVE_N_START], [
NETSYNC_KILLHARD
-MONOTONE --db=test$1.db --rcfile=netsync.lua serve localhost:$_PORT $2 &
+MONOTONE --db=test$1.db --rcfile=netsync.lua --pid-file=monotone_at.pid serve localhost:$_PORT $2 &
sleep 4
])
# run as NETSYNC_SERVE_START(collection name)
m4_define([NETSYNC_SERVE_START], [
NETSYNC_KILLHARD
-MONOTONE --rcfile=netsync.lua serve localhost:$_PORT $1 &
+MONOTONE --rcfile=netsync.lua --pid-file=monotone_at.pid serve localhost:$_PORT $1 &
sleep 4
])
# run as NETSYNC_SERVE_STOP
--- unix/process.cc
+++ unix/process.cc
@@ -50,7 +50,7 @@
return chmod(path, mode);
}
-int process_spawn(const char * const argv[])
+pid_t process_spawn(const char * const argv[])
{
{
std::ostringstream cmdline_ss;
@@ -72,14 +72,14 @@
execvp(argv[0], (char * const *)argv);
return -1;
default: /* Parent */
- return (int)pid;
+ return pid;
}
}
-int process_wait(int pid, int *res)
+int process_wait(pid_t pid, int *res)
{
int status;
- pid = waitpid((pid_t)pid, &status, 0);
+ pid = waitpid(pid, &status, 0);
if (WIFEXITED(status))
*res = WEXITSTATUS(status);
else
@@ -87,12 +87,17 @@
return 0;
}
-int process_kill(int pid, int signal)
+int process_kill(pid_t pid, int signal)
{
- return kill((pid_t)pid, signal);
+ return kill(pid, signal);
}
int process_sleep(unsigned int seconds)
{
return sleep(seconds);
}
+
+pid_t get_process_id()
+{
+ return getpid();
+}
--- win32/process.cc
+++ win32/process.cc
@@ -27,7 +27,7 @@
return 0; /* Basically meaningless on win32 */
}
-int process_spawn(const char * const argv[])
+pid_t process_spawn(const char * const argv[])
{
int i;
char *realexe,*filepart;
@@ -88,10 +88,10 @@
}
free(realexe);
CloseHandle(pi.hThread);
- return (int)pi.hProcess;
+ return pi.hProcess;
}
-int process_wait(int pid, int *res)
+pid_t process_wait(pid_t pid, int *res)
{
HANDLE hProcess = (HANDLE)pid;
if (WaitForSingleObject(hProcess, INFINITE)==WAIT_FAILED)
@@ -105,7 +105,7 @@
return 0;
}
-int process_kill(int pid, int signal)
+int process_kill(pid_t pid, int signal)
{
HANDLE hProcess = (HANDLE)pid;
if (TerminateProcess(hProcess, 1)==0)
@@ -118,3 +118,9 @@
Sleep(seconds*1000);
return 0;
}
+
+pid_t get_process_id()
+{
+ return GetCurrentProcessId();
+}
+