Search code examples
cposix

Concatenate path and basename


basename(3) and dirname(3) can split an absolute path into its respective components.

Short of using snprintf(3), is there a natural posix-compliant library call that does the inverse - takes a directory and a filename and concatenates them?

Manually concatenation works fine for me, but can get a little tedious at times.


Solution

  • as far I know there is no such function in POSIX. However in the GNU libc manual there is a nice helper function:

    char *concat (const char *str, ...)
      {
       va_list ap;
       size_t allocated = 100;
       char *result = (char *) malloc (allocated);
    
       if (result != NULL)
         {
           char *newp;
           char *wp;
    
           va_start (ap, str);
    
           wp = result;
           for (s = str; s != NULL; s = va_arg (ap, const char *))
             {
               size_t len = strlen (s);
    
               /* Resize the allocated memory if necessary.  */
               if (wp + len + 1 > result + allocated)
                 {
                   allocated = (allocated + len) * 2;
                   newp = (char *) realloc (result, allocated);
                   if (newp == NULL)
                     {
                       free (result);
                       return NULL;
                     }
                   wp = newp + (wp - result);
                   result = newp;
                 }
    
               wp = mempcpy (wp, s, len);
             }
    
           /* Terminate the result string.  */
           *wp++ = '\0';
    
           /* Resize memory to the optimal size.  */
           newp = realloc (result, wp - result);
           if (newp != NULL)
             result = newp;
    
           va_end (ap);
         }
    
       return result;
     }
    

    usage:

    const char *path = concat(directory, "/", file);