return r;
}
+
+int readlink_malloc(const char *p, char **r) {
+ size_t l = 100;
+
+ assert(p);
+ assert(r);
+
+ for (;;) {
+ char *c;
+ ssize_t n;
+
+ if (!(c = new(char, l)))
+ return -ENOMEM;
+
+ if ((n = readlink(p, c, l-1)) < 0) {
+ int ret = -errno;
+ free(c);
+ return ret;
+ }
+
+ if ((size_t) n < l-1) {
+ c[n] = 0;
+ *r = c;
+ return 0;
+ }
+
+ free(c);
+ l *= 2;
+ }
+}
+
+char *file_name_from_path(const char *p) {
+ char *r;
+
+ assert(p);
+
+ if ((r = strrchr(p, '/')))
+ return r + 1;
+
+ return (char*) p;
+}
+
+bool path_is_absolute(const char *p) {
+ assert(p);
+
+ return p[0] == '/';
+}
+
+bool is_path(const char *p) {
+
+ return !!strchr(p, '/');
+}
+
+char *path_make_absolute(const char *p, const char *prefix) {
+ char *r;
+
+ assert(p);
+
+ if (path_is_absolute(p) || !prefix)
+ return strdup(p);
+
+ if (asprintf(&r, "%s/%s", prefix, p) < 0)
+ return NULL;
+
+ return r;
+}