annotate contrib/chg/chg.c @ 28196:87de4a22e8c2

chg: hold a lock file before connected to server This is a part of the one server per config series. In multiple-server setup, multiple clients may try to start different servers (on demand) at the same time. The old lock will not guarantee a client to connect to the server it just started, and is not crash friendly. This patch addressed above issues by using flock and does not release the lock until the client actually connects to the server or times out.
author Jun Wu <quark@fb.com>
date Tue, 16 Feb 2016 11:08:52 +0000
parents 7623ba92af72
children a3d73e069f8d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
1 /*
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
2 * A fast client for Mercurial command server
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
3 *
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
4 * Copyright (c) 2011 Yuya Nishihara <yuya@tcha.org>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
5 *
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
6 * This software may be used and distributed according to the terms of the
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
7 * GNU General Public License version 2 or any later version.
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
8 */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
9
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
10 #include <assert.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
11 #include <errno.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
12 #include <fcntl.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
13 #include <signal.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
14 #include <stdio.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
15 #include <stdlib.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
16 #include <string.h>
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
17 #include <sys/file.h>
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
18 #include <sys/stat.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
19 #include <sys/types.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
20 #include <sys/un.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
21 #include <sys/wait.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
22 #include <time.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
23 #include <unistd.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
24
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
25 #include "hgclient.h"
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
26 #include "util.h"
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
27
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
28 #ifndef UNIX_PATH_MAX
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
29 #define UNIX_PATH_MAX (sizeof(((struct sockaddr_un *)NULL)->sun_path))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
30 #endif
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
31
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
32 struct cmdserveropts {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
33 char sockname[UNIX_PATH_MAX];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
34 char lockfile[UNIX_PATH_MAX];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
35 char pidfile[UNIX_PATH_MAX];
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
36 size_t argsize;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
37 const char **args;
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
38 int lockfd;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
39 };
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
40
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
41 static void initcmdserveropts(struct cmdserveropts *opts) {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
42 memset(opts, 0, sizeof(struct cmdserveropts));
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
43 opts->lockfd = -1;
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
44 }
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
45
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
46 static void freecmdserveropts(struct cmdserveropts *opts) {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
47 free(opts->args);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
48 opts->args = NULL;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
49 opts->argsize = 0;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
50 }
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
51
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
52 /*
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
53 * Test if an argument is a sensitive flag that should be passed to the server.
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
54 * Return 0 if not, otherwise the number of arguments starting from the current
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
55 * one that should be passed to the server.
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
56 */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
57 static size_t testsensitiveflag(const char *arg)
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
58 {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
59 static const struct {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
60 const char *name;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
61 size_t narg;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
62 } flags[] = {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
63 {"--config", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
64 {"--cwd", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
65 {"--repo", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
66 {"--repository", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
67 {"--traceback", 0},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
68 {"-R", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
69 };
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
70 size_t i;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
71 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
72 size_t len = strlen(flags[i].name);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
73 size_t narg = flags[i].narg;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
74 if (memcmp(arg, flags[i].name, len) == 0) {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
75 if (arg[len] == '\0') { /* --flag (value) */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
76 return narg + 1;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
77 } else if (arg[len] == '=' && narg > 0) { /* --flag=value */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
78 return 1;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
79 } else if (flags[i].name[1] != '-') { /* short flag */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
80 return 1;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
81 }
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
82 }
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
83 }
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
84 return 0;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
85 }
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
86
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
87 /*
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
88 * Parse argv[] and put sensitive flags to opts->args
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
89 */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
90 static void setcmdserverargs(struct cmdserveropts *opts,
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
91 int argc, const char *argv[])
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
92 {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
93 size_t i, step;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
94 opts->argsize = 0;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
95 for (i = 0, step = 1; i < (size_t)argc; i += step, step = 1) {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
96 if (!argv[i])
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
97 continue; /* pass clang-analyse */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
98 if (strcmp(argv[i], "--") == 0)
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
99 break;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
100 size_t n = testsensitiveflag(argv[i]);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
101 if (n == 0 || i + n > (size_t)argc)
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
102 continue;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
103 opts->args = reallocx(opts->args,
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
104 (n + opts->argsize) * sizeof(char *));
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
105 memcpy(opts->args + opts->argsize, argv + i,
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
106 sizeof(char *) * n);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
107 opts->argsize += n;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
108 step = n;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
109 }
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
110 }
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
111
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
112 static void preparesockdir(const char *sockdir)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
113 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
114 int r;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
115 r = mkdir(sockdir, 0700);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
116 if (r < 0 && errno != EEXIST)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
117 abortmsg("cannot create sockdir %s (errno = %d)",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
118 sockdir, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
119
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
120 struct stat st;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
121 r = lstat(sockdir, &st);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
122 if (r < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
123 abortmsg("cannot stat %s (errno = %d)", sockdir, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
124 if (!S_ISDIR(st.st_mode))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
125 abortmsg("cannot create sockdir %s (file exists)", sockdir);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
126 if (st.st_uid != geteuid() || st.st_mode & 0077)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
127 abortmsg("insecure sockdir %s", sockdir);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
128 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
129
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
130 static void setcmdserveropts(struct cmdserveropts *opts)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
131 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
132 int r;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
133 char sockdir[UNIX_PATH_MAX];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
134 const char *envsockname = getenv("CHGSOCKNAME");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
135 if (!envsockname) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
136 /* by default, put socket file in secure directory
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
137 * (permission of socket file may be ignored on some Unices) */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
138 const char *tmpdir = getenv("TMPDIR");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
139 if (!tmpdir)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
140 tmpdir = "/tmp";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
141 r = snprintf(sockdir, sizeof(sockdir), "%s/chg%d",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
142 tmpdir, geteuid());
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
143 if (r < 0 || (size_t)r >= sizeof(sockdir))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
144 abortmsg("too long TMPDIR (r = %d)", r);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
145 preparesockdir(sockdir);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
146 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
147
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
148 const char *basename = (envsockname) ? envsockname : sockdir;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
149 const char *sockfmt = (envsockname) ? "%s" : "%s/server";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
150 const char *lockfmt = (envsockname) ? "%s.lock" : "%s/lock";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
151 const char *pidfmt = (envsockname) ? "%s.pid" : "%s/pid";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
152 r = snprintf(opts->sockname, sizeof(opts->sockname), sockfmt, basename);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
153 if (r < 0 || (size_t)r >= sizeof(opts->sockname))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
154 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
155 r = snprintf(opts->lockfile, sizeof(opts->lockfile), lockfmt, basename);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
156 if (r < 0 || (size_t)r >= sizeof(opts->lockfile))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
157 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
158 r = snprintf(opts->pidfile, sizeof(opts->pidfile), pidfmt, basename);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
159 if (r < 0 || (size_t)r >= sizeof(opts->pidfile))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
160 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
161 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
162
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
163 /*
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
164 * Acquire a file lock that indicates a client is trying to start and connect
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
165 * to a server, before executing a command. The lock is released upon exit or
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
166 * explicit unlock. Will block if the lock is held by another process.
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
167 */
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
168 static void lockcmdserver(struct cmdserveropts *opts)
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
169 {
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
170 if (opts->lockfd == -1) {
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
171 opts->lockfd = open(opts->lockfile, O_RDWR | O_CREAT | O_NOFOLLOW, 0600);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
172 if (opts->lockfd == -1)
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
173 abortmsg("cannot create lock file %s", opts->lockfile);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
174 }
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
175 int r = flock(opts->lockfd, LOCK_EX);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
176 if (r == -1)
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
177 abortmsg("cannot acquire lock");
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
178 }
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
179
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
180 /*
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
181 * Release the file lock held by calling lockcmdserver. Will do nothing if
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
182 * lockcmdserver is not called.
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
183 */
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
184 static void unlockcmdserver(struct cmdserveropts *opts)
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
185 {
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
186 if (opts->lockfd == -1)
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
187 return;
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
188 flock(opts->lockfd, LOCK_UN);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
189 close(opts->lockfd);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
190 opts->lockfd = -1;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
191 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
192
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
193 static void execcmdserver(const struct cmdserveropts *opts)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
194 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
195 const char *hgcmd = getenv("CHGHG");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
196 if (!hgcmd || hgcmd[0] == '\0')
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
197 hgcmd = getenv("HG");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
198 if (!hgcmd || hgcmd[0] == '\0')
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
199 hgcmd = "hg";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
200
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
201 const char *baseargv[] = {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
202 hgcmd,
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
203 "serve",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
204 "--cwd", "/",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
205 "--cmdserver", "chgunix",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
206 "--address", opts->sockname,
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
207 "--daemon-postexec", "none",
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
208 "--pid-file", opts->pidfile,
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
209 "--config", "extensions.chgserver=",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
210 /* wrap root ui so that it can be disabled/enabled by config */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
211 "--config", "progress.assume-tty=1",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
212 };
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
213 size_t baseargvsize = sizeof(baseargv) / sizeof(baseargv[0]);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
214 size_t argsize = baseargvsize + opts->argsize + 1;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
215
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
216 const char **argv = mallocx(sizeof(char *) * argsize);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
217 memcpy(argv, baseargv, sizeof(baseargv));
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
218 memcpy(argv + baseargvsize, opts->args, sizeof(char *) * opts->argsize);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
219 argv[argsize - 1] = NULL;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
220
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
221 if (execvp(hgcmd, (char **)argv) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
222 abortmsg("failed to exec cmdserver (errno = %d)", errno);
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
223 free(argv);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
224 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
225
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
226 /* Retry until we can connect to the server. Give up after some time. */
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
227 static hgclient_t *retryconnectcmdserver(struct cmdserveropts *opts, pid_t pid)
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
228 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
229 static const struct timespec sleepreq = {0, 10 * 1000000};
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
230 int pst = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
231
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
232 for (unsigned int i = 0; i < 10 * 100; i++) {
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
233 hgclient_t *hgc = hgc_open(opts->sockname);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
234 if (hgc)
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
235 return hgc;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
236
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
237 if (pid > 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
238 /* collect zombie if child process fails to start */
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
239 int r = waitpid(pid, &pst, WNOHANG);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
240 if (r != 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
241 goto cleanup;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
242 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
243
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
244 nanosleep(&sleepreq, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
245 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
246
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
247 abortmsg("timed out waiting for cmdserver %s", opts->sockname);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
248 return NULL;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
249
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
250 cleanup:
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
251 if (WIFEXITED(pst)) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
252 abortmsg("cmdserver exited with status %d", WEXITSTATUS(pst));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
253 } else if (WIFSIGNALED(pst)) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
254 abortmsg("cmdserver killed by signal %d", WTERMSIG(pst));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
255 } else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
256 abortmsg("error white waiting cmdserver");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
257 }
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
258 return NULL;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
259 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
260
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
261 /* Connect to a cmdserver. Will start a new server on demand. */
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
262 static hgclient_t *connectcmdserver(struct cmdserveropts *opts)
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
263 {
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
264 hgclient_t *hgc = hgc_open(opts->sockname);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
265 if (hgc)
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
266 return hgc;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
267
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
268 lockcmdserver(opts);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
269 hgc = hgc_open(opts->sockname);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
270 if (hgc) {
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
271 unlockcmdserver(opts);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
272 debugmsg("cmdserver is started by another process");
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
273 return hgc;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
274 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
275
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
276 debugmsg("start cmdserver at %s", opts->sockname);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
277
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
278 pid_t pid = fork();
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
279 if (pid < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
280 abortmsg("failed to fork cmdserver process");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
281 if (pid == 0) {
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
282 /* do not leak lockfd to hg */
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
283 close(opts->lockfd);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
284 /* bypass uisetup() of pager extension */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
285 int nullfd = open("/dev/null", O_WRONLY);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
286 if (nullfd >= 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
287 dup2(nullfd, fileno(stdout));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
288 close(nullfd);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
289 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
290 execcmdserver(opts);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
291 } else {
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
292 hgc = retryconnectcmdserver(opts, pid);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
293 }
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
294
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
295 unlockcmdserver(opts);
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
296 return hgc;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
297 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
298
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
299 static void killcmdserver(const struct cmdserveropts *opts, int sig)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
300 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
301 FILE *fp = fopen(opts->pidfile, "r");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
302 if (!fp)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
303 abortmsg("cannot open %s (errno = %d)", opts->pidfile, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
304 int pid = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
305 int n = fscanf(fp, "%d", &pid);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
306 fclose(fp);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
307 if (n != 1 || pid <= 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
308 abortmsg("cannot read pid from %s", opts->pidfile);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
309
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
310 if (kill((pid_t)pid, sig) < 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
311 if (errno == ESRCH)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
312 return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
313 abortmsg("cannot kill %d (errno = %d)", pid, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
314 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
315 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
316
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
317 static pid_t peerpid = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
318
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
319 static void forwardsignal(int sig)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
320 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
321 assert(peerpid > 0);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
322 if (kill(peerpid, sig) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
323 abortmsg("cannot kill %d (errno = %d)", peerpid, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
324 debugmsg("forward signal %d", sig);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
325 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
326
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
327 static void handlestopsignal(int sig)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
328 {
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
329 sigset_t unblockset, oldset;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
330 struct sigaction sa, oldsa;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
331 if (sigemptyset(&unblockset) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
332 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
333 if (sigaddset(&unblockset, sig) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
334 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
335 memset(&sa, 0, sizeof(sa));
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
336 sa.sa_handler = SIG_DFL;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
337 sa.sa_flags = SA_RESTART;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
338 if (sigemptyset(&sa.sa_mask) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
339 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
340
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
341 forwardsignal(sig);
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
342 if (raise(sig) < 0) /* resend to self */
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
343 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
344 if (sigaction(sig, &sa, &oldsa) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
345 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
346 if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
347 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
348 /* resent signal will be handled before sigprocmask() returns */
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
349 if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
350 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
351 if (sigaction(sig, &oldsa, NULL) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
352 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
353 return;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
354
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
355 error:
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
356 abortmsg("failed to handle stop signal (errno = %d)", errno);
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
357 }
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
358
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
359 static void setupsignalhandler(pid_t pid)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
360 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
361 if (pid <= 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
362 return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
363 peerpid = pid;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
364
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
365 struct sigaction sa;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
366 memset(&sa, 0, sizeof(sa));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
367 sa.sa_handler = forwardsignal;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
368 sa.sa_flags = SA_RESTART;
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
369 if (sigemptyset(&sa.sa_mask) < 0)
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
370 goto error;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
371
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
372 if (sigaction(SIGHUP, &sa, NULL) < 0)
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
373 goto error;
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
374 if (sigaction(SIGINT, &sa, NULL) < 0)
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
375 goto error;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
376
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
377 /* terminate frontend by double SIGTERM in case of server freeze */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
378 sa.sa_flags |= SA_RESETHAND;
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
379 if (sigaction(SIGTERM, &sa, NULL) < 0)
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
380 goto error;
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
381
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
382 /* propagate job control requests to worker */
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
383 sa.sa_handler = forwardsignal;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
384 sa.sa_flags = SA_RESTART;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
385 if (sigaction(SIGCONT, &sa, NULL) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
386 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
387 sa.sa_handler = handlestopsignal;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
388 sa.sa_flags = SA_RESTART;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
389 if (sigaction(SIGTSTP, &sa, NULL) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
390 goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
391
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
392 return;
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
393
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
394 error:
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
395 abortmsg("failed to set up signal handlers (errno = %d)", errno);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
396 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
397
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
398 /* This implementation is based on hgext/pager.py (pre 369741ef7253) */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
399 static void setuppager(hgclient_t *hgc, const char *const args[],
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
400 size_t argsize)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
401 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
402 const char *pagercmd = hgc_getpager(hgc, args, argsize);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
403 if (!pagercmd)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
404 return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
405
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
406 int pipefds[2];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
407 if (pipe(pipefds) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
408 return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
409 pid_t pid = fork();
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
410 if (pid < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
411 goto error;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
412 if (pid == 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
413 close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
414 if (dup2(pipefds[1], fileno(stdout)) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
415 goto error;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
416 if (isatty(fileno(stderr))) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
417 if (dup2(pipefds[1], fileno(stderr)) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
418 goto error;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
419 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
420 close(pipefds[1]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
421 hgc_attachio(hgc); /* reattach to pager */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
422 return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
423 } else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
424 dup2(pipefds[0], fileno(stdin));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
425 close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
426 close(pipefds[1]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
427
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
428 int r = execlp("/bin/sh", "/bin/sh", "-c", pagercmd, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
429 if (r < 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
430 abortmsg("cannot start pager '%s' (errno = %d)",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
431 pagercmd, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
432 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
433 return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
434 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
435
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
436 error:
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
437 close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
438 close(pipefds[1]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
439 abortmsg("failed to prepare pager (errno = %d)", errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
440 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
441
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
442 int main(int argc, const char *argv[], const char *envp[])
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
443 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
444 if (getenv("CHGDEBUG"))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
445 enabledebugmsg();
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
446
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
447 struct cmdserveropts opts;
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
448 initcmdserveropts(&opts);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
449 setcmdserveropts(&opts);
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
450 setcmdserverargs(&opts, argc, argv);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
451
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
452 if (argc == 2) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
453 int sig = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
454 if (strcmp(argv[1], "--kill-chg-daemon") == 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
455 sig = SIGTERM;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
456 if (strcmp(argv[1], "--reload-chg-daemon") == 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
457 sig = SIGHUP;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
458 if (sig > 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
459 killcmdserver(&opts, sig);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
460 return 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
461 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
462 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
463
28196
87de4a22e8c2 chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents: 28194
diff changeset
464 hgclient_t *hgc = connectcmdserver(&opts);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
465 if (!hgc)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
466 abortmsg("cannot open hg client");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
467
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
468 setupsignalhandler(hgc_peerpid(hgc));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
469 hgc_setenv(hgc, envp);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
470 setuppager(hgc, argv + 1, argc - 1);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
471 int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
472 hgc_close(hgc);
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
473 freecmdserveropts(&opts);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
474 return exitcode;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
475 }