xapian-core  2.0.0
remoteconnection.h
Go to the documentation of this file.
1 
4 /* Copyright (C) 2006,2007,2008,2010,2011,2014,2015,2019,2024 Olly Betts
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see
18  * <https://www.gnu.org/licenses/>.
19  */
20 
21 #ifndef XAPIAN_INCLUDED_REMOTECONNECTION_H
22 #define XAPIAN_INCLUDED_REMOTECONNECTION_H
23 
24 #include <string>
25 
26 #include "remoteprotocol.h"
27 
28 #ifdef __WIN32__
29 # include "safewinsock2.h"
30 #else
31 # include "safesyssocket.h"
32 #endif
33 
43  void operator=(const RemoteConnection &);
44 
47 
53  int fdin;
54 
61  int fdout;
62 
63 #ifndef __WIN32__
64  // On Unix-like platforms we want to avoid generating SIGPIPE when writing
65  // to a socket when the other end has been closed since signals break the
66  // encapsulation of what we're doing inside the library - either user code
67  // would need to handle the SIGPIPE, or we set a signal handler for SIGPIPE
68  // but that would handle *any* SIGPIPE in the process, not just those we
69  // might trigger, and that could break user code which expects to trigger
70  // and handle SIGPIPE.
71  //
72  // We don't need SIGPIPE since we can check errno==EPIPE instead (which is
73  // actually simpler to do).
74  //
75  // We support using SO_NOSIGPIPE (not standardised) or MSG_NOSIGNAL
76  // (specified by POSIX but more awkward to use) which seems to cover all
77  // modern Unix-like platforms. For platforms without either we currently
78  // just set the SIGPIPE signal handler to SIG_IGN.
79 # if defined(SO_NOSIGPIPE) && !defined(__NetBSD__)
80  // Prefer using SO_NOSIGPIPE and write(), except on NetBSD where we seem to
81  // still get SIGPIPE despite using it.
82 # define USE_SO_NOSIGPIPE
83 # elif defined MSG_NOSIGNAL
84  // Use send(..., MSG_NOSIGNAL).
85  int send_flags = MSG_NOSIGNAL;
86 # define USE_MSG_NOSIGNAL
87 # endif
88 #endif
89 
91  std::string buffer;
92 
95 
108  bool read_at_least(size_t min_len, double end_time);
109 
110 #ifdef __WIN32__
117  WSAOVERLAPPED overlapped;
118 
123  DWORD calc_read_wait_msecs(double end_time);
124 #else
126  ssize_t send_or_write(const void* p, size_t n);
127 #endif
128 
129  protected:
134  std::string context;
135 
136  public:
138  RemoteConnection(int fdin_, int fdout_,
139  const std::string & context_ = std::string());
140 
141 #ifdef __WIN32__
143  ~RemoteConnection();
144 #endif
145 
147  int get_read_fd() const { return fdin; }
148 
166  int sniff_next_message_type(double end_time);
167 
178  int get_message(std::string &result, double end_time);
179 
196  int get_message_chunked(double end_time);
197 
218  int get_message_chunk(std::string &result, size_t at_least,
219  double end_time);
220 
232  int receive_file(const std::string &file, double end_time);
233 
243  void send_message(char type, std::string_view s, double end_time);
244 
254  void send_file(char type, int fd, double end_time);
255 
261  void shutdown();
262 
264  void do_close();
265 
267  const std::string& get_context() const { return context; }
268 };
269 
276  public:
278  OwnedRemoteConnection(int fdin_, int fdout_,
279  const std::string& context_ = std::string())
280  : RemoteConnection(fdin_, fdout_, context_) { }
281 
284  do_close();
285  }
286 };
287 
288 #endif // XAPIAN_INCLUDED_REMOTECONNECTION_H
RemoteConnection which owns its own fd(s).
OwnedRemoteConnection(int fdin_, int fdout_, const std::string &context_=std::string())
Constructor.
~OwnedRemoteConnection()
Destructor.
A RemoteConnection object provides a bidirectional connection to another RemoteConnection object on a...
void send_message(char type, std::string_view s, double end_time)
Send a message.
int fdin
The file descriptor used for reading.
std::string buffer
Buffer to hold unprocessed input.
const std::string & get_context() const
Return the context to report with errors.
RemoteConnection(const RemoteConnection &)
Don't allow copying.
int get_message_chunk(std::string &result, size_t at_least, double end_time)
Read a chunk of a message from fdin.
bool read_at_least(size_t min_len, double end_time)
Read until there are at least min_len bytes in buffer.
int fdout
The file descriptor used for writing.
int receive_file(const std::string &file, double end_time)
Save the contents of a message as a file.
off_t chunked_data_left
Remaining bytes of message data still to come over fdin for a chunked read.
void do_close()
Close the connection.
int get_read_fd() const
Return the underlying fd this remote connection reads from.
int get_message(std::string &result, double end_time)
Read one message from fdin.
void shutdown()
Shutdown the connection.
int sniff_next_message_type(double end_time)
Check what the next message type is.
int get_message_chunked(double end_time)
Prepare to read one message from fdin in chunks.
std::string context
The context to report with errors.
ssize_t send_or_write(const void *p, size_t n)
Helper which calls send() or write().
void operator=(const RemoteConnection &)
Don't allow assignment.
void send_file(char type, int fd, double end_time)
Send the contents of a file as a message.
PositionList * p
double end_time(double timeout)
Return the end time for a timeout in timeout seconds.
Definition: realtime.h:95
Remote protocol version and message numbers.
include <sys/socket.h> with portability workarounds.
include <winsock2.h> but working around problems.