[Lldb-commits] [lldb] r107370 - /lldb/trunk/source/Core/FileSpec.cpp
Jim Ingham
jingham at apple.com
Wed Jun 30 18:48:54 PDT 2010
Author: jingham
Date: Wed Jun 30 20:48:53 2010
New Revision: 107370
URL: http://llvm.org/viewvc/llvm-project?rev=107370&view=rev
Log:
Moved the User Name expansion over to FileSpec, and converted it to use getpwname directly.
Changed the file completion to deal with this, and FileSpec::Resolve now resolves all user names (not just ~/).
Modified:
lldb/trunk/source/Core/FileSpec.cpp
Modified: lldb/trunk/source/Core/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FileSpec.cpp?rev=107370&r1=107369&r2=107370&view=diff
==============================================================================
--- lldb/trunk/source/Core/FileSpec.cpp (original)
+++ lldb/trunk/source/Core/FileSpec.cpp Wed Jun 30 20:48:53 2010
@@ -9,12 +9,12 @@
#include <fcntl.h>
-#include <glob.h>
#include <libgen.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <pwd.h>
#include <fstream>
@@ -42,18 +42,89 @@
static std::string g_tilde;
if (g_tilde.empty())
{
- glob_t globbuf;
- if (::glob("~/", GLOB_TILDE, NULL, &globbuf) == 0) //success
- {
- g_tilde = globbuf.gl_pathv[0];
- ::globfree (&globbuf);
- }
+ struct passwd *user_entry;
+ user_entry = getpwuid(geteuid());
+ if (user_entry != NULL)
+ g_tilde = user_entry->pw_dir;
+
if (g_tilde.empty())
return NULL;
}
return g_tilde.c_str();
}
+// Resolves the username part of a path of the form ~user/other/directories, and
+// writes the result into dst_path.
+// Returns 0 if there WAS a ~ in the path but the username couldn't be resolved.
+// Otherwise returns the number of characters copied into dst_path. If the return
+// is >= dst_len, then the resolved path is too long...
+int
+FileSpec::ResolveUsername (const char *src_path, char *dst_path, size_t dst_len)
+{
+ char user_home[PATH_MAX];
+ const char *user_name;
+
+ if (src_path == NULL || src_path[0] == '\0')
+ return 0;
+
+ // If there's no ~, then just copy src_path straight to dst_path (they may be the same string...)
+ if (src_path[0] != '~')
+ {
+ int len = strlen (src_path);
+ if (len >= dst_len)
+ {
+ bcopy(src_path, dst_path, dst_len - 1);
+ dst_path[dst_len] = '\0';
+ }
+ else
+ bcopy(src_path, dst_path, len + 1);
+
+ return len;
+ }
+
+ char *first_slash = strchr(src_path, '/');
+ char remainder[PATH_MAX];
+
+ if (first_slash == NULL)
+ {
+ // The whole name is the username (minus the ~):
+ user_name = src_path + 1;
+ remainder[0] = '\0';
+ }
+ else
+ {
+ int user_name_len = first_slash - src_path - 1;
+ memcpy(user_home, src_path + 1, user_name_len);
+ user_home[user_name_len] = '\0';
+ user_name = user_home;
+
+ strcpy(remainder, first_slash);
+ }
+
+ if (user_name == NULL)
+ return 0;
+ // User name of "" means the current user...
+
+ struct passwd *user_entry;
+ const char *home_dir;
+
+ if (user_name[0] == '\0')
+ {
+ home_dir = GetCachedGlobTildeSlash();
+ }
+ else
+ {
+ user_entry = getpwnam (user_name);
+ if (user_entry != NULL)
+ home_dir = user_entry->pw_dir;
+ }
+
+ if (home_dir == NULL)
+ return 0;
+ else
+ return ::snprintf (dst_path, dst_len, "%s%s", home_dir, remainder);
+}
+
int
FileSpec::Resolve (const char *src_path, char *dst_path, size_t dst_len)
{
@@ -62,8 +133,15 @@
// Glob if needed for ~/, otherwise copy in case src_path is same as dst_path...
char unglobbed_path[PATH_MAX];
- if (::strstr (src_path, "~/") == src_path)
- ::snprintf(unglobbed_path, sizeof(unglobbed_path), "%s%s", GetCachedGlobTildeSlash(), src_path + 2);
+ if (src_path[0] == '~')
+ {
+ int return_count = ResolveUsername(src_path, unglobbed_path, sizeof(unglobbed_path));
+
+ // If we couldn't find the user referred to, or the resultant path was too long,
+ // then just copy over the src_path.
+ if (return_count == 0 || return_count >= sizeof(unglobbed_path))
+ ::snprintf (unglobbed_path, sizeof(unglobbed_path), "%s", src_path);
+ }
else
::snprintf(unglobbed_path, sizeof(unglobbed_path), "%s", src_path);
More information about the lldb-commits
mailing list