@matheusbsbs / matheus-bagliano / commits / 2fc647004a
Fork 0

strbuf: instate cleanup rule in case of non-memory errors

Make all strbuf functions that can fail free() their memory on error if they have allocated it. They don't shrink buffers that have been grown, though. This allows for easier error handling, as callers only need to call strbuf_release() if A) the command succeeded or B) if they would have had to do so anyway because they added something to the strbuf themselves. Bonus hunk: document strbuf_readlink. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Jan 6, 2009 at 21:41 UTC 2fc647004ac7016128372a85db8245581e493812
2 files changed +22 -6
Documentation/technical/api-strbuf.txt
+9 -2
@@ -133,8 +133,10 @@ Functions
133
134 * Adding data to the buffer
135
136 -NOTE: All of these functions in this section will grow the buffer as
137 - necessary.
136 +NOTE: All of the functions in this section will grow the buffer as necessary.
137 +If they fail for some reason other than memory shortage and the buffer hadn't
138 +been allocated before (i.e. the `struct strbuf` was set to `STRBUF_INIT`),
139 +then they will free() it.
140
141 `strbuf_addch`::
142
@@ -235,6 +237,11 @@ same behaviour as well.
237 Read the contents of a file, specified by its path. The third argument
238 can be used to give a hint about the file size, to avoid reallocs.
239
240 +`strbuf_readlink`::
241 +
242 + Read the target of a symbolic link, specified by its path. The third
243 + argument can be used to give a hint about the size, to avoid reallocs.
244 +
245 `strbuf_getline`::
246
247 Read a line from a FILE* pointer. The second argument specifies the line
strbuf.c
+13 -4
@@ -256,18 +256,21 @@ size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder,
256 size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f)
257 {
258 size_t res;
259 + size_t oldalloc = sb->alloc;
260
261 strbuf_grow(sb, size);
262 res = fread(sb->buf + sb->len, 1, size, f);
262 - if (res > 0) {
263 + if (res > 0)
264 strbuf_setlen(sb, sb->len + res);
264 - }
265 + else if (res < 0 && oldalloc == 0)
266 + strbuf_release(sb);
267 return res;
268 }
269
270 ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint)
271 {
272 size_t oldlen = sb->len;
273 + size_t oldalloc = sb->alloc;
274
275 strbuf_grow(sb, hint ? hint : 8192);
276 for (;;) {
@@ -275,7 +278,10 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint)
278
279 cnt = xread(fd, sb->buf + sb->len, sb->alloc - sb->len - 1);
280 if (cnt < 0) {
278 - strbuf_setlen(sb, oldlen);
281 + if (oldalloc == 0)
282 + strbuf_release(sb);
283 + else
284 + strbuf_setlen(sb, oldlen);
285 return -1;
286 }
287 if (!cnt)
@@ -292,6 +298,8 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint)
298
299 int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint)
300 {
301 + size_t oldalloc = sb->alloc;
302 +
303 if (hint < 32)
304 hint = 32;
305
@@ -311,7 +319,8 @@ int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint)
319 /* .. the buffer was too small - try again */
320 hint *= 2;
321 }
314 - strbuf_release(sb);
322 + if (oldalloc == 0)
323 + strbuf_release(sb);
324 return -1;
325 }
326