diff options
author | wax@kishkin.ru <> | 2004-09-16 00:47:45 +0600 |
---|---|---|
committer | wax@kishkin.ru <> | 2004-09-16 00:47:45 +0600 |
commit | eb7515366b050a0fceed63e27e89e89c95483242 (patch) | |
tree | c716748cbe263336273d57ccd7f7d711218b425f /mysql-test/my_manage.c | |
parent | 9ddd3ad5ec24c3adc137861af0323c8d624a301c (diff) | |
download | mariadb-git-eb7515366b050a0fceed63e27e89e89c95483242.tar.gz |
WL#964
porting mysql_test_run on Linux and Windows
Diffstat (limited to 'mysql-test/my_manage.c')
-rw-r--r-- | mysql-test/my_manage.c | 860 |
1 files changed, 860 insertions, 0 deletions
diff --git a/mysql-test/my_manage.c b/mysql-test/my_manage.c new file mode 100644 index 00000000000..e23d4f2227e --- /dev/null +++ b/mysql-test/my_manage.c @@ -0,0 +1,860 @@ +/* + Copyright (c) 2003 Novell, Inc. All Rights Reserved. + + 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 +*/ + +#include <stdio.h> +#include <errno.h> +#ifndef __WIN__ +#include <dirent.h> +#endif +#include <string.h> +#ifdef __NETWARE__ +#include <screen.h> +#include <proc.h> +#else +#include <sys/types.h> +#ifndef __WIN__ +#include <sys/wait.h> +#include <unistd.h> +#else +#include <direct.h> +#include <stdlib.h> +#include <stdio.h> +#endif +#endif +#include <ctype.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <assert.h> + +#include "my_manage.h" + +#ifndef __NETWARE__ +#define ASSERT assert +extern char **environ; +#endif + + + +/****************************************************************************** + + macros + +******************************************************************************/ + +/****************************************************************************** + + global variables + +******************************************************************************/ + +/****************************************************************************** + + functions + +******************************************************************************/ + +/****************************************************************************** + + init_args() + + Init an argument list. + +******************************************************************************/ +void init_args(arg_list_t *al) +{ + ASSERT(al != NULL); + + al->argc = 0; + al->size = ARG_BUF; + al->argv = malloc(al->size * sizeof(char *)); + ASSERT(al->argv != NULL); + + return; +} + +/****************************************************************************** + + add_arg() + + Add an argument to a list. + +******************************************************************************/ +void add_arg(arg_list_t *al, const char *format, ...) +{ + va_list ap; + char temp[PATH_MAX]; + + ASSERT(al != NULL); + + // increase size + if (al->argc >= (int)al->size) + { + al->size += ARG_BUF; + al->argv = realloc(al->argv, al->size * sizeof(char *)); + ASSERT(al->argv != NULL); + } + + if (format) + { + va_start(ap, format); + vsprintf(temp, format, ap); + va_end(ap); + + al->argv[al->argc] = malloc(strlen(temp)+1); + ASSERT(al->argv[al->argc] != NULL); + strcpy(al->argv[al->argc], temp); + + ++(al->argc); + } + else + { + al->argv[al->argc] = NULL; + } + + return; +} + +/****************************************************************************** + + free_args() + + Free an argument list. + +******************************************************************************/ +void free_args(arg_list_t *al) +{ + int i; + + ASSERT(al != NULL); + + for(i = 0; i < al->argc; i++) + { + ASSERT(al->argv[i] != NULL); + free(al->argv[i]); + al->argv[i] = NULL; + } + + free(al->argv); + al->argc = 0; + al->argv = NULL; + + return; +} + +/****************************************************************************** + + sleep_until_file_deleted() + + Sleep until the given file is no longer found. + +******************************************************************************/ +#ifndef __WIN__ +int sleep_until_file_deleted(char *pid_file) +#else +int sleep_until_file_deleted(HANDLE pid_file) +#endif +{ + int err; +#ifndef __WIN__ + struct stat buf; + int i; + + for(i = 0; (i < TRY_MAX) && (err = !stat(pid_file, &buf)); i++) sleep(1); + + if (err != 0) err = errno; +#else + err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT); +#endif + return err; +} + +/****************************************************************************** + + sleep_until_file_exists() + + Sleep until the given file exists. + +******************************************************************************/ +#ifndef __WIN__ +int sleep_until_file_exists(char *pid_file) +#else +int sleep_until_file_exists(HANDLE pid_file) +#endif +{ + int err; +#ifndef __WIN__ + struct stat buf; + int i; + + for(i = 0; (i < TRY_MAX) && (err = stat(pid_file, &buf)); i++) sleep(1); + + if (err != 0) err = errno; +#else + err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT); +#endif + return err; +} + +/****************************************************************************** + + wait_for_server_start() + + Wait for the server on the given port to start. + +******************************************************************************/ +int wait_for_server_start(char *bin_dir, char *mysqladmin_file, char *user, char *password, int port,char *tmp_dir) +{ + arg_list_t al; + int err, i; + char trash[PATH_MAX]; + + // mysqladmin file + snprintf(trash, PATH_MAX, "%s/trash.out",tmp_dir); + + // args + init_args(&al); + add_arg(&al, "%s", mysqladmin_file); + add_arg(&al, "--no-defaults"); + add_arg(&al, "--port=%u", port); + add_arg(&al, "--user=%s", user); + add_arg(&al, "--password=%s", password); + add_arg(&al, "--silent"); + +//#ifdef NOT_USED +#ifndef __NETWARE__ + add_arg(&al, "-O"); + add_arg(&al, "connect_timeout=10"); + add_arg(&al, "-w"); +#endif + + add_arg(&al, "--host=localhost"); +#ifndef __NETWARE__ + add_arg(&al, "--protocol=tcp"); +#endif + add_arg(&al, "ping"); + + // NetWare does not support the connect timeout in the TCP/IP stack + // -- we will try the ping multiple times +#ifndef __WIN__ + for(i = 0; (i < TRY_MAX) + && (err = spawn(mysqladmin_file, &al, TRUE, NULL, + trash, NULL, NULL)); i++) sleep(1); +#else + err = spawn(mysqladmin_file, &al, TRUE, NULL,trash, NULL, NULL); +#endif + + // free args + free_args(&al); + + return err; +} + +/****************************************************************************** + + spawn() + + Spawn the given path with the given arguments. + +******************************************************************************/ +#ifdef __NETWARE__ +int spawn(char *path, arg_list_t *al, int join, char *input, + char *output, char *error, char *pid_file) +{ + pid_t pid; + int result = 0; + wiring_t wiring = { FD_UNUSED, FD_UNUSED, FD_UNUSED }; + unsigned long flags = PROC_CURRENT_SPACE | PROC_INHERIT_CWD; + + // open wiring + if (input) + wiring.infd = open(input, O_RDONLY); + + if (output) + wiring.outfd = open(output, O_WRONLY | O_CREAT | O_TRUNC); + + if (error) + wiring.errfd = open(error, O_WRONLY | O_CREAT | O_TRUNC); + + // procve requires a NULL + add_arg(al, NULL); + + // go + pid = procve(path, flags, NULL, &wiring, NULL, NULL, 0, + NULL, (const char **)al->argv); + + // close wiring + if (wiring.infd != -1) + close(wiring.infd); + + if (wiring.outfd != -1) + close(wiring.outfd); + + if (wiring.errfd != -1) + close(wiring.errfd); + + return result; +} +#elif __WIN__ + +int spawn(char *path, arg_list_t *al, int join, char *input, + char *output, char *error, HANDLE *pid) +{ + intptr_t result; + int i; + STARTUPINFO startup_info; + PROCESS_INFORMATION process_information; + DWORD exit_code; + char win_args[1024]= ""; + char command_line[1024]= ""; + + /* + Skip the first parameter + */ + for(i = 1; i < al->argc; i++) + { + ASSERT(al->argv[i] != NULL); + strcat(win_args,al->argv[i]); + strcat(win_args," "); + } + + memset(&startup_info,0,sizeof(STARTUPINFO)); + startup_info.cb = sizeof(STARTUPINFO); + + if (input) + freopen(input, "rb", stdin); + + if (output) + freopen(output, "wb", stdout); + + if (error) + freopen(error, "wb", stderr); + + result= CreateProcess( + path, + (LPSTR)&win_args, + NULL, + NULL, + TRUE, + 0, + NULL, + NULL, + &startup_info, + &process_information + ); + + if (result && process_information.hProcess) + { + if (join) + { + if (WaitForSingleObject(process_information.hProcess, mysqld_timeout) == WAIT_TIMEOUT) + { + exit_code= -1; + } + else + { + GetExitCodeProcess(process_information.hProcess, &exit_code); + } + CloseHandle(process_information.hProcess); + } + else + { + exit_code= 0; + } + if (pid != NULL) + *pid= process_information.hProcess; + } + else + { + exit_code= -1; + } + if (input) + freopen("CONIN$","rb",stdin); + if (output) + freopen("CONOUT$","wb",stdout); + if (error) + freopen("CONOUT$","wb",stderr); + + return exit_code; +} +#else +int spawn(char *path, arg_list_t *al, int join, char *input, + char *output, char *error, char *pid_file) +{ + pid_t pid; + int res_exec = 0; + int result = 0; + + pid = fork(); + + if (pid == -1) + { + fprintf(stderr, "fork was't created\n"); + /* + We can't create the fork...exit with error + */ + return EXIT_FAILURE; + } + + if (pid > 0) + { + /* + The parent process is waiting for child process if join is not zero + */ + if (join) + { + waitpid(pid, &result, 0); + if (WIFEXITED(result) != 0) + { + result = WEXITSTATUS(result); + } + else + { + result = EXIT_FAILURE; + } + } + } + else + { + + /* + Child process + */ + + add_arg(al, NULL); + + + /* + Reassign streams + */ + if (input) + freopen(input, "r", stdin); + + + if (output) + freopen(output, "w", stdout); + + + if (error) + freopen(error, "w", stderr); + + /* Spawn the process */ + if ((res_exec = execve(path, al->argv, environ)) < 0) + { + exit(EXIT_FAILURE); + } + + /* + Restore streams + */ + if (input) + freopen("/dev/tty", "r", stdin); + + if (output) + freopen("/dev/tty", "w", stdout); + + if (error) + freopen("/dev/tty", "w", stderr); + + exit(0); + } + + return result; +} +#endif +/****************************************************************************** + + stop_server() + + Stop the server with the given port and pid file. + +******************************************************************************/ +#ifndef __WIN__ +int stop_server(char *bin_dir, char *mysqladmin_file, char *user, char *password, int port, + char *pid_file,char *tmp_dir) +#else +int stop_server(char *bin_dir, char *mysqladmin_file, char *user, char *password, int port, + HANDLE pid_file,char *tmp_dir) +#endif +{ + arg_list_t al; + int err = 0; + char trash[PATH_MAX]; + + snprintf(trash, PATH_MAX, "%s/trash.out",tmp_dir); + + // args + init_args(&al); + add_arg(&al, "%s", mysqladmin_file); + add_arg(&al, "--no-defaults"); + add_arg(&al, "--port=%u", port); + add_arg(&al, "--user=%s", user); + add_arg(&al, "--password=%s", password); + add_arg(&al, "-O"); + add_arg(&al, "shutdown_timeout=20"); +#ifndef __NETWARE__ + add_arg(&al, "--protocol=tcp"); +#endif + add_arg(&al, "shutdown"); + + // spawn + if ((err = spawn(mysqladmin_file, &al, TRUE, NULL, + trash, NULL, NULL)) == 0) + { + sleep_until_file_deleted(pid_file); + } + else + { +#ifndef __WIN__ + pid_t pid = get_server_pid(pid_file); + + // shutdown failed - kill server + kill_server(pid); + + sleep(TRY_MAX); + + // remove pid file if possible + err = remove(pid_file); +#else + TerminateProcess(pid_file,err); +#endif + } + + // free args + free_args(&al); + + return err; +} + +/****************************************************************************** + + get_server_pid() + + Get the VM id with the given pid file. + +******************************************************************************/ +#ifndef __WIN__ +pid_t get_server_pid(char *pid_file) +{ + char buf[PATH_MAX]; + int fd, err; + char *p; + pid_t id = 0; + + // discover id + fd = open(pid_file, O_RDONLY); + + err = read(fd, buf, PATH_MAX); + + close(fd); + + if (err > 0) + { + // terminate string + if ((p = strchr(buf, '\n')) != NULL) + { + *p = '\0'; + + // check for a '\r' + if ((p = strchr(buf, '\r')) != NULL) + { + *p = '\0'; + } + } + else + { + buf[err] = '\0'; + } + + id = strtol(buf, NULL, 0); + } + + return id; +} + +/****************************************************************************** + + kill_server() + + Force a kill of the server with the given pid. + +******************************************************************************/ +void kill_server(pid_t pid) +{ + if (pid > 0) + { +#if !defined(__NETWARE__) + /* Send SIGTERM to pid */ + kill(pid, SIGTERM); +#else /* __NETWARE__ */ + /* destroy vm */ + NXVmDestroy(pid); +#endif + } +} +#endif +/****************************************************************************** + + del_tree() + + Delete the directory and subdirectories. + +******************************************************************************/ +void del_tree(char *dir) +{ +#ifndef __WIN__ + DIR *parent = opendir(dir); + struct dirent *entry; + char temp[PATH_MAX]; + + if (parent == NULL) + { + return; + } + + while((entry = readdir(parent)) != NULL) + { + // create long name + snprintf(temp, PATH_MAX, "%s/%s", dir, entry->d_name); + + if (entry->d_name[0] == '.') + { + // Skip + } + else + if (S_ISDIR(entry->d_type)) + { + // delete subdirectory + del_tree(temp); + } + else + { + // remove file + remove(temp); + } + } + // remove directory + rmdir(dir); +#else + struct _finddata_t parent; + intptr_t handle; + char temp[PATH_MAX]; + char mask[PATH_MAX]; + + snprintf(mask,MAX_PATH,"%s/*.*",dir); + + if ((handle=_findfirst(mask,&parent)) == -1L) + { + return; + } + + do + { + // create long name + snprintf(temp, PATH_MAX, "%s/%s", dir, parent.name); + if (parent.name[0] == '.') + { + // Skip + } + else + if (parent.attrib & _A_SUBDIR) + { + // delete subdirectory + del_tree(temp); + } + else + { + // remove file + remove(temp); + } + } while (_findnext(handle,&parent) == 0); + + _findclose(handle); + + // remove directory + _rmdir(dir); +#endif +} + +/****************************************************************************** + + removef() + +******************************************************************************/ +int removef(const char *format, ...) +{ +#ifdef __NETWARE__ + va_list ap; + char path[PATH_MAX]; + + va_start(ap, format); + + vsnprintf(path, PATH_MAX, format, ap); + + va_end(ap); + return remove(path); + +#eldef __WIN__ + { + va_list ap; + char path[PATH_MAX]; + struct _finddata_t parent; + intptr_t handle; + char temp[PATH_MAX]; + char *p; + + va_start(ap, format); + + vsnprintf(path, PATH_MAX, format, ap); + + va_end(ap); + + p = path + strlen(path); + while (*p != '\\' && *p != '/' && p > path) p--; + + if ((handle=_findfirst(path,&parent)) == -1L) + { + /* + if there is not files....it's ok. + */ + return 0; + } + + *p = '\0'; + + do + { + if (! (parent.attrib & _A_SUBDIR)) + { + snprintf(temp, PATH_MAX, "%s/%s", path, parent.name); + remove(temp); + } + }while (_findnext(handle,&parent) == 0); + + _findclose(handle); + } +#else + DIR *parent; + struct dirent *entry; + char temp[PATH_MAX]; + va_list ap; + char path[PATH_MAX]; + char *p; + /* + Get path with mask + */ + va_start(ap, format); + + vsnprintf(path, PATH_MAX, format, ap); + + va_end(ap); + + p = path + strlen(path); + while (*p != '\\' && *p != '/' && p > path) p--; + *p = '\0'; + p++; + + parent = opendir(path); + + if (parent == NULL) + { + return; + } + + while((entry = readdir(parent)) != NULL) + { + /* + entry is not directory and entry matches with mask + */ + if (!S_ISDIR(entry->d_type) && !fnmatch(p, entry->d_name,0)) + { + // create long name + snprintf(temp, PATH_MAX, "%s/%s", path, entry->d_name); + // Delete only files + remove(temp); + } + } +#endif + return 0; +} + +/****************************************************************************** + + get_basedir() + +******************************************************************************/ +void get_basedir(char *argv0, char *basedir) +{ + char temp[PATH_MAX]; + char *p; + int position; + + ASSERT(argv0 != NULL); + ASSERT(basedir != NULL); + + strcpy(temp, strlwr(argv0)); + while((p = strchr(temp, '\\')) != NULL) *p = '/'; + + if ((position = strinstr(temp, "/bin/")) != 0) + { + p = temp + position; + *p = '\0'; + strcpy(basedir, temp); + } +} + +#if !defined(__NETWARE__) && !defined(__WIN__) +char *strlwr(const char *s) +{ + return s; +} +#endif + +uint strinstr(reg1 const char *str,reg4 const char *search) +{ + reg2 my_string i,j; + my_string start = (my_string) str; + + skipp: + while (*str != '\0') + { + if (*str++ == *search) + { + i=(my_string) str; j= (my_string) search+1; + while (*j) + if (*i++ != *j++) goto skipp; + return ((uint) (str - start)); + } + } + return (0); +} + +/****************************************************************************** + + remove_empty_file() + +******************************************************************************/ +void remove_empty_file(const char *file_name) +{ + struct stat file; + + if (!stat(file_name,&file)) + { + if (!file.st_size) + remove(file_name); + } +} |