Skip to content

Commit

Permalink
Fix problem where watch implicitly created.
Browse files Browse the repository at this point in the history
Summary:
A user that runs the following commands will implicitly create a watch:
- state-enter
- state-leave
- subscribe
- trigger
- watch
This change will limit the watch creation to the watch command (explicit).
This will make behaviors more intuitive and prevent future issues.
We separate commands for the resolve_root and resolve_root_create - as a defensive measure.

Reviewed By: wez

Differential Revision: D5829679

fbshipit-source-id: 06995044b48fdadde02dece1624322a6e8b160bc
  • Loading branch information
eamonnkent authored and facebook-github-bot committed Sep 15, 2017
1 parent 02934e4 commit e02729e
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 32 deletions.
2 changes: 1 addition & 1 deletion InMemoryView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ void InMemoryView::debugContentHashCache(
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto view = std::dynamic_pointer_cast<watchman::InMemoryView>(root->view());
if (!view) {
Expand Down
10 changes: 5 additions & 5 deletions cmds/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ static void cmd_debug_recrawl(
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto resp = make_response();

Expand All @@ -36,7 +36,7 @@ static void cmd_debug_show_cursors(
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto resp = make_response();

Expand Down Expand Up @@ -69,7 +69,7 @@ static void cmd_debug_ageout(
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

std::chrono::seconds min_age(json_integer_value(json_array_get(args, 2)));

Expand All @@ -87,7 +87,7 @@ static void cmd_debug_poison(
const json_ref& args) {
struct timeval now;

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

gettimeofday(&now, NULL);

Expand Down Expand Up @@ -166,7 +166,7 @@ static void cmd_debug_get_subscriptions(
const json_ref& args) {
auto client = (watchman_user_client*)clientbase;

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto resp = make_response();
auto debug_info = root->unilateralResponses->getDebugInfo();
Expand Down
2 changes: 1 addition & 1 deletion cmds/find.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ static void cmd_find(struct watchman_client* client, const json_ref& args) {
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto query = w_query_parse_legacy(root, args, 2, nullptr, nullptr, nullptr);
if (client->client_mode) {
Expand Down
2 changes: 1 addition & 1 deletion cmds/info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ static void cmd_get_config(
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto resp = make_response();

Expand Down
2 changes: 1 addition & 1 deletion cmds/query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ static void cmd_query(struct watchman_client* client, const json_ref& args) {
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

const auto& query_spec = args.at(2);
auto query = w_query_parse(root, query_spec);
Expand Down
2 changes: 1 addition & 1 deletion cmds/since.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ static void cmd_since(struct watchman_client* client, const json_ref& args) {
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto clock_ele = json_array_get(args, 2);
clockspec = json_string_value(clock_ele);
Expand Down
4 changes: 2 additions & 2 deletions cmds/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static void cmd_state_enter(
json_ref response;
auto client = dynamic_cast<watchman_user_client*>(clientbase);

auto root = resolve_root(client, args, 1, true);
auto root = resolveRoot(client, args);

if (!parse_state_arg(client, args, &parsed)) {
return;
Expand Down Expand Up @@ -195,7 +195,7 @@ static void cmd_state_leave(
auto client = dynamic_cast<watchman_user_client*>(clientbase);
json_ref response;

auto root = resolve_root(client, args, 1, true);
auto root = resolveRoot(client, args);

if (!parse_state_arg(client, args, &parsed)) {
return;
Expand Down
6 changes: 3 additions & 3 deletions cmds/subscribe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ static void cmd_flush_subscriptions(
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

std::vector<w_string> subs_to_sync;
if (subs) {
Expand Down Expand Up @@ -395,7 +395,7 @@ static void cmd_unsubscribe(
struct watchman_user_client* client =
(struct watchman_user_client*)clientbase;

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto jstr = json_array_get(args, 2);
name = json_string_value(jstr);
Expand Down Expand Up @@ -442,7 +442,7 @@ static void cmd_subscribe(
return;
}

auto root = resolve_root(client, args, 1, true);
auto root = resolveRoot(client, args);

jname = args.at(2);
if (!json_is_string(jname)) {
Expand Down
6 changes: 3 additions & 3 deletions cmds/trigger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static void cmd_trigger_delete(
w_string tname;
bool res;

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

if (json_array_size(args) != 3) {
send_error_response(client, "wrong number of arguments");
Expand Down Expand Up @@ -123,7 +123,7 @@ W_CMD_REG("trigger-del", cmd_trigger_delete, CMD_DAEMON, w_cmd_realpath_root)
static void cmd_trigger_list(
struct watchman_client* client,
const json_ref& args) {
auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto resp = make_response();
auto arr = root->triggerListToJson();
Expand Down Expand Up @@ -352,7 +352,7 @@ static void cmd_trigger(struct watchman_client* client, const json_ref& args) {
json_ref trig;
json_ref resp;

auto root = resolve_root(client, args, 1, true);
auto root = resolveRoot(client, args);

if (json_array_size(args) < 3) {
send_error_response(client, "not enough arguments");
Expand Down
8 changes: 4 additions & 4 deletions cmds/watch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static void cmd_clock(struct watchman_client* client, const json_ref& args) {
}

/* resolve the root */
auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

if (sync_timeout &&
!root->syncToNow(std::chrono::milliseconds(sync_timeout))) {
Expand Down Expand Up @@ -83,7 +83,7 @@ static void cmd_watch_delete(
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto resp = make_response();
resp.set({{"watch-del", json_boolean(root->stopWatch())},
Expand Down Expand Up @@ -233,7 +233,7 @@ static void cmd_watch(struct watchman_client* client, const json_ref& args) {
return;
}

auto root = resolve_root(client, args, 1, true);
auto root = resolveOrCreateRoot(client, args);
root->view()->waitUntilReadyToQuery(root).wait();

auto resp = make_response();
Expand Down Expand Up @@ -272,7 +272,7 @@ static void cmd_watch_project(
return;
}

auto root = resolve_root(client, args, 1, true);
auto root = resolveOrCreateRoot(client, args);

root->view()->waitUntilReadyToQuery(root).wait();

Expand Down
18 changes: 15 additions & 3 deletions listener-user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,9 @@ void add_root_warnings_to_response(
"`\n")));
}

std::shared_ptr<w_root_t> resolve_root(
std::shared_ptr<w_root_t> doResolveOrCreateRoot(
struct watchman_client* client,
const json_ref& args,
size_t root_index,
bool create) {
const char *root_name;
char* errmsg = nullptr;
Expand All @@ -51,10 +50,11 @@ std::shared_ptr<w_root_t> resolve_root(
free(errmsg);
};

// Assume root is first element
size_t root_index = 1;
if (args.array().size() <= root_index) {
throw RootResolveError("wrong number of arguments");
}

const auto& ele = args.at(root_index);

root_name = json_string_value(ele);
Expand Down Expand Up @@ -96,6 +96,18 @@ std::shared_ptr<w_root_t> resolve_root(
return root;
}

std::shared_ptr<w_root_t> resolveRoot(
struct watchman_client* client,
const json_ref& args) {
return doResolveOrCreateRoot(client, args, false);
}

std::shared_ptr<w_root_t> resolveOrCreateRoot(
struct watchman_client* client,
const json_ref& args) {
return doResolveOrCreateRoot(client, args, true);
}

watchman_user_client::watchman_user_client(
std::unique_ptr<watchman_stream>&& stm)
: watchman_client(std::move(stm)) {}
Expand Down
2 changes: 1 addition & 1 deletion watcher/fsevents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ static void cmd_debug_fsevents_inject_drop(
return;
}

auto root = resolve_root(client, args, 1, false);
auto root = resolveRoot(client, args);

auto watcher = watcherFromRoot(root);
if (!watcher) {
Expand Down
15 changes: 9 additions & 6 deletions watchman_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,16 @@ bool enqueue_response(
json_ref&& json,
bool ping);

// Resolve the root. If the root cannot be resolved,
// a RootResolveError will be thrown
std::shared_ptr<w_root_t> resolve_root(
// Resolve the root. Failure will throw a RootResolveError exception
std::shared_ptr<w_root_t> resolveRoot(
struct watchman_client* client,
const json_ref& args,
size_t root_index,
bool create);
const json_ref& args);

// Resolve the root, or if not found and the configuration permits,
// attempt to create it. throws RootResolveError on failure.
std::shared_ptr<w_root_t> resolveOrCreateRoot(
struct watchman_client* client,
const json_ref& args);

json_ref make_response(void);
void annotate_with_clock(const std::shared_ptr<w_root_t>& root, json_ref& resp);
Expand Down

0 comments on commit e02729e

Please sign in to comment.