Removed issue around zero length returns now being valid. Fixed memory leak
[awesomized/libmemcached] / libmemcached / memcached_storage.c
1 /*
2 Memcached library
3
4 memcached_set()
5 memcached_replace()
6 memcached_add()
7
8 */
9
10 #include "common.h"
11
12 /* Inline this */
13 static char *storage_op_string(memcached_storage_action verb)
14 {
15 switch (verb)
16 {
17 case SET_OP:
18 return "set";
19 case REPLACE_OP:
20 return "replace";
21 case ADD_OP:
22 return "add";
23 case PREPEND_OP:
24 return "prepend";
25 case APPEND_OP:
26 return "append";
27 case CAS_OP:
28 return "cas";
29 };
30
31 return SET_OP;
32 }
33
34 memcached_return memcached_send(memcached_st *ptr,
35 char *master_key, size_t master_key_length,
36 char *key, size_t key_length,
37 char *value, size_t value_length,
38 time_t expiration,
39 uint32_t flags,
40 uint64_t cas,
41 memcached_storage_action verb)
42 {
43 char to_write;
44 size_t write_length;
45 ssize_t sent_length;
46 memcached_return rc;
47 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
48 unsigned int server_key;
49
50 unlikely (key_length == 0)
51 return MEMCACHED_NO_KEY_PROVIDED;
52
53 unlikely (ptr->number_of_hosts == 0)
54 return MEMCACHED_NO_SERVERS;
55
56 if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
57 return MEMCACHED_BAD_KEY_PROVIDED;
58
59 server_key= memcached_generate_hash(ptr, master_key, master_key_length);
60
61 if (cas)
62 write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
63 "%s %.*s %u %llu %zu %llu\r\n", storage_op_string(verb),
64 (int)key_length, key, flags,
65 (unsigned long long)expiration, value_length,
66 (unsigned long long)cas);
67 else
68 write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
69 "%s %.*s %u %llu %zu\r\n", storage_op_string(verb),
70 (int)key_length, key, flags,
71 (unsigned long long)expiration, value_length);
72
73 if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
74 {
75 rc= MEMCACHED_WRITE_FAILURE;
76 goto error;
77 }
78
79 rc= memcached_do(&ptr->hosts[server_key], buffer, write_length, 0);
80 if (rc != MEMCACHED_SUCCESS)
81 goto error;
82
83 if ((sent_length= memcached_io_write(&ptr->hosts[server_key], value, value_length, 0)) == -1)
84 {
85 rc= MEMCACHED_WRITE_FAILURE;
86 goto error;
87 }
88
89 if ((ptr->flags & MEM_BUFFER_REQUESTS) && verb == SET_OP)
90 to_write= 0;
91 else
92 to_write= 1;
93
94 if ((sent_length= memcached_io_write(&ptr->hosts[server_key], "\r\n", 2, to_write)) == -1)
95 {
96 rc= MEMCACHED_WRITE_FAILURE;
97 goto error;
98 }
99
100 if (to_write == 0)
101 return MEMCACHED_BUFFERED;
102
103 rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
104
105 if (rc == MEMCACHED_STORED)
106 return MEMCACHED_SUCCESS;
107 else
108 return rc;
109
110 error:
111 memcached_io_reset(&ptr->hosts[server_key]);
112
113 return rc;
114 }