#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
char * rpath_to_apath(const char * rpath, char * buf, int buf_size);
int main(int argc, char * argv[])
{
char * rpath = NULL;
char * apath = NULL;
if((argc == 2 && strcmp(argv[1], "--help") == 0)
|| argc > 2)
{
printf("Usage: %s <relative_path>\n", argv[0]);
return EXIT_SUCCESS;
}
if(argc == 1)
rpath = "./";
else
rpath = argv[1];
if(rpath[0] == '/')
{
fprintf(stderr, "path must be relative path!\n");
return EXIT_FAILURE;
}
printf("relative path: %s\n", rpath);
if((apath = malloc(PATH_MAX)) == NULL)
{
perror("malloc");
return EXIT_FAILURE;
}
memset(apath, 0, PATH_MAX);
printf("absolute path: %s\n", rpath_to_apath(rpath, apath, PATH_MAX));
free(apath);
return EXIT_SUCCESS;
}
char * rpath_to_apath(const char * rpath, char * buf, int buf_size)
{
char cur_work_dir[PATH_MAX] = {0};
int index = 0;
const char * p = rpath;
while(*p == '.')
p++;
if(*p == '/')
p++;
if(getcwd(cur_work_dir, PATH_MAX) == NULL)
{
perror("getcwd");
return NULL;
}
index = strlen(strncpy(buf, cur_work_dir, buf_size - 1));
if(*p)
{
buf[index] = '/';
strncpy(buf + index + 1, p,
MIN(strlen(p), (buf_size - 1) - (index + 1)));
}
return buf;
}
这段代码仅仅是实现相对路径和绝对路径之间的转换,但其中存在一个BUG:代码严重依赖于当前工作目录。
正确的做法是调用系统调用realpath()
:
#include <stdlib.h>
char * realpath(const char * pathname, char * resolved_path);