]> git.ipfire.org Git - thirdparty/git.git/blame - fsmonitor-ipc.c
cache.h: remove unnecessary headers
[thirdparty/git.git] / fsmonitor-ipc.c
CommitLineData
d2bd862e
JH
1#include "cache.h"
2#include "fsmonitor.h"
f394e093 3#include "gettext.h"
d2bd862e
JH
4#include "simple-ipc.h"
5#include "fsmonitor-ipc.h"
d1cbe1e6 6#include "repository.h"
d2bd862e
JH
7#include "run-command.h"
8#include "strbuf.h"
9#include "trace2.h"
10
11#ifndef HAVE_FSMONITOR_DAEMON_BACKEND
12
13/*
14 * A trivial implementation of the fsmonitor_ipc__ API for unsupported
15 * platforms.
16 */
17
18int fsmonitor_ipc__is_supported(void)
19{
20 return 0;
21}
22
6beb2688 23const char *fsmonitor_ipc__get_path(struct repository *r)
d2bd862e
JH
24{
25 return NULL;
26}
27
28enum ipc_active_state fsmonitor_ipc__get_state(void)
29{
30 return IPC_STATE__OTHER_ERROR;
31}
32
33int fsmonitor_ipc__send_query(const char *since_token,
34 struct strbuf *answer)
35{
36 return -1;
37}
38
39int fsmonitor_ipc__send_command(const char *command,
40 struct strbuf *answer)
41{
42 return -1;
43}
44
45#else
46
47int fsmonitor_ipc__is_supported(void)
48{
49 return 1;
50}
51
d2bd862e
JH
52enum ipc_active_state fsmonitor_ipc__get_state(void)
53{
6beb2688 54 return ipc_get_active_state(fsmonitor_ipc__get_path(the_repository));
d2bd862e
JH
55}
56
57static int spawn_daemon(void)
58{
d82dbbd8 59 struct child_process cmd = CHILD_PROCESS_INIT;
d2bd862e 60
d82dbbd8
RS
61 cmd.git_cmd = 1;
62 cmd.no_stdin = 1;
63 cmd.trace2_child_class = "fsmonitor";
64 strvec_pushl(&cmd.args, "fsmonitor--daemon", "start", NULL);
65
66 return run_command(&cmd);
d2bd862e
JH
67}
68
69int fsmonitor_ipc__send_query(const char *since_token,
70 struct strbuf *answer)
71{
72 int ret = -1;
73 int tried_to_spawn = 0;
74 enum ipc_active_state state = IPC_STATE__OTHER_ERROR;
75 struct ipc_client_connection *connection = NULL;
76 struct ipc_client_connect_options options
77 = IPC_CLIENT_CONNECT_OPTIONS_INIT;
78 const char *tok = since_token ? since_token : "";
79 size_t tok_len = since_token ? strlen(since_token) : 0;
80
81 options.wait_if_busy = 1;
82 options.wait_if_not_found = 0;
83
84 trace2_region_enter("fsm_client", "query", NULL);
85 trace2_data_string("fsm_client", NULL, "query/command", tok);
86
87try_again:
6beb2688
ED
88 state = ipc_client_try_connect(fsmonitor_ipc__get_path(the_repository),
89 &options, &connection);
d2bd862e
JH
90
91 switch (state) {
92 case IPC_STATE__LISTENING:
93 ret = ipc_client_send_command_to_connection(
94 connection, tok, tok_len, answer);
95 ipc_client_close_connection(connection);
96
97 trace2_data_intmax("fsm_client", NULL,
98 "query/response-length", answer->len);
99 goto done;
100
101 case IPC_STATE__NOT_LISTENING:
102 case IPC_STATE__PATH_NOT_FOUND:
103 if (tried_to_spawn)
104 goto done;
105
106 tried_to_spawn++;
107 if (spawn_daemon())
108 goto done;
109
110 /*
111 * Try again, but this time give the daemon a chance to
112 * actually create the pipe/socket.
113 *
114 * Granted, the daemon just started so it can't possibly have
115 * any FS cached yet, so we'll always get a trivial answer.
116 * BUT the answer should include a new token that can serve
117 * as the basis for subsequent requests.
118 */
119 options.wait_if_not_found = 1;
120 goto try_again;
121
122 case IPC_STATE__INVALID_PATH:
123 ret = error(_("fsmonitor_ipc__send_query: invalid path '%s'"),
6beb2688 124 fsmonitor_ipc__get_path(the_repository));
d2bd862e
JH
125 goto done;
126
127 case IPC_STATE__OTHER_ERROR:
128 default:
129 ret = error(_("fsmonitor_ipc__send_query: unspecified error on '%s'"),
6beb2688 130 fsmonitor_ipc__get_path(the_repository));
d2bd862e
JH
131 goto done;
132 }
133
134done:
135 trace2_region_leave("fsm_client", "query", NULL);
136
137 return ret;
138}
139
140int fsmonitor_ipc__send_command(const char *command,
141 struct strbuf *answer)
142{
143 struct ipc_client_connection *connection = NULL;
144 struct ipc_client_connect_options options
145 = IPC_CLIENT_CONNECT_OPTIONS_INIT;
146 int ret;
147 enum ipc_active_state state;
148 const char *c = command ? command : "";
149 size_t c_len = command ? strlen(command) : 0;
150
151 strbuf_reset(answer);
152
153 options.wait_if_busy = 1;
154 options.wait_if_not_found = 0;
155
6beb2688
ED
156 state = ipc_client_try_connect(fsmonitor_ipc__get_path(the_repository),
157 &options, &connection);
d2bd862e
JH
158 if (state != IPC_STATE__LISTENING) {
159 die(_("fsmonitor--daemon is not running"));
160 return -1;
161 }
162
163 ret = ipc_client_send_command_to_connection(connection, c, c_len,
164 answer);
165 ipc_client_close_connection(connection);
166
167 if (ret == -1) {
168 die(_("could not send '%s' command to fsmonitor--daemon"), c);
169 return -1;
170 }
171
172 return 0;
173}
174
175#endif