/* * Connect to watchman's socket. Sets a socket send and receive * timeout of `timeout`. Pass a {0} for no-timeout. On error, * returns NULL and, if `error` is non-NULL, fills it in. */ struct watchman_connection * watchman_connect(struct timeval timeout, struct watchman_error *error) { struct watchman_connection *conn = NULL; /* If an environment variable WATCHMAN_SOCK is set, establish a connection to that address. Otherwise, run `watchman get-sockname` to start the daemon and retrieve its address. */ const char *sockname_env = getenv("WATCHMAN_SOCK"); if (sockname_env) { conn = watchman_sock_connect(sockname_env, timeout, error); goto done; } struct watchman_popen *p = watchman_popen_getsockname(error); if (p == NULL) { return NULL; } char buf[WATCHMAN_GET_SOCKNAME_MAX + 1]; proto_t proto = read_with_timeout(p->fd, buf, WATCHMAN_GET_SOCKNAME_MAX, timeout); if (watchman_pclose(error, p)) { goto done; } if (proto_is_null(proto)) { watchman_err(error, WATCHMAN_ERR_WATCHMAN_BROKEN, "Got bad or no JSON/BSER from watchman get-sockname"); goto done; } if (!proto_is_object(proto)) { watchman_err(error, WATCHMAN_ERR_WATCHMAN_BROKEN, "Got bad JSON/BSER from watchman get-sockname: object expected"); goto bad_proto; } proto_t sockname_obj = proto_object_get(proto, "sockname"); if (proto_is_null(sockname_obj)) { watchman_err(error, WATCHMAN_ERR_WATCHMAN_BROKEN, "Got bad JSON/BSER from watchman get-sockname: " "sockname element expected"); goto bad_proto; } if (!proto_is_string(sockname_obj)) { watchman_err(error, WATCHMAN_ERR_WATCHMAN_BROKEN, "Got bad JSON/BSER from watchman get-sockname:" " sockname is not string"); goto bad_proto; } const char *sockname = proto_strdup(sockname_obj); conn = watchman_sock_connect(sockname, timeout, error); bad_proto: proto_free(proto); done: return conn; }
/* * Connect to watchman's socket. Sets a socket send and receive * timeout of `timeout`. Pass a {0} for no-timeout. On error, * returns NULL and, if `error` is non-NULL, fills it in. */ struct watchman_connection * watchman_connect(struct timeval timeout, struct watchman_error *error) { struct watchman_connection *conn = NULL; /* If an environment variable WATCHMAN_SOCK is set, establish a connection to that address. Otherwise, run `watchman get-sockname` to start the daemon and retrieve its address. */ const char *sockname_env = getenv("WATCHMAN_SOCK"); if (sockname_env) { conn = watchman_sock_connect(sockname_env, timeout, error); goto done; } struct watchman_popen *p = watchman_popen_getsockname(error); if (p == NULL) { return NULL; } char buf[WATCHMAN_GET_SOCKNAME_MAX + 1]; json_t *json = read_json_with_timeout(p->fd, buf, WATCHMAN_GET_SOCKNAME_MAX, timeout); if (watchman_pclose(error, p)) { goto done; } if (!json) { watchman_err(error, WATCHMAN_ERR_WATCHMAN_BROKEN, "Got bad or no JSON from watchman get-sockname"); goto done; } if (!json_is_object(json)) { watchman_err(error, WATCHMAN_ERR_WATCHMAN_BROKEN, "Got bad JSON from watchman get-sockname: object expected"); goto bad_json; } json_t *sockname_obj = json_object_get(json, "sockname"); if (!sockname_obj) { watchman_err(error, WATCHMAN_ERR_WATCHMAN_BROKEN, "Got bad JSON from watchman get-sockname: " "sockname element expected"); goto bad_json; } if (!json_is_string(sockname_obj)) { watchman_err(error, WATCHMAN_ERR_WATCHMAN_BROKEN, "Got bad JSON from watchman get-sockname:" " sockname is not string"); goto bad_json; } const char *sockname = json_string_value(sockname_obj); conn = watchman_sock_connect(sockname, timeout, error); bad_json: json_decref(json); done: return conn; }