Commit abeda651 authored by Chad MILLER's avatar Chad MILLER

Bug#31605: mysql_upgrade relies on Linux /proc filesystem when not \

	running on Windows

We used two OS-specific methods of looking up the executable 
name, which don't work outside of those two kinds of OSes 
(Linux+Solaris and Windows).

We assume that if the user ran this program with a certain 
name, we can run the other sibling programs with a similar name.

(re-patch in bzr)
parent 82d13392
...@@ -259,6 +259,10 @@ get_one_option(int optid, const struct my_option *opt, ...@@ -259,6 +259,10 @@ get_one_option(int optid, const struct my_option *opt,
} }
/**
Run a command using the shell, storing its output in the supplied dynamic
string.
*/
static int run_command(char* cmd, static int run_command(char* cmd,
DYNAMIC_STRING *ds_res) DYNAMIC_STRING *ds_res)
{ {
...@@ -331,36 +335,16 @@ static int run_tool(char *tool_path, DYNAMIC_STRING *ds_res, ...) ...@@ -331,36 +335,16 @@ static int run_tool(char *tool_path, DYNAMIC_STRING *ds_res, ...)
} }
/* /**
Try to get the full path to this exceutable Look for the filename of given tool, with the presumption that it is in the
same directory as mysql_upgrade and that the same executable-searching
Return 0 if path found mechanism will be used when we run our sub-shells with popen() later.
*/ */
static void find_tool(char *tool_executable_name, const char *tool_name,
static my_bool get_full_path_to_executable(char* path) const char *self_name)
{ {
my_bool ret; char *last_fn_libchar;
DBUG_ENTER("get_full_path_to_executable");
#ifdef __WIN__
ret= (GetModuleFileName(NULL, path, FN_REFLEN) == 0);
#else
/* my_readlink returns 0 if a symlink was read */
ret= (my_readlink(path, "/proc/self/exe", MYF(0)) != 0);
/* Might also want to try with /proc/$$/exe if the above fails */
#endif
DBUG_PRINT("exit", ("path: %s", path));
DBUG_RETURN(ret);
}
/*
Look for the tool in the same directory as mysql_upgrade.
*/
static void find_tool(char *tool_path, const char *tool_name)
{
char path[FN_REFLEN];
DYNAMIC_STRING ds_tmp; DYNAMIC_STRING ds_tmp;
DBUG_ENTER("find_tool"); DBUG_ENTER("find_tool");
DBUG_PRINT("enter", ("progname: %s", my_progname)); DBUG_PRINT("enter", ("progname: %s", my_progname));
...@@ -368,77 +352,57 @@ static void find_tool(char *tool_path, const char *tool_name) ...@@ -368,77 +352,57 @@ static void find_tool(char *tool_path, const char *tool_name)
if (init_dynamic_string(&ds_tmp, "", 32, 32)) if (init_dynamic_string(&ds_tmp, "", 32, 32))
die("Out of memory"); die("Out of memory");
/* Initialize path with the full path to this program */ last_fn_libchar= strrchr(self_name, FN_LIBCHAR);
if (get_full_path_to_executable(path))
if (last_fn_libchar == NULL)
{ {
/* /*
Easy way to get full executable path failed, try mysql_upgrade was found by the shell searching the path. A sibling
other methods next to us should be found the same way.
*/ */
if (my_progname[0] == FN_LIBCHAR) strncpy(tool_executable_name, tool_name, FN_REFLEN);
{
/* 1. my_progname contains full path */
strmake(path, my_progname, FN_REFLEN);
}
else if (my_progname[0] == '.')
{
/* 2. my_progname contains relative path, prepend wd */
char buf[FN_REFLEN];
my_getwd(buf, FN_REFLEN, MYF(0));
my_snprintf(path, FN_REFLEN, "%s%s", buf, my_progname);
}
else
{
/* 3. Just go for it and hope tool is in path */
path[0]= 0;
}
} }
else
DBUG_PRINT("info", ("path: '%s'", path));
/* Chop off binary name (i.e mysql-upgrade) from path */
dirname_part(path, path);
/*
When running in a not yet installed build and using libtool,
the program(mysql_upgrade) will be in .libs/ and executed
through a libtool wrapper in order to use the dynamic libraries
from this build. The same must be done for the tools(mysql and
mysqlcheck). Thus if path ends in .libs/, step up one directory
and execute the tools from there
*/
path[max((strlen(path)-1), 0)]= 0; /* Chop off last / */
if (strncmp(path + dirname_length(path), ".libs", 5) == 0)
{ {
DBUG_PRINT("info", ("Chopping off .libs from '%s'", path)); /*
mysql_upgrade was run absolutely or relatively. We can find a sibling
/* Chop off .libs */ by replacing our name after the LIBCHAR with the new tool name.
dirname_part(path, path); */
}
DBUG_PRINT("info", ("path: '%s'", path));
/* Format name of the tool to search for */ /*
fn_format(tool_path, tool_name, When running in a not yet installed build and using libtool,
path, "", MYF(MY_REPLACE_DIR)); the program(mysql_upgrade) will be in .libs/ and executed
through a libtool wrapper in order to use the dynamic libraries
from this build. The same must be done for the tools(mysql and
mysqlcheck). Thus if path ends in .libs/, step up one directory
and execute the tools from there
*/
if (((last_fn_libchar - 6) >= self_name) &&
(strncmp(last_fn_libchar - 5, ".libs", 5) == 0) &&
(*(last_fn_libchar - 6) == FN_LIBCHAR))
{
DBUG_PRINT("info", ("Chopping off \".libs\" from end of path"));
last_fn_libchar -= 6;
}
verbose("Looking for '%s' in: %s", tool_name, tool_path); my_snprintf(tool_executable_name, FN_REFLEN, "%.*s%c%s",
(last_fn_libchar - self_name), self_name,
FN_LIBCHAR,
tool_name);
}
/* Make sure the tool exists */ verbose("Looking for '%s' as: %s", tool_name, tool_executable_name);
if (my_access(tool_path, F_OK) != 0)
die("Can't find '%s'", tool_path);
/* /*
Make sure it can be executed Make sure it can be executed
*/ */
if (run_tool(tool_path, if (run_tool(tool_executable_name,
&ds_tmp, /* Get output from command, discard*/ &ds_tmp, /* Get output from command, discard*/
"--help", "--help",
"2>&1", "2>&1",
IF_WIN("> NUL", "> /dev/null"), IF_WIN("> NUL", "> /dev/null"),
NULL)) NULL))
die("Can't execute '%s'", tool_path); die("Can't execute '%s'", tool_executable_name);
dynstr_free(&ds_tmp); dynstr_free(&ds_tmp);
...@@ -748,11 +712,20 @@ static const char *load_default_groups[]= ...@@ -748,11 +712,20 @@ static const char *load_default_groups[]=
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char self_name[FN_REFLEN];
MY_INIT(argv[0]); MY_INIT(argv[0]);
#ifdef __NETWARE__ #ifdef __NETWARE__
setscreenmode(SCR_AUTOCLOSE_ON_EXIT); setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
#endif #endif
#if __WIN__
if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
#endif
{
strncpy(self_name, argv[0], FN_REFLEN);
}
if (init_dynamic_string(&ds_args, "", 512, 256)) if (init_dynamic_string(&ds_args, "", 512, 256))
die("Out of memory"); die("Out of memory");
...@@ -774,10 +747,10 @@ int main(int argc, char **argv) ...@@ -774,10 +747,10 @@ int main(int argc, char **argv)
dynstr_append(&ds_args, " "); dynstr_append(&ds_args, " ");
/* Find mysql */ /* Find mysql */
find_tool(mysql_path, IF_WIN("mysql.exe", "mysql")); find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name);
/* Find mysqlcheck */ /* Find mysqlcheck */
find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck")); find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);
/* /*
Read the mysql_upgrade_info file to check if mysql_upgrade Read the mysql_upgrade_info file to check if mysql_upgrade
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment