}
int readlinkat_malloc(int fd, const char *p, char **ret) {
- size_t l = FILENAME_MAX+1;
- int r;
+ size_t l = PATH_MAX;
assert(p);
assert(ret);
for (;;) {
- char *c;
+ _cleanup_free_ char *c = NULL;
ssize_t n;
- c = new(char, l);
+ c = new(char, l+1);
if (!c)
return -ENOMEM;
- n = readlinkat(fd, p, c, l-1);
- if (n < 0) {
- r = -errno;
- free(c);
- return r;
- }
+ n = readlinkat(fd, p, c, l);
+ if (n < 0)
+ return -errno;
- if ((size_t) n < l-1) {
+ if ((size_t) n < l) {
c[n] = 0;
- *ret = c;
+ *ret = TAKE_PTR(c);
return 0;
}
- free(c);
+ if (l > (SSIZE_MAX-1)/2) /* readlinkat() returns an ssize_t, and we want an extra byte for a
+ * trailing NUL, hence do an overflow check relative to SSIZE_MAX-1
+ * here */
+ return -EFBIG;
+
l *= 2;
}
}