mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-25 04:43:03 +01:00
201 lines
5.5 KiB
C++
201 lines
5.5 KiB
C++
/*
|
|
* The contents of this file are subject to the Interbase Public
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy
|
|
* of the License at http://www.Inprise.com/IPL.html
|
|
*
|
|
* Software distributed under the License is distributed on an
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
* or implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code was created by Inprise Corporation
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
* Copyright (C) Inprise Corporation.
|
|
*
|
|
* All Rights Reserved.
|
|
* Contributor(s): ______________________________________.
|
|
* $Id: guard.cpp,v 1.5 2002-09-08 07:56:50 dimitr Exp $
|
|
*/
|
|
/* contains the main() and not shared routines for ibguard */
|
|
|
|
#define FOREVER 1
|
|
#define ONETIME 2
|
|
#define IGNORE 3
|
|
#define NORMAL_EXIT 0
|
|
|
|
#define SUPER_SERVER_BINARY "bin/fbserver"
|
|
|
|
#define INTERBASE_USER "interbase"
|
|
#define FIREBIRD_USER "firebird"
|
|
#define INTERBASE_USER_SHORT "interbas"
|
|
|
|
#include "firebird.h"
|
|
#include "../jrd/ib_stdio.h"
|
|
|
|
#ifdef HAVE_STRING_H
|
|
#include <string.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
#include <sys/types.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
#include <sys/stat.h>
|
|
#endif
|
|
|
|
#include "../jrd/common.h"
|
|
#include "../jrd/isc_proto.h"
|
|
#include "../jrd/gds_proto.h"
|
|
#include "../jrd/file_params.h"
|
|
#include "../utilities/util_proto.h"
|
|
|
|
|
|
int CLIB_ROUTINE main( int argc, char **argv)
|
|
{
|
|
/**************************************
|
|
*
|
|
* m a i n
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* The main for ibguard. This process is used to start
|
|
* the super server (fbserver) and keep it running
|
|
* after an abnormal termination.
|
|
*
|
|
* process takes 1 argument: -f (default) or -o
|
|
*
|
|
**************************************/
|
|
TEXT **end, *p, c;
|
|
USHORT option = FOREVER; /* holds FOREVER or ONETIME */
|
|
TEXT user_name[256]; /* holds the user name */
|
|
USHORT done = TRUE, fd_guard;
|
|
pid_t child_pid;
|
|
TEXT *prog_name = argv[0];
|
|
TEXT *server_args[2];
|
|
TEXT process_name[1024];
|
|
|
|
ULONG old_mask;
|
|
ULONG new_mask = 0000;
|
|
|
|
end = argc + argv;
|
|
argv++;
|
|
while (argv < end) {
|
|
p = *argv++;
|
|
if (*p++ == '-')
|
|
switch (UPPER(*p)) {
|
|
case 'F':
|
|
option = FOREVER;
|
|
break;
|
|
case 'O':
|
|
option = ONETIME;
|
|
break;
|
|
case 'S':
|
|
option = IGNORE;
|
|
break;
|
|
default:
|
|
ib_fprintf(ib_stderr,
|
|
"Usage: %s [-signore | -onetime | -forever (default)]\n",
|
|
prog_name);
|
|
exit(-1);
|
|
break;
|
|
}
|
|
|
|
} /* while */
|
|
|
|
/* check user id */
|
|
ISC_get_user(user_name, NULL, NULL, NULL, NULL, NULL, NULL);
|
|
|
|
if (strcmp(user_name, INTERBASE_USER) && strcmp(user_name, "root")
|
|
&& strcmp(user_name, FIREBIRD_USER)
|
|
&& strcmp(user_name, INTERBASE_USER_SHORT)) {
|
|
/* invalid user bail out */
|
|
ib_fprintf(ib_stderr,
|
|
"%s: Invalid user (must be %s, %s, %s or root).\n",
|
|
prog_name, FIREBIRD_USER, INTERBASE_USER,
|
|
INTERBASE_USER_SHORT);
|
|
exit(-2);
|
|
}
|
|
|
|
/* get and set the umask for the current process */
|
|
old_mask = umask(new_mask);
|
|
|
|
/* exclusive lock the file */
|
|
if ((fd_guard = UTIL_ex_lock(GUARD_FILE)) < 0) {
|
|
/* could not get exclusive lock -- some other guardian is running */
|
|
if (fd_guard == -2)
|
|
ib_fprintf(ib_stderr, "%s: Program is already running.\n",
|
|
prog_name);
|
|
exit(-3);
|
|
}
|
|
|
|
/* the umask back to orignal donot want to carry this to child process */
|
|
umask(old_mask);
|
|
|
|
/* move the server name into the argument to be passed */
|
|
server_args[0] = process_name;
|
|
server_args[1] = NULL;
|
|
|
|
do {
|
|
int ret_code;
|
|
|
|
gds__log("%s: guardian starting %s\n",
|
|
prog_name, SUPER_SERVER_BINARY);
|
|
child_pid = UTIL_start_process(SUPER_SERVER_BINARY, server_args);
|
|
if (child_pid == -1) {
|
|
/* could not fork the server */
|
|
gds__log("%s: guardian could not start %s\n", prog_name,
|
|
server_args[1] ? server_args[1] : SUPER_SERVER_BINARY);
|
|
ib_fprintf(ib_stderr, "%s: Could not start %s\n", prog_name,
|
|
server_args[1] ? server_args[1] : SUPER_SERVER_BINARY);
|
|
UTIL_ex_unlock(fd_guard);
|
|
exit(-4);
|
|
}
|
|
|
|
/* wait for child to die, and evaluate exit status */
|
|
ret_code = UTIL_wait_for_child(child_pid);
|
|
if (ret_code != NORMAL_EXIT) {
|
|
/* check for startup error */
|
|
if (ret_code == STARTUP_ERROR) {
|
|
gds__log("%s: %s terminated due to startup error (%d)\n",
|
|
prog_name, server_args[1] ? server_args[1] :
|
|
SUPER_SERVER_BINARY, ret_code);
|
|
if (option == IGNORE) {
|
|
gds__log
|
|
("%s: %s terminated due to startup error (%d)\n Trying again\n",
|
|
prog_name,
|
|
server_args[1] ? server_args[1] :
|
|
SUPER_SERVER_BINARY, ret_code);
|
|
|
|
done = FALSE; /* Try it again, Sam (even if it is a startup error) FSG 8.11.2000 */
|
|
}
|
|
else {
|
|
gds__log("%s: %s terminated due to startup error (%d)\n",
|
|
prog_name, server_args[1] ? server_args[1] :
|
|
SUPER_SERVER_BINARY, ret_code);
|
|
|
|
done = TRUE; /* do not restart we have a startup problem */
|
|
}
|
|
}
|
|
else {
|
|
gds__log("%s: %s terminated abnormally (%d)\n", prog_name,
|
|
server_args[1] ? server_args[1] :
|
|
SUPER_SERVER_BINARY, ret_code);
|
|
if (option == FOREVER || option == IGNORE)
|
|
done = FALSE;
|
|
}
|
|
}
|
|
else {
|
|
/* Normal shutdown - eg: via ibmgr - don't restart the server */
|
|
gds__log("%s: %s normal shutdown.\n", prog_name,
|
|
server_args[1] ? server_args[1] : SUPER_SERVER_BINARY);
|
|
done = TRUE;
|
|
}
|
|
} while (!done);
|
|
|
|
UTIL_ex_unlock(fd_guard);
|
|
exit(0);
|
|
} /* main */
|