mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-25 04:43:03 +01:00
ef2ff91438
o use predefined macros to test for sys/wait.h, time.h and sys/time.h o search strcasecmp in libresolv only if strcasecmp and stricmp are not in libc o use predefined macro AC_SYS_LARGEFILE to determine 64Bit I/O o determine the alignment of long and double (ALIGNMENT,DOUBLE_ALIGN), still need to write a test for FB_ALIGN!
248 lines
5.6 KiB
C++
248 lines
5.6 KiB
C++
/*
|
|
* PROGRAM: InterBase Utility programs
|
|
* MODULE: util.c
|
|
* DESCRIPTION: Utility routines for fbguard & fbserver
|
|
*
|
|
* 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: util.cpp,v 1.7 2002-09-18 12:50:05 eku Exp $
|
|
*/
|
|
|
|
#include "firebird.h"
|
|
#include "../jrd/ib_stdio.h"
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h> /* for open() and fcntl() */
|
|
#include <errno.h>
|
|
|
|
#ifdef HAVE_FLOCK
|
|
#include <sys/file.h> /* for flock() */
|
|
#endif
|
|
|
|
#ifdef HAVE_STRING_H
|
|
#include <string.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h> /* for fork() */
|
|
#endif
|
|
|
|
#ifdef HAVE_WAIT_H
|
|
#include <wait.h> /* for waitpid() */
|
|
#endif
|
|
|
|
#if HAVE_SYS_WAIT_H
|
|
# include <sys/wait.h>
|
|
#endif
|
|
#ifndef WEXITSTATUS
|
|
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
|
|
#endif
|
|
#ifndef WIFEXITED
|
|
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
|
|
#endif
|
|
|
|
|
|
#include "../jrd/common.h"
|
|
#include "../jrd/gdsassert.h"
|
|
#include "../utilities/util_proto.h"
|
|
#include "../jrd/gds_proto.h"
|
|
#include "../jrd/isc_proto.h"
|
|
|
|
#ifndef MAXPATHLEN
|
|
#define MAXPATHLEN 1024
|
|
#endif
|
|
|
|
|
|
|
|
pid_t UTIL_start_process(char *process, char **argv)
|
|
{
|
|
/**************************************
|
|
*
|
|
* U T I L _ s t a r t _ p r o c e s s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
*
|
|
* This function is used to create the specified process,
|
|
*
|
|
* Returns Codes:
|
|
* -1 Process spawn failed.
|
|
* pid Successful creation. PID is returned.
|
|
*
|
|
* Note: Make sure that the argument list ends with a null
|
|
* and the first argument is large enough to hold the complete
|
|
* expanded process name. (MAXPATHLEN recommended)
|
|
*
|
|
**************************************/
|
|
TEXT string[MAXPATHLEN];
|
|
pid_t pid;
|
|
|
|
assert(process != NULL);
|
|
assert(argv != NULL);
|
|
|
|
/* prepend InterBase home directory to the program name */
|
|
gds__prefix(string, process);
|
|
|
|
/* add place in argv for visibility to "ps" */
|
|
strcpy(argv[0], string);
|
|
|
|
if (!(pid = vfork())) {
|
|
execv(string, argv);
|
|
_exit(FINI_ERROR);
|
|
}
|
|
|
|
return (pid);
|
|
}
|
|
|
|
|
|
int UTIL_wait_for_child( pid_t child_pid)
|
|
{
|
|
/**************************************
|
|
*
|
|
* U T I L _ w a i t _ f o r _ c h i l d
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
*
|
|
* This function is used to wait for the child specified by child_pid
|
|
*
|
|
* Return code:
|
|
* 0 Normal exit
|
|
* -1 Abnormal exit - unknown reason.
|
|
* Other Abnormal exit - process error code returned.
|
|
*
|
|
**************************************/
|
|
int child_exit_status;
|
|
|
|
assert(child_pid != 0);
|
|
|
|
/* wait for the child process with child_pid to exit */
|
|
|
|
while (waitpid(child_pid, &child_exit_status, 0) == -1)
|
|
if (SYSCALL_INTERRUPTED(errno))
|
|
continue;
|
|
else
|
|
return (errno);
|
|
|
|
/* Check for very specific conditions before we assume the child
|
|
did a normal exit. */
|
|
|
|
if (WIFEXITED(child_exit_status) && (WEXITSTATUS(child_exit_status) != 0))
|
|
return (WEXITSTATUS(child_exit_status));
|
|
|
|
if (
|
|
#ifndef AIX_PPC
|
|
WCOREDUMP(child_exit_status) ||
|
|
#endif
|
|
WIFSIGNALED(child_exit_status) || !WIFEXITED(child_exit_status))
|
|
return (-1);
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
int UTIL_ex_lock( TEXT * file)
|
|
{
|
|
/**************************************
|
|
*
|
|
* U T I L _ e x _ l o c k
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
*
|
|
* This function is used to exclusively lock a file.
|
|
*
|
|
* Return Codes:
|
|
* -1 Failure to open file.
|
|
* -2 Failure to obtain exclusive lock on file.
|
|
* otherwise Success - file descriptor is returned.
|
|
*
|
|
**************************************/
|
|
|
|
TEXT expanded_filename[MAXPATHLEN], tmp[MAXPATHLEN], hostname[64];
|
|
int fd_file; /* file fd for the opened and locked file */
|
|
|
|
#ifndef HAVE_FLOCK
|
|
struct flock lock;
|
|
#endif
|
|
|
|
/* get the file name and prepend the complete path etc */
|
|
gds__prefix_lock(tmp, file);
|
|
sprintf(expanded_filename, tmp, ISC_get_host(hostname, sizeof(hostname)));
|
|
|
|
if ((fd_file = open(expanded_filename, O_RDWR | O_CREAT, 0666)) == -1) {
|
|
ib_fprintf(ib_stderr, "Could not open %s for write\n",
|
|
expanded_filename);
|
|
return (-1);
|
|
}
|
|
|
|
assert(fd_file != -2);
|
|
|
|
#ifndef HAVE_FLOCK
|
|
/* get an exclusive lock on the GUARD file without blocking on the call */
|
|
lock.l_type = F_WRLCK;
|
|
lock.l_whence = 0;
|
|
lock.l_start = 0;
|
|
lock.l_len = 0;
|
|
if (fcntl(fd_file, F_SETLK, &lock) == -1)
|
|
#else
|
|
if (flock(fd_file, LOCK_EX))
|
|
#endif
|
|
{
|
|
close(fd_file);
|
|
return (-2);
|
|
}
|
|
return (fd_file);
|
|
}
|
|
|
|
|
|
void UTIL_ex_unlock( int fd_file)
|
|
{
|
|
/**************************************
|
|
*
|
|
* U T I L _ e x _ l o c k
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
*
|
|
* This function is used to unlock the exclusive file.
|
|
*
|
|
**************************************/
|
|
|
|
|
|
#ifndef HAVE_FLOCK
|
|
|
|
struct flock lock;
|
|
|
|
/* get an exclusive lock on the GUARD file with a block */
|
|
lock.l_type = F_UNLCK;
|
|
lock.l_whence = 0;
|
|
lock.l_start = 0;
|
|
lock.l_len = 0;
|
|
fcntl(fd_file, F_SETLKW, &lock);
|
|
#else
|
|
flock(fd_file, LOCK_UN);
|
|
#endif
|
|
close(fd_file);
|
|
}
|