@@ -55,49 +55,41 @@ static void get_next_component(struct strbuf *next, struct strbuf *remaining)
5555 * Return the real path (i.e., absolute path, with symlinks resolved
5656 * and extra slashes removed) equivalent to the specified path. (If
5757 * you want an absolute path but don't mind links, use
58- * absolute_path().) The return value is a pointer to a static
59- * buffer.
58+ * absolute_path().) Places the resolved realpath in the provided strbuf.
6059 *
6160 * The directory part of path (i.e., everything up to the last
6261 * dir_sep) must denote a valid, existing directory, but the last
6362 * component need not exist. If die_on_error is set, then die with an
6463 * informative error message if there is a problem. Otherwise, return
6564 * NULL on errors (without generating any output).
66- *
67- * If path is our buffer, then return path, as it's already what the
68- * user wants.
6965 */
70- static const char * real_path_internal (const char * path , int die_on_error )
66+ char * strbuf_realpath (struct strbuf * resolved , const char * path ,
67+ int die_on_error )
7168{
72- static struct strbuf resolved = STRBUF_INIT ;
7369 struct strbuf remaining = STRBUF_INIT ;
7470 struct strbuf next = STRBUF_INIT ;
7571 struct strbuf symlink = STRBUF_INIT ;
7672 char * retval = NULL ;
7773 int num_symlinks = 0 ;
7874 struct stat st ;
7975
80- /* We've already done it */
81- if (path == resolved .buf )
82- return path ;
83-
8476 if (!* path ) {
8577 if (die_on_error )
8678 die ("The empty string is not a valid path" );
8779 else
8880 goto error_out ;
8981 }
9082
91- strbuf_reset (& resolved );
83+ strbuf_reset (resolved );
9284
9385 if (is_absolute_path (path )) {
9486 /* absolute path; start with only root as being resolved */
9587 int offset = offset_1st_component (path );
96- strbuf_add (& resolved , path , offset );
88+ strbuf_add (resolved , path , offset );
9789 strbuf_addstr (& remaining , path + offset );
9890 } else {
9991 /* relative path; can use CWD as the initial resolved path */
100- if (strbuf_getcwd (& resolved )) {
92+ if (strbuf_getcwd (resolved )) {
10193 if (die_on_error )
10294 die_errno ("unable to get current working directory" );
10395 else
@@ -116,21 +108,21 @@ static const char *real_path_internal(const char *path, int die_on_error)
116108 continue ; /* '.' component */
117109 } else if (next .len == 2 && !strcmp (next .buf , ".." )) {
118110 /* '..' component; strip the last path component */
119- strip_last_component (& resolved );
111+ strip_last_component (resolved );
120112 continue ;
121113 }
122114
123115 /* append the next component and resolve resultant path */
124- if (!is_dir_sep (resolved . buf [resolved . len - 1 ]))
125- strbuf_addch (& resolved , '/' );
126- strbuf_addbuf (& resolved , & next );
116+ if (!is_dir_sep (resolved -> buf [resolved -> len - 1 ]))
117+ strbuf_addch (resolved , '/' );
118+ strbuf_addbuf (resolved , & next );
127119
128- if (lstat (resolved . buf , & st )) {
120+ if (lstat (resolved -> buf , & st )) {
129121 /* error out unless this was the last component */
130122 if (errno != ENOENT || remaining .len ) {
131123 if (die_on_error )
132124 die_errno ("Invalid path '%s'" ,
133- resolved . buf );
125+ resolved -> buf );
134126 else
135127 goto error_out ;
136128 }
@@ -146,29 +138,29 @@ static const char *real_path_internal(const char *path, int die_on_error)
146138 goto error_out ;
147139 }
148140
149- len = strbuf_readlink (& symlink , resolved . buf ,
141+ len = strbuf_readlink (& symlink , resolved -> buf ,
150142 st .st_size );
151143 if (len < 0 ) {
152144 if (die_on_error )
153145 die_errno ("Invalid symlink '%s'" ,
154- resolved . buf );
146+ resolved -> buf );
155147 else
156148 goto error_out ;
157149 }
158150
159151 if (is_absolute_path (symlink .buf )) {
160152 /* absolute symlink; set resolved to root */
161153 int offset = offset_1st_component (symlink .buf );
162- strbuf_reset (& resolved );
163- strbuf_add (& resolved , symlink .buf , offset );
154+ strbuf_reset (resolved );
155+ strbuf_add (resolved , symlink .buf , offset );
164156 strbuf_remove (& symlink , 0 , offset );
165157 } else {
166158 /*
167159 * relative symlink
168160 * strip off the last component since it will
169161 * be replaced with the contents of the symlink
170162 */
171- strip_last_component (& resolved );
163+ strip_last_component (resolved );
172164 }
173165
174166 /*
@@ -188,24 +180,29 @@ static const char *real_path_internal(const char *path, int die_on_error)
188180 }
189181 }
190182
191- retval = resolved . buf ;
183+ retval = resolved -> buf ;
192184
193185error_out :
194186 strbuf_release (& remaining );
195187 strbuf_release (& next );
196188 strbuf_release (& symlink );
197189
190+ if (!retval )
191+ strbuf_reset (resolved );
192+
198193 return retval ;
199194}
200195
201196const char * real_path (const char * path )
202197{
203- return real_path_internal (path , 1 );
198+ static struct strbuf realpath = STRBUF_INIT ;
199+ return strbuf_realpath (& realpath , path , 1 );
204200}
205201
206202const char * real_path_if_valid (const char * path )
207203{
208- return real_path_internal (path , 0 );
204+ static struct strbuf realpath = STRBUF_INIT ;
205+ return strbuf_realpath (& realpath , path , 0 );
209206}
210207
211208/*
0 commit comments