git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/3] C implementation of the 'git' program, take two.

From
Linus Torvalds <torvalds@osdl.org>
Date
Nov 16, 2005, 00:18 UTC
Message-ID
<Pine.LNX.4.64.0511151603510.11232@g5.osdl.org>
In-Reply-To
<20051115233125.3153B5BF76@nox.op5.se>
On Wed, 16 Nov 2005, Andreas Ericsson wrote:
Show 9 quoted lines
> +
> +	/* allow relative paths, but run with exact */
> +	if (chdir(exec_path)) {
> +		printf("git: '%s': %s\n", exec_path, strerror(errno));
> +		exit (1);
> +	}
> +
> +	getcwd(git_command, sizeof(git_command));
> +	chdir(wd);

Argh. This is pretty horrible way to turn a path into an absolute one. Especially since you didn't even test whether the original "wd" was successful.

Why don't you just do
	if (exec_path[0] != '/') {
		.. prepend "cwd/" to exec_path ..

since as far as I can tell you don't actually care whether it's a simplified path or not (you can remove "./" at the beginning just to make it cleaner, if you wish. In fact, you can remove "../" at the beginning too (but only the beginning) since getcwd() shouldn't have any symlink components).

The reason to avoid "chdir(relative) + chdir(back)" is that it totally unnecessarily breaks under some extreme cases. For example, if the exec_path is already absolute, and we just happen to be in a really deep subdirectory, then the getcwd() could have failed due to the PATH_MAX limitations.

Also, depending on getcwd() will not work if any parent directory is unreadable or non-executable (well, under Linux it will, as long as it's executable, since getcwd() is actually a system call. Not in UNIX in general, though). Again, that means that unless you _have_ to know what the cwd is, you should try to avoid relying on it.

Now, there are Linux-specific tricks that can avoid some of the problems if you want to, but they are very much hacks:

	if (filename[0] != '/') {
		fd = open(filename, O_DIRECTORY);
		if (fd >= 0) {
			snprintf(link_name, sizeof(link_name), "/proc/self/fd/%d", fd);
			if (!readlink(link_name ...)) {
				.. there it is ..
			}
			close(fd);
		}
	..
and the nicer thign to do is to just not try to be clever.
		Linus
Previous: Junio C HamanoNext: Andreas Ericsson
Message 5 of 9 in “C implementation of the 'git' program, take two.”
  1. 1/3 C implementation of the 'git' program, take two.Andreas Ericsson, Nov 15, 2005
  2. Junio C HamanoNov 15, 2005
  3. Andreas EricssonNov 16, 2005
  4. Junio C HamanoNov 16, 2005
  5. Linus TorvaldsNov 16, 2005
  6. Andreas EricssonNov 16, 2005
  7. Linus TorvaldsNov 16, 2005
  8. Johannes SchindelinNov 16, 2005
  9. Alex RiesenNov 16, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.