Commit a843a05f authored by unknown's avatar unknown

Workaround for problem where cygwin's bash/sh randomly fails with error 128 which

mainly occurs on win2003 64bit.
 - Execute "exec" commands directly with cmd.exe and replace "--exec echo ..." with "--exec .\echo.exe ..." 


client/mysqltest.c:
  Workaround the problem with "echo" in windows not behaving like "echo" in Unix.
  - Replace "--exec echo ..." with "--exec <path to mysqltest>\echo.exe" thus forcing
    use of our own echo implementation which baheves like on Unix.
  - The above change makes it possible to remove the need to execute all --exec's
    inside cygwin. Add ifdefs to only use use cygwin's bash conditionally
mysql-test/lib/mtr_misc.pl:
  Add function for converting to the OS's native format
mysql-test/mysql-test-run.pl:
  Convert path to executables to "windows native" (c:\<path>\) instead of "mixed"(c:/<path>) mode
  necessary for pipes and redirects to work properly in cmd.exe
client/echo.c:
  New BitKeeper file ``client/echo.c''
parent 7560dbd2
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
echo is a replacement for the "echo" command builtin to cmd.exe
on Windows, to get a Unix eqvivalent behaviour when running commands
like:
$> echo "hello" | mysql
The windows "echo" would have sent "hello" to mysql while
Unix echo will send hello without the enclosing hyphens
This is a very advanced high tech program so take care when
you change it and remember to valgrind it before production
use.
*/
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
for (i= 1; i < argc; i++)
{
fprintf(stdout, "%s", argv[i]);
if (i < argc - 1)
fprintf(stdout, " ");
}
fprintf(stdout, "\n");
return 0;
}
......@@ -407,6 +407,8 @@ TYPELIB command_typelib= {array_elements(command_names),"",
DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages;
char builtin_echo[FN_REFLEN];
void die(const char *fmt, ...)
ATTRIBUTE_FORMAT(printf, 1, 2);
void abort_not_supported_test(const char *fmt, ...)
......@@ -913,10 +915,10 @@ void warning_msg(const char *fmt, ...)
dynstr_append_mem(&ds_warning_messages,
buff, len);
}
#ifndef __WIN__
len= vsnprintf(buff, sizeof(buff), fmt, args);
len= my_vsnprintf(buff, sizeof(buff), fmt, args);
dynstr_append_mem(&ds_warning_messages, buff, len);
#endif
dynstr_append(&ds_warning_messages, "\n");
va_end(args);
......@@ -1497,29 +1499,36 @@ void do_source(struct st_command *command)
}
#ifdef __WIN__
#if defined __WIN__
#ifdef USE_CYGWIN
/* Variables used for temporary sh files used for emulating Unix on Windows */
char tmp_sh_name[64], tmp_sh_cmd[70];
#endif
void init_tmp_sh_file()
{
#ifdef USE_CYGWIN
/* Format a name for the tmp sh file that is unique for this process */
my_snprintf(tmp_sh_name, sizeof(tmp_sh_name), "tmp_%d.sh", getpid());
/* Format the command to execute in order to run the script */
my_snprintf(tmp_sh_cmd, sizeof(tmp_sh_cmd), "sh %s", tmp_sh_name);
#endif
}
void free_tmp_sh_file()
{
#ifdef USE_CYGWIN
my_delete(tmp_sh_name, MYF(0));
#endif
}
#endif
FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode)
{
#ifdef __WIN__
#if defined __WIN__ && defined USE_CYGWIN
/* Dump the command into a sh script file and execute with popen */
str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length);
return popen(tmp_sh_cmd, mode);
......@@ -1529,6 +1538,64 @@ FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode)
}
static void init_builtin_echo(void)
{
#ifdef __WIN__
/* Look for "echo.exe" in same dir as mysqltest was started from */
dirname_part(builtin_echo, my_progname);
fn_format(builtin_echo, ".\\echo.exe",
builtin_echo, "", MYF(MY_REPLACE_DIR));
/* Make sure echo.exe exists */
if (access(builtin_echo, F_OK) != 0)
builtin_echo[0]= 0;
return;
#else
builtin_echo[0]= 0;
return;
#endif
}
/*
Replace a substring
SYNOPSIS
replace
ds_str The string to search and perform the replace in
search_str The string to search for
search_len Length of the string to search for
replace_str The string to replace with
replace_len Length of the string to replace with
RETURN
0 String replaced
1 Could not find search_str in str
*/
static int replace(DYNAMIC_STRING *ds_str,
const char *search_str, ulong search_len,
const char *replace_str, ulong replace_len)
{
DYNAMIC_STRING ds_tmp;
const char *start= strstr(ds_str->str, search_str);
if (!start)
return 1;
init_dynamic_string(&ds_tmp, "",
ds_str->length + replace_len, 256);
dynstr_append_mem(&ds_tmp, ds_str->str, start - ds_str->str);
dynstr_append_mem(&ds_tmp, replace_str, replace_len);
dynstr_append(&ds_tmp, start + search_len);
dynstr_set(ds_str, ds_tmp.str);
dynstr_free(&ds_tmp);
return 0;
}
/*
Execute given command.
......@@ -1547,13 +1614,13 @@ FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode)
NOTE
Although mysqltest is executed from cygwin shell, the command will be
executed in "cmd.exe". Thus commands like "rm" etc can NOT be used, use
system for those commands.
mysqltest commmand(s) like "remove_file" for that
*/
void do_exec(struct st_command *command)
{
int error;
char buf[1024];
char buf[512];
FILE *res_file;
char *cmd= command->first_argument;
DYNAMIC_STRING ds_cmd;
......@@ -1571,8 +1638,15 @@ void do_exec(struct st_command *command)
/* Eval the command, thus replacing all environment variables */
do_eval(&ds_cmd, cmd, command->end, TRUE);
/* Check if echo should be replaced with "builtin" echo */
if (builtin_echo[0] && strncmp(cmd, "echo", 4) == 0)
{
/* Replace echo with our "builtin" echo */
replace(&ds_cmd, "echo", 4, builtin_echo, strlen(builtin_echo));
}
DBUG_PRINT("info", ("Executing '%s' as '%s'",
command->first_argument, cmd));
command->first_argument, ds_cmd.str));
if (!(res_file= my_popen(&ds_cmd, "r")) && command->abort_on_error)
die("popen(\"%s\", \"r\") failed", command->first_argument);
......@@ -1690,7 +1764,7 @@ int do_modify_var(struct st_command *command,
int my_system(DYNAMIC_STRING* ds_cmd)
{
#ifdef __WIN__
#if defined __WIN__ && defined USE_CYGWIN
/* Dump the command into a sh script file and execute with system */
str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length);
return system(tmp_sh_cmd);
......@@ -5613,6 +5687,7 @@ int main(int argc, char **argv)
parser.current_line= parser.read_lines= 0;
memset(&var_reg, 0, sizeof(var_reg));
init_builtin_echo();
#ifdef __WIN__
init_tmp_sh_file();
init_win_path_patterns();
......
......@@ -8,6 +8,7 @@ use strict;
sub mtr_full_hostname ();
sub mtr_short_hostname ();
sub mtr_native_path($);
sub mtr_init_args ($);
sub mtr_add_arg ($$@);
sub mtr_path_exists(@);
......@@ -49,6 +50,16 @@ sub mtr_short_hostname () {
return $hostname;
}
# Convert path to OS native format
sub mtr_native_path($)
{
my $path= shift;
$path=~ s/\//\\/g
if ($::glob_win32);
return $path;
}
# FIXME move to own lib
sub mtr_init_args ($) {
......
......@@ -347,6 +347,7 @@ sub stop_all_servers ();
sub run_mysqltest ($);
sub usage ($);
######################################################################
#
# Main program
......@@ -1518,7 +1519,8 @@ sub executable_setup () {
sub generate_cmdline_mysqldump ($) {
my($mysqld) = @_;
return
"$exe_mysqldump --no-defaults -uroot " .
mtr_native_path($exe_mysqldump) .
" --no-defaults -uroot " .
"--port=$mysqld->{'port'} " .
"--socket=$mysqld->{'path_sock'} --password=";
}
......@@ -1721,7 +1723,8 @@ sub environment_setup () {
# Setup env so childs can execute mysqlcheck
# ----------------------------------------------------
my $cmdline_mysqlcheck=
"$exe_mysqlcheck --no-defaults -uroot " .
mtr_native_path($exe_mysqlcheck) .
" --no-defaults -uroot " .
"--port=$master->[0]->{'port'} " .
"--socket=$master->[0]->{'path_sock'} --password=";
......@@ -1755,7 +1758,8 @@ sub environment_setup () {
if ( $exe_mysqlslap )
{
my $cmdline_mysqlslap=
"$exe_mysqlslap -uroot " .
mtr_native_path($exe_mysqlslap) .
" -uroot " .
"--port=$master->[0]->{'port'} " .
"--socket=$master->[0]->{'path_sock'} --password= " .
"--lock-directory=$opt_tmpdir";
......@@ -1772,7 +1776,8 @@ sub environment_setup () {
# Setup env so childs can execute mysqlimport
# ----------------------------------------------------
my $cmdline_mysqlimport=
"$exe_mysqlimport -uroot " .
mtr_native_path($exe_mysqlimport) .
" -uroot " .
"--port=$master->[0]->{'port'} " .
"--socket=$master->[0]->{'path_sock'} --password=";
......@@ -1788,7 +1793,8 @@ sub environment_setup () {
# Setup env so childs can execute mysqlshow
# ----------------------------------------------------
my $cmdline_mysqlshow=
"$exe_mysqlshow -uroot " .
mtr_native_path($exe_mysqlshow) .
" -uroot " .
"--port=$master->[0]->{'port'} " .
"--socket=$master->[0]->{'path_sock'} --password=";
......@@ -1803,7 +1809,7 @@ sub environment_setup () {
# Setup env so childs can execute mysqlbinlog
# ----------------------------------------------------
my $cmdline_mysqlbinlog=
"$exe_mysqlbinlog" .
mtr_native_path($exe_mysqlbinlog) .
" --no-defaults --local-load=$opt_tmpdir";
if ( $mysql_version_id >= 50000 )
{
......@@ -1821,7 +1827,8 @@ sub environment_setup () {
# Setup env so childs can execute mysql
# ----------------------------------------------------
my $cmdline_mysql=
"$exe_mysql --no-defaults --host=localhost --user=root --password= " .
mtr_native_path($exe_mysql) .
" --no-defaults --host=localhost --user=root --password= " .
"--port=$master->[0]->{'port'} " .
"--socket=$master->[0]->{'path_sock'} ".
"--character-sets-dir=$path_charsetsdir";
......@@ -1850,17 +1857,17 @@ sub environment_setup () {
# ----------------------------------------------------
# Setup env so childs can execute my_print_defaults
# ----------------------------------------------------
$ENV{'MYSQL_MY_PRINT_DEFAULTS'}= $exe_my_print_defaults;
$ENV{'MYSQL_MY_PRINT_DEFAULTS'}= mtr_native_path($exe_my_print_defaults);
# ----------------------------------------------------
# Setup env so childs can execute mysqladmin
# ----------------------------------------------------
$ENV{'MYSQLADMIN'}= $exe_mysqladmin;
$ENV{'MYSQLADMIN'}= mtr_native_path($exe_mysqladmin);
# ----------------------------------------------------
# Setup env so childs can execute perror
# ----------------------------------------------------
$ENV{'MY_PERROR'}= $exe_perror;
$ENV{'MY_PERROR'}= mtr_native_path($exe_perror);
# ----------------------------------------------------
# Add the path where mysqld will find udf_example.so
......@@ -4516,7 +4523,8 @@ sub run_mysqltest ($) {
# ----------------------------------------------------------------------
# export MYSQL_TEST variable containing <path>/mysqltest <args>
# ----------------------------------------------------------------------
$ENV{'MYSQL_TEST'}= "$exe_mysqltest " . join(" ", @$args);
$ENV{'MYSQL_TEST'}=
mtr_native_path($exe_mysqltest) . " " . join(" ", @$args);
# ----------------------------------------------------------------------
# Add arguments that should not go into the MYSQL_TEST env var
......
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