Move adu_strerror() to adu.c.
[adu.git] / string.c
index 946faabdfd09ce688059c5d8ce15e140af282a29..4775175dcca010ea723fcf2660a6be71fed7a3fe 100644 (file)
--- a/string.c
+++ b/string.c
@@ -123,10 +123,28 @@ __must_check __malloc char *adu_strdup(const char *s)
  */
 __must_check __printf_1_2 __malloc char *make_message(const char *fmt, ...)
 {
-       char *msg;
+       char *p;
+       int n;
+       size_t size = 100;
 
-       VSPRINTF(fmt, msg);
-       return msg;
+       p = adu_malloc(size);
+       while (1) {
+               va_list ap;
+               /* Try to print in the allocated space. */
+               va_start(ap, fmt);
+               n = vsnprintf(p, size, fmt, ap);
+               va_end(ap);
+               /* If that worked, return the string. */
+               if (n > -1 && n < size)
+                       break;
+               /* Else try again with more space. */
+               if (n > -1) /* glibc 2.1 */
+                       size = n + 1; /* precisely what is needed */
+               else /* glibc 2.0 */
+                       size *= 2; /* twice the old size */
+               p = adu_realloc(p, size);
+       }
+       return p;
 }
 
 /**
@@ -209,7 +227,7 @@ __must_check int atoi64(const char *str, int64_t *result)
  *
  * \return The number of substrings found in \a args.
  */
-__must_check unsigned split_args(char *args, char *** const argv_ptr, const char *delim)
+unsigned split_args(char *args, char *** const argv_ptr, const char *delim)
 {
        char *p = args;
        char **argv;
@@ -373,3 +391,35 @@ err:
        free(argv);
        return ret;
 }
+
+char *absolute_path(const char *path)
+{
+       char *cwd, *ap;
+       long int path_max;
+
+       if (!path || !path[0])
+               return NULL;
+       if (path[0] == '/')
+               return adu_strdup(path);
+
+#ifdef PATH_MAX
+       path_max = PATH_MAX;
+#else
+       /*
+        * The result of pathconf(3) may be huge and unsuitable for mallocing
+        * memory. OTOH pathconf(3) may return -1 to signify that PATH_MAX is
+        * not bounded.
+        */
+       path_max = pathconf(name, _PC_PATH_MAX);
+       if (path_max <= 0 || path_max >= 4096)
+               path_max = 4096;
+#endif
+       cwd = adu_malloc(path_max);
+       if (!getcwd(cwd, path_max)) {
+               free(cwd);
+               return NULL;
+       }
+       ap = make_message("%s/%s", cwd, path);
+       free(cwd);
+       return ap;
+}