Standardize the snprintf() failure messages, and add tests for libmemcached_util_getpid()
[awesomized/libmemcached] / libmemcached / flush.cc
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Libmemcached library
4 *
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * * The names of its contributors may not be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 */
36
37 #include <libmemcached/common.h>
38
39 static memcached_return_t memcached_flush_binary(memcached_st *ptr,
40 time_t expiration);
41 static memcached_return_t memcached_flush_textual(memcached_st *ptr,
42 time_t expiration);
43
44 memcached_return_t memcached_flush(memcached_st *ptr, time_t expiration)
45 {
46 memcached_return_t rc;
47 if (memcached_failed(rc= initialize_query(ptr)))
48 {
49 return rc;
50 }
51
52 LIBMEMCACHED_MEMCACHED_FLUSH_START();
53 if (ptr->flags.binary_protocol)
54 rc= memcached_flush_binary(ptr, expiration);
55 else
56 rc= memcached_flush_textual(ptr, expiration);
57 LIBMEMCACHED_MEMCACHED_FLUSH_END();
58 return rc;
59 }
60
61 static memcached_return_t memcached_flush_textual(memcached_st *ptr,
62 time_t expiration)
63 {
64 unlikely (memcached_server_count(ptr) == 0)
65 return MEMCACHED_NO_SERVERS;
66
67 for (unsigned int x= 0; x < memcached_server_count(ptr); x++)
68 {
69 memcached_return_t rc;
70 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
71
72 bool no_reply= ptr->flags.no_reply;
73 memcached_server_write_instance_st instance=
74 memcached_server_instance_fetch(ptr, x);
75
76 int send_length;
77 if (expiration)
78 {
79 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
80 "flush_all %llu%s\r\n",
81 (unsigned long long)expiration, no_reply ? " noreply" : "");
82 }
83 else
84 {
85 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
86 "flush_all%s\r\n", no_reply ? " noreply" : "");
87 }
88
89 if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
90 {
91 return memcached_set_error(*instance, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
92 memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)"));
93 }
94
95 rc= memcached_do(instance, buffer, (size_t)send_length, true);
96
97 if (rc == MEMCACHED_SUCCESS && !no_reply)
98 (void)memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
99 }
100
101 return MEMCACHED_SUCCESS;
102 }
103
104 static memcached_return_t memcached_flush_binary(memcached_st *ptr,
105 time_t expiration)
106 {
107 protocol_binary_request_flush request= {};
108
109 unlikely (memcached_server_count(ptr) == 0)
110 return MEMCACHED_NO_SERVERS;
111
112 request.message.header.request.magic= (uint8_t)PROTOCOL_BINARY_REQ;
113 request.message.header.request.opcode= PROTOCOL_BINARY_CMD_FLUSH;
114 request.message.header.request.extlen= 4;
115 request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
116 request.message.header.request.bodylen= htonl(request.message.header.request.extlen);
117 request.message.body.expiration= htonl((uint32_t) expiration);
118
119 for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
120 {
121 memcached_server_write_instance_st instance=
122 memcached_server_instance_fetch(ptr, x);
123
124 if (ptr->flags.no_reply)
125 {
126 request.message.header.request.opcode= PROTOCOL_BINARY_CMD_FLUSHQ;
127 }
128 else
129 {
130 request.message.header.request.opcode= PROTOCOL_BINARY_CMD_FLUSH;
131 }
132
133 if (memcached_do(instance, request.bytes, sizeof(request.bytes), true) != MEMCACHED_SUCCESS)
134 {
135 memcached_io_reset(instance);
136 return MEMCACHED_WRITE_FAILURE;
137 }
138 }
139
140 for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
141 {
142 memcached_server_write_instance_st instance=
143 memcached_server_instance_fetch(ptr, x);
144
145 if (memcached_server_response_count(instance) > 0)
146 (void)memcached_response(instance, NULL, 0, NULL);
147 }
148
149 return MEMCACHED_SUCCESS;
150 }