@@ -33,24 +33,22 @@ int is_directory(const char *path)
3333 */
3434static const char * real_path_internal (const char * path , int die_on_error )
3535{
36- static char bufs [ 2 ][ PATH_MAX + 1 ], * buf = bufs [ 0 ], * next_buf = bufs [ 1 ] ;
36+ static struct strbuf sb = STRBUF_INIT ;
3737 char * retval = NULL ;
3838
3939 /*
4040 * If we have to temporarily chdir(), store the original CWD
4141 * here so that we can chdir() back to it at the end of the
4242 * function:
4343 */
44- char cwd [1024 ] = "" ;
45-
46- int buf_index = 1 ;
44+ struct strbuf cwd = STRBUF_INIT ;
4745
4846 int depth = MAXDEPTH ;
4947 char * last_elem = NULL ;
5048 struct stat st ;
5149
5250 /* We've already done it */
53- if (path == buf || path == next_buf )
51+ if (path == sb . buf )
5452 return path ;
5553
5654 if (!* path ) {
@@ -60,90 +58,74 @@ static const char *real_path_internal(const char *path, int die_on_error)
6058 goto error_out ;
6159 }
6260
63- if (strlcpy (buf , path , PATH_MAX ) >= PATH_MAX ) {
64- if (die_on_error )
65- die ("Too long path: %.*s" , 60 , path );
66- else
67- goto error_out ;
68- }
61+ strbuf_reset (& sb );
62+ strbuf_addstr (& sb , path );
6963
7064 while (depth -- ) {
71- if (!is_directory (buf )) {
72- char * last_slash = find_last_dir_sep (buf );
65+ if (!is_directory (sb . buf )) {
66+ char * last_slash = find_last_dir_sep (sb . buf );
7367 if (last_slash ) {
7468 last_elem = xstrdup (last_slash + 1 );
75- last_slash [ 1 ] = '\0' ;
69+ strbuf_setlen ( & sb , last_slash - sb . buf + 1 ) ;
7670 } else {
77- last_elem = xstrdup ( buf );
78- * buf = '\0' ;
71+ last_elem = xmemdupz ( sb . buf , sb . len );
72+ strbuf_reset ( & sb ) ;
7973 }
8074 }
8175
82- if (* buf ) {
83- if (!* cwd && ! getcwd ( cwd , sizeof ( cwd ) )) {
76+ if (sb . len ) {
77+ if (!cwd . len && strbuf_getcwd ( & cwd )) {
8478 if (die_on_error )
8579 die_errno ("Could not get current working directory" );
8680 else
8781 goto error_out ;
8882 }
8983
90- if (chdir (buf )) {
84+ if (chdir (sb . buf )) {
9185 if (die_on_error )
92- die_errno ("Could not switch to '%s'" , buf );
86+ die_errno ("Could not switch to '%s'" ,
87+ sb .buf );
9388 else
9489 goto error_out ;
9590 }
9691 }
97- if (! getcwd ( buf , PATH_MAX )) {
92+ if (strbuf_getcwd ( & sb )) {
9893 if (die_on_error )
9994 die_errno ("Could not get current working directory" );
10095 else
10196 goto error_out ;
10297 }
10398
10499 if (last_elem ) {
105- size_t len = strlen (buf );
106- if (len + strlen (last_elem ) + 2 > PATH_MAX ) {
107- if (die_on_error )
108- die ("Too long path name: '%s/%s'" ,
109- buf , last_elem );
110- else
111- goto error_out ;
112- }
113- if (len && !is_dir_sep (buf [len - 1 ]))
114- buf [len ++ ] = '/' ;
115- strcpy (buf + len , last_elem );
100+ if (sb .len && !is_dir_sep (sb .buf [sb .len - 1 ]))
101+ strbuf_addch (& sb , '/' );
102+ strbuf_addstr (& sb , last_elem );
116103 free (last_elem );
117104 last_elem = NULL ;
118105 }
119106
120- if (!lstat (buf , & st ) && S_ISLNK (st .st_mode )) {
121- ssize_t len = readlink (buf , next_buf , PATH_MAX );
107+ if (!lstat (sb .buf , & st ) && S_ISLNK (st .st_mode )) {
108+ struct strbuf next_sb = STRBUF_INIT ;
109+ ssize_t len = strbuf_readlink (& next_sb , sb .buf , 0 );
122110 if (len < 0 ) {
123111 if (die_on_error )
124- die_errno ("Invalid symlink '%s'" , buf );
125- else
126- goto error_out ;
127- }
128- if (PATH_MAX <= len ) {
129- if (die_on_error )
130- die ("symbolic link too long: %s" , buf );
112+ die_errno ("Invalid symlink '%s'" ,
113+ sb .buf );
131114 else
132115 goto error_out ;
133116 }
134- next_buf [len ] = '\0' ;
135- buf = next_buf ;
136- buf_index = 1 - buf_index ;
137- next_buf = bufs [buf_index ];
117+ strbuf_swap (& sb , & next_sb );
118+ strbuf_release (& next_sb );
138119 } else
139120 break ;
140121 }
141122
142- retval = buf ;
123+ retval = sb . buf ;
143124error_out :
144125 free (last_elem );
145- if (* cwd && chdir (cwd ))
146- die_errno ("Could not change back to '%s'" , cwd );
126+ if (cwd .len && chdir (cwd .buf ))
127+ die_errno ("Could not change back to '%s'" , cwd .buf );
128+ strbuf_release (& cwd );
147129
148130 return retval ;
149131}
@@ -158,54 +140,16 @@ const char *real_path_if_valid(const char *path)
158140 return real_path_internal (path , 0 );
159141}
160142
161- static const char * get_pwd_cwd (void )
162- {
163- static char cwd [PATH_MAX + 1 ];
164- char * pwd ;
165- struct stat cwd_stat , pwd_stat ;
166- if (getcwd (cwd , PATH_MAX ) == NULL )
167- return NULL ;
168- pwd = getenv ("PWD" );
169- if (pwd && strcmp (pwd , cwd )) {
170- stat (cwd , & cwd_stat );
171- if ((cwd_stat .st_dev || cwd_stat .st_ino ) &&
172- !stat (pwd , & pwd_stat ) &&
173- pwd_stat .st_dev == cwd_stat .st_dev &&
174- pwd_stat .st_ino == cwd_stat .st_ino ) {
175- strlcpy (cwd , pwd , PATH_MAX );
176- }
177- }
178- return cwd ;
179- }
180-
181143/*
182144 * Use this to get an absolute path from a relative one. If you want
183145 * to resolve links, you should use real_path.
184- *
185- * If the path is already absolute, then return path. As the user is
186- * never meant to free the return value, we're safe.
187146 */
188147const char * absolute_path (const char * path )
189148{
190- static char buf [PATH_MAX + 1 ];
191-
192- if (!* path ) {
193- die ("The empty string is not a valid path" );
194- } else if (is_absolute_path (path )) {
195- if (strlcpy (buf , path , PATH_MAX ) >= PATH_MAX )
196- die ("Too long path: %.*s" , 60 , path );
197- } else {
198- size_t len ;
199- const char * fmt ;
200- const char * cwd = get_pwd_cwd ();
201- if (!cwd )
202- die_errno ("Cannot determine the current working directory" );
203- len = strlen (cwd );
204- fmt = (len > 0 && is_dir_sep (cwd [len - 1 ])) ? "%s%s" : "%s/%s" ;
205- if (snprintf (buf , PATH_MAX , fmt , cwd , path ) >= PATH_MAX )
206- die ("Too long path: %.*s" , 60 , path );
207- }
208- return buf ;
149+ static struct strbuf sb = STRBUF_INIT ;
150+ strbuf_reset (& sb );
151+ strbuf_add_absolute_path (& sb , path );
152+ return sb .buf ;
209153}
210154
211155/*
0 commit comments