contrib/chg/chg.c
author Jun Wu <quark@fb.com>
Mon, 22 Feb 2016 16:59:08 +0000
changeset 28194 7623ba92af72
parent 28167 66f6dad20c19
child 28196 87de4a22e8c2
permissions -rw-r--r--
serve: rename --daemon-pipefds to --daemon-postexec (BC) Initially we use --daemon-pipefds to pass file descriptors for synchronization. Later, in order to support Windows, --daemon-pipefds is changed to accept a file path to unlink instead. The name is outdated since then. chg client is designed to use flock, which will be held before starting a server and until the client actually connects to the server it started. The unlink synchronization approach is not so helpful in this case. To address the issues, this patch renames pipefds to postexec and the following patch will allow the value of --daemon-postexec to be things like 'unlink:/path/to/file' or 'none'.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    17
#include <sys/stat.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    18
#include <sys/types.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    19
#include <sys/un.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    20
#include <sys/wait.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    21
#include <time.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    22
#include <unistd.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    23
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    24
#include "hgclient.h"
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    25
#include "util.h"
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    26
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    27
#ifndef UNIX_PATH_MAX
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    28
#define UNIX_PATH_MAX (sizeof(((struct sockaddr_un *)NULL)->sun_path))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    29
#endif
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    30
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    31
struct cmdserveropts {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    32
	char sockname[UNIX_PATH_MAX];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    33
	char lockfile[UNIX_PATH_MAX];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    34
	char pidfile[UNIX_PATH_MAX];
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    35
	size_t argsize;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    36
	const char **args;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    37
};
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    38
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    39
static void initcmdserveropts(struct cmdserveropts *opts) {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    40
	memset(opts, 0, sizeof(struct cmdserveropts));
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    41
}
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    42
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    43
static void freecmdserveropts(struct cmdserveropts *opts) {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    44
	free(opts->args);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    45
	opts->args = NULL;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    46
	opts->argsize = 0;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    47
}
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    48
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    49
/*
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    50
 * 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
    51
 * 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
    52
 * 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
    53
 */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    54
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
    55
{
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    56
	static const struct {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    57
		const char *name;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    58
		size_t narg;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    59
	} flags[] = {
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    60
		{"--config", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    61
		{"--cwd", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    62
		{"--repo", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    63
		{"--repository", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    64
		{"--traceback", 0},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    65
		{"-R", 1},
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    66
	};
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    67
	size_t i;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    68
	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
    69
		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
    70
		size_t narg = flags[i].narg;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    71
		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
    72
			if (arg[len] == '\0') {  /* --flag (value) */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    73
				return narg + 1;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    74
			} 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
    75
				return 1;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    76
			} 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
    77
				return 1;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    78
			}
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    79
		}
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    80
	}
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    81
	return 0;
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
/*
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    85
 * 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
    86
 */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    87
static void setcmdserverargs(struct cmdserveropts *opts,
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    88
			     int argc, const char *argv[])
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
	size_t i, step;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    91
	opts->argsize = 0;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    92
	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
    93
		if (!argv[i])
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    94
			continue;  /* pass clang-analyse */
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    95
		if (strcmp(argv[i], "--") == 0)
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    96
			break;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    97
		size_t n = testsensitiveflag(argv[i]);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
    98
		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
    99
			continue;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   100
		opts->args = reallocx(opts->args,
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   101
				      (n + opts->argsize) * sizeof(char *));
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   102
		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
   103
		       sizeof(char *) * n);
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   104
		opts->argsize += n;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   105
		step = n;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   106
	}
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   107
}
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   108
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   109
static void preparesockdir(const char *sockdir)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   110
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   111
	int r;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   112
	r = mkdir(sockdir, 0700);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   113
	if (r < 0 && errno != EEXIST)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   114
		abortmsg("cannot create sockdir %s (errno = %d)",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   115
			 sockdir, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   116
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   117
	struct stat st;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   118
	r = lstat(sockdir, &st);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   119
	if (r < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   120
		abortmsg("cannot stat %s (errno = %d)", sockdir, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   121
	if (!S_ISDIR(st.st_mode))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   122
		abortmsg("cannot create sockdir %s (file exists)", sockdir);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   123
	if (st.st_uid != geteuid() || st.st_mode & 0077)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   124
		abortmsg("insecure sockdir %s", sockdir);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   125
}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   126
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   127
static void setcmdserveropts(struct cmdserveropts *opts)
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
	int r;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   130
	char sockdir[UNIX_PATH_MAX];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   131
	const char *envsockname = getenv("CHGSOCKNAME");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   132
	if (!envsockname) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   133
		/* by default, put socket file in secure directory
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   134
		 * (permission of socket file may be ignored on some Unices) */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   135
		const char *tmpdir = getenv("TMPDIR");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   136
		if (!tmpdir)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   137
			tmpdir = "/tmp";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   138
		r = snprintf(sockdir, sizeof(sockdir), "%s/chg%d",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   139
			     tmpdir, geteuid());
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   140
		if (r < 0 || (size_t)r >= sizeof(sockdir))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   141
			abortmsg("too long TMPDIR (r = %d)", r);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   142
		preparesockdir(sockdir);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   143
	}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   144
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   145
	const char *basename = (envsockname) ? envsockname : sockdir;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   146
	const char *sockfmt = (envsockname) ? "%s" : "%s/server";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   147
	const char *lockfmt = (envsockname) ? "%s.lock" : "%s/lock";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   148
	const char *pidfmt = (envsockname) ? "%s.pid" : "%s/pid";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   149
	r = snprintf(opts->sockname, sizeof(opts->sockname), sockfmt, basename);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   150
	if (r < 0 || (size_t)r >= sizeof(opts->sockname))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   151
		abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   152
	r = snprintf(opts->lockfile, sizeof(opts->lockfile), lockfmt, basename);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   153
	if (r < 0 || (size_t)r >= sizeof(opts->lockfile))
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->pidfile, sizeof(opts->pidfile), pidfmt, basename);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   156
	if (r < 0 || (size_t)r >= sizeof(opts->pidfile))
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
}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   159
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   160
/*
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   161
 * Make lock file that indicates cmdserver process is about to start. Created
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   162
 * lock file will be deleted by server. (0: success, -1: lock exists)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   163
 */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   164
static int lockcmdserver(const struct cmdserveropts *opts)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   165
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   166
	int r;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   167
	char info[32];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   168
	r = snprintf(info, sizeof(info), "%d", getpid());
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   169
	if (r < 0 || (size_t)r >= sizeof(info))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   170
		abortmsg("failed to format lock info");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   171
	r = symlink(info, opts->lockfile);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   172
	if (r < 0 && errno != EEXIST)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   173
		abortmsg("failed to make lock %s (errno = %d)",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   174
			 opts->lockfile, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   175
	return r;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   176
}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   177
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   178
static void execcmdserver(const struct cmdserveropts *opts)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   179
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   180
	const char *hgcmd = getenv("CHGHG");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   181
	if (!hgcmd || hgcmd[0] == '\0')
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   182
		hgcmd = getenv("HG");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   183
	if (!hgcmd || hgcmd[0] == '\0')
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   184
		hgcmd = "hg";
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   185
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   186
	const char *baseargv[] = {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   187
		hgcmd,
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   188
		"serve",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   189
		"--cwd", "/",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   190
		"--cmdserver", "chgunix",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   191
		"--address", opts->sockname,
28194
7623ba92af72 serve: rename --daemon-pipefds to --daemon-postexec (BC)
Jun Wu <quark@fb.com>
parents: 28167
diff changeset
   192
		"--daemon-postexec", opts->lockfile,
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   193
		"--pid-file", opts->pidfile,
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   194
		"--config", "extensions.chgserver=",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   195
		/* 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
   196
		"--config", "progress.assume-tty=1",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   197
	};
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   198
	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
   199
	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
   200
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   201
	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
   202
	memcpy(argv, baseargv, sizeof(baseargv));
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   203
	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
   204
	argv[argsize - 1] = NULL;
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   205
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   206
	if (execvp(hgcmd, (char **)argv) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   207
		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
   208
	free(argv);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   209
}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   210
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   211
/*
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   212
 * Sleep until lock file is deleted, i.e. cmdserver process starts listening.
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   213
 * If pid is given, it also checks if the child process fails to start.
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   214
 */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   215
static void waitcmdserver(const struct cmdserveropts *opts, pid_t pid)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   216
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   217
	static const struct timespec sleepreq = {0, 10 * 1000000};
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   218
	int pst = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   219
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   220
	for (unsigned int i = 0; i < 10 * 100; i++) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   221
		int r;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   222
		struct stat lst;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   223
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   224
		r = lstat(opts->lockfile, &lst);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   225
		if (r < 0 && errno == ENOENT)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   226
			return;  /* lock file deleted by server */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   227
		if (r < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   228
			goto cleanup;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   229
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   230
		if (pid > 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   231
			/* collect zombie if child process fails to start */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   232
			r = waitpid(pid, &pst, WNOHANG);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   233
			if (r != 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   234
				goto cleanup;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   235
		}
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
		nanosleep(&sleepreq, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   238
	}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   239
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   240
	abortmsg("timed out waiting for cmdserver %s", opts->lockfile);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   241
	return;
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
cleanup:
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   244
	if (pid > 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   245
		/* lockfile should be made by this process */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   246
		unlink(opts->lockfile);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   247
	if (WIFEXITED(pst)) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   248
		abortmsg("cmdserver exited with status %d", WEXITSTATUS(pst));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   249
	} else if (WIFSIGNALED(pst)) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   250
		abortmsg("cmdserver killed by signal %d", WTERMSIG(pst));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   251
	} else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   252
		abortmsg("error white waiting cmdserver");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   253
	}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   254
}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   255
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   256
/* Spawn new background cmdserver */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   257
static void startcmdserver(const struct cmdserveropts *opts)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   258
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   259
	debugmsg("start cmdserver at %s", opts->sockname);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   260
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   261
	if (lockcmdserver(opts) < 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   262
		debugmsg("lock file exists, waiting...");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   263
		waitcmdserver(opts, 0);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   264
		return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   265
	}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   266
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   267
	/* remove dead cmdserver socket if any */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   268
	unlink(opts->sockname);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   269
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   270
	pid_t pid = fork();
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   271
	if (pid < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   272
		abortmsg("failed to fork cmdserver process");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   273
	if (pid == 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   274
		/* bypass uisetup() of pager extension */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   275
		int nullfd = open("/dev/null", O_WRONLY);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   276
		if (nullfd >= 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   277
			dup2(nullfd, fileno(stdout));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   278
			close(nullfd);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   279
		}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   280
		execcmdserver(opts);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   281
	} else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   282
		waitcmdserver(opts, pid);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   283
	}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   284
}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   285
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   286
static void killcmdserver(const struct cmdserveropts *opts, int sig)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   287
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   288
	FILE *fp = fopen(opts->pidfile, "r");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   289
	if (!fp)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   290
		abortmsg("cannot open %s (errno = %d)", opts->pidfile, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   291
	int pid = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   292
	int n = fscanf(fp, "%d", &pid);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   293
	fclose(fp);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   294
	if (n != 1 || pid <= 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   295
		abortmsg("cannot read pid from %s", opts->pidfile);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   296
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   297
	if (kill((pid_t)pid, sig) < 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   298
		if (errno == ESRCH)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   299
			return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   300
		abortmsg("cannot kill %d (errno = %d)", pid, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   301
	}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   302
}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   303
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   304
static pid_t peerpid = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   305
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   306
static void forwardsignal(int sig)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   307
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   308
	assert(peerpid > 0);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   309
	if (kill(peerpid, sig) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   310
		abortmsg("cannot kill %d (errno = %d)", peerpid, errno);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   311
	debugmsg("forward signal %d", sig);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   312
}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   313
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   314
static void handlestopsignal(int sig)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   315
{
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   316
	sigset_t unblockset, oldset;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   317
	struct sigaction sa, oldsa;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   318
	if (sigemptyset(&unblockset) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   319
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   320
	if (sigaddset(&unblockset, sig) < 0)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   321
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   322
	memset(&sa, 0, sizeof(sa));
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   323
	sa.sa_handler = SIG_DFL;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   324
	sa.sa_flags = SA_RESTART;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   325
	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
   326
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   327
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   328
	forwardsignal(sig);
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   329
	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
   330
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   331
	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
   332
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   333
	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
   334
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   335
	/* 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
   336
	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
   337
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   338
	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
   339
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   340
	return;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   341
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   342
error:
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   343
	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
   344
}
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   345
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   346
static void setupsignalhandler(pid_t pid)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   347
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   348
	if (pid <= 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   349
		return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   350
	peerpid = pid;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   351
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   352
	struct sigaction sa;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   353
	memset(&sa, 0, sizeof(sa));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   354
	sa.sa_handler = forwardsignal;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   355
	sa.sa_flags = SA_RESTART;
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   356
	if (sigemptyset(&sa.sa_mask) < 0)
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   357
		goto error;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   358
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   359
	if (sigaction(SIGHUP, &sa, NULL) < 0)
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   360
		goto error;
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   361
	if (sigaction(SIGINT, &sa, NULL) < 0)
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   362
		goto error;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   363
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   364
	/* terminate frontend by double SIGTERM in case of server freeze */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   365
	sa.sa_flags |= SA_RESETHAND;
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   366
	if (sigaction(SIGTERM, &sa, NULL) < 0)
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   367
		goto error;
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   368
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   369
	/* 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
   370
	sa.sa_handler = forwardsignal;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   371
	sa.sa_flags = SA_RESTART;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   372
	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
   373
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   374
	sa.sa_handler = handlestopsignal;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   375
	sa.sa_flags = SA_RESTART;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   376
	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
   377
		goto error;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
   378
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   379
	return;
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   380
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   381
error:
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
   382
	abortmsg("failed to set up signal handlers (errno = %d)", errno);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   383
}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   384
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   385
/* This implementation is based on hgext/pager.py (pre 369741ef7253) */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   386
static void setuppager(hgclient_t *hgc, const char *const args[],
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   387
		       size_t argsize)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   388
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   389
	const char *pagercmd = hgc_getpager(hgc, args, argsize);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   390
	if (!pagercmd)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   391
		return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   392
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   393
	int pipefds[2];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   394
	if (pipe(pipefds) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   395
		return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   396
	pid_t pid = fork();
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   397
	if (pid < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   398
		goto error;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   399
	if (pid == 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   400
		close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   401
		if (dup2(pipefds[1], fileno(stdout)) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   402
			goto error;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   403
		if (isatty(fileno(stderr))) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   404
			if (dup2(pipefds[1], fileno(stderr)) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   405
				goto error;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   406
		}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   407
		close(pipefds[1]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   408
		hgc_attachio(hgc);  /* reattach to pager */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   409
		return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   410
	} else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   411
		dup2(pipefds[0], fileno(stdin));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   412
		close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   413
		close(pipefds[1]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   414
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   415
		int r = execlp("/bin/sh", "/bin/sh", "-c", pagercmd, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   416
		if (r < 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   417
			abortmsg("cannot start pager '%s' (errno = %d)",
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   418
				 pagercmd, errno);
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
		return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   421
	}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   422
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   423
error:
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   424
	close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   425
	close(pipefds[1]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   426
	abortmsg("failed to prepare pager (errno = %d)", errno);
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   429
int main(int argc, const char *argv[], const char *envp[])
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   430
{
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   431
	if (getenv("CHGDEBUG"))
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   432
		enabledebugmsg();
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   433
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   434
	struct cmdserveropts opts;
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   435
	initcmdserveropts(&opts);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   436
	setcmdserveropts(&opts);
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   437
	setcmdserverargs(&opts, argc, argv);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   438
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   439
	if (argc == 2) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   440
		int sig = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   441
		if (strcmp(argv[1], "--kill-chg-daemon") == 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   442
			sig = SIGTERM;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   443
		if (strcmp(argv[1], "--reload-chg-daemon") == 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   444
			sig = SIGHUP;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   445
		if (sig > 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   446
			killcmdserver(&opts, sig);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   447
			return 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   448
		}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   449
	}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   450
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   451
	hgclient_t *hgc = hgc_open(opts.sockname);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   452
	if (!hgc) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   453
		startcmdserver(&opts);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   454
		hgc = hgc_open(opts.sockname);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   455
	}
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   456
	if (!hgc)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   457
		abortmsg("cannot open hg client");
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   458
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   459
	setupsignalhandler(hgc_peerpid(hgc));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   460
	hgc_setenv(hgc, envp);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   461
	setuppager(hgc, argv + 1, argc - 1);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   462
	int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   463
	hgc_close(hgc);
28167
66f6dad20c19 chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents: 28086
diff changeset
   464
	freecmdserveropts(&opts);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   465
	return exitcode;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   466
}