Exemplo n.º 1
0
// create directory for lock files and set appropriate access rights
void createLockDirectory(const char* pathname)
{
	do
	{
		if (access(pathname, R_OK | W_OK | X_OK) == 0)
		{
			struct STAT st;
			if (os_utils::stat(pathname, &st) != 0)
				system_call_failed::raise("stat");

			if (S_ISDIR(st.st_mode))
				return;

			// not exactly original meaning, but very close to it
			system_call_failed::raise("access", ENOTDIR);
		}
	} while (SYSCALL_INTERRUPTED(errno));

	while (mkdir(pathname, 0700) != 0)		// anyway need chmod to avoid umask effects
	{
		if (SYSCALL_INTERRUPTED(errno))
		{
			continue;
		}
		(Arg::Gds(isc_lock_dir_access) << pathname).raise();
	}

	changeFileRights(pathname, 0770);
}
Exemplo n.º 2
0
int UTIL_shutdown_child(pid_t child_pid, unsigned timeout_term, unsigned timeout_kill)
{
/**************************************
 *
 *      U T I L _ s h u t d o w n _ c h i l d
 *
 **************************************
 *
 * Functional description
 *
 *     Terminates child using TERM signal, then KILL if it does not finish
 *     within specified timeout
 *
 * Return code:
 *	0	Child finished cleanly (TERM)
 *	1	Child killed (KILL)
 *	2	Child not killed by KILL
 *	-1	Syscall failed
 *
 **************************************/

	int r = kill(child_pid, SIGTERM);

	if (r < 0)
		return ((errno == ESRCH) ? 0 : -1);

	if (UTIL_set_handler(SIGALRM, alrm_handler, false) < 0)
		return -1;

	alarm(timeout_term);

	int child_status;
	r = waitpid(child_pid, &child_status, 0);

	if ((r < 0) && !SYSCALL_INTERRUPTED(errno))
		return -1;

	if (r == child_pid)
		return 0;

	r = kill(child_pid, SIGKILL);

	if (r < 0)
		return ((errno == ESRCH) ? 0 : -1);

	alarm(timeout_kill);
	r = waitpid(child_pid, &child_status, 0);

	if ((r < 0) && !SYSCALL_INTERRUPTED(errno))
		return -1;

	if (r == child_pid)
		return 1;

	return 2;
}
Exemplo n.º 3
0
// open (or create if missing) and set appropriate access rights
int openCreateSharedFile(const char* pathname, int flags)
{
	int fd = os_utils::open(pathname, flags | O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
	if (fd < 0)
		raiseError(fd, pathname);

	// Security check - avoid symbolic links in /tmp.
	// Malicious user can create a symlink with this name pointing to say
	// security2.fdb and when the lock file is created the file will be damaged.

	struct stat st;
	int rc;

	do {
		rc = fstat(fd, &st);
	} while (fd != 0 && SYSCALL_INTERRUPTED(errno));

	if (rc != 0)
	{
		int e = errno;
		close(fd);
		raiseError(e, pathname);
	}

	if (S_ISLNK(st.st_mode))
	{
		close(fd);
		raiseError(ELOOP, pathname);
	}

	changeFileRights(pathname, 0660);

	return fd;
}
Exemplo n.º 4
0
// force file descriptor to have O_CLOEXEC set
int open(const char* pathname, int flags, mode_t mode)
{
	int fd;
	do {
		fd = ::open(pathname, flags | O_CLOEXEC, mode);
	} while (fd < 0 && SYSCALL_INTERRUPTED(errno));

	if (fd < 0 && errno == EINVAL)	// probably O_CLOEXEC not accepted
	{
		do {
			fd = ::open(pathname, flags | O_CLOEXEC, mode);
		} while (fd < 0 && SYSCALL_INTERRUPTED(errno));
	}

	setCloseOnExec(fd);
	return fd;
}
Exemplo n.º 5
0
// setting flag is not absolutely required, therefore ignore errors here
void setCloseOnExec(int fd)
{
	if (fd >= 0)
	{
		while (fcntl(fd, F_SETFD, O_CLOEXEC) < 0 && SYSCALL_INTERRUPTED(errno))
			;
	}
}
Exemplo n.º 6
0
// set file's last access and modification time to current time
bool touchFile(const char* pathname)
{
#ifdef HAVE_UTIME_H
	while (utime(pathname, NULL) < 0)
	{
		if (SYSCALL_INTERRUPTED(errno))
		{
			continue;
		}
		return false;
	}

	return true;
#else
	return false;
#endif
}
Exemplo n.º 7
0
FILE* fopen(const char* pathname, const char* mode)
{
	FILE* f = NULL;
	do
	{
#ifdef LSB_BUILD
		// TODO: use open + fdopen to avoid races
		f = fopen64(pathname, mode);
#else
		f = ::fopen(pathname, mode);
#endif
	} while (f == NULL && SYSCALL_INTERRUPTED(errno));

	if (f)
		setCloseOnExec(fileno(f));
	return f;
}
Exemplo n.º 8
0
int UTIL_wait_for_child(pid_t child_pid, const volatile sig_atomic_t& shutting_down)
{
/**************************************
 *
 *      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.
 *	-2	TERM signal caught
 *	Other	Abnormal exit - process error code returned.
 *
 **************************************/
	int child_exit_status;

	fb_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))
		{
			if (shutting_down)
				return -2;
			continue;
		}
		return (errno);
	}

	if (WIFEXITED(child_exit_status))
		return WEXITSTATUS(child_exit_status);

	return -1;
}
Exemplo n.º 9
0
static bool get_line( int *argc, SCHAR** argv, TEXT* stuff)
{
    /**************************************
     *
     *	g e t _ l i n e
     *
     **************************************
     *
     * Functional description
     *	Read the current line and put its pieces into an argc/argv
     *	structure.   Reads a max of MAXARGS - 1 pieces (argv [0] is
     *	unused), and a max of MAXSTUFF characters, at which point
     *
     **************************************/
    TEXT msg[MSG_LEN];

    SRVRMGR_msg_get(MSG_PROMPT, msg);
    printf("%s ", msg);		// "FBMGR> "

    //if (sw_service_gsec)
    //	putc ('\001', stdout);

    fflush(stdout);
    *argc = 1;
    TEXT* cursor = stuff;
    USHORT count = MAXSTUFF - 1;
    bool first = true;

    // for each input character, if it's white space (or any non-printable,
    // non-newline for that matter), ignore it; if it's a newline, we're
    // done; otherwise, put it in the current argument

    while (*argc < MAXARGS && count > 0)
    {
        TEXT c = getc(stdin);
        if (c > ' ' && c <= '~')
        {
            // note that the first argument gets a '-' appended to the front to fool
            // the switch checker into thinking it came from the command line

            for (argv[(*argc)++] = cursor; count > 0; count--)
            {
                if (first)
                {
                    first = false;
                    if (c != '?')
                    {
                        *cursor++ = '-';
                        count--;
                    }
                }
                *cursor++ = c;
                c = getc(stdin);
                if (c <= ' ' || c > '~')
                    break;
            }
            *cursor++ = '\0';
            count--;
        }
        if (c == '\n')
            break;
        if (c == EOF)
        {
            if (SYSCALL_INTERRUPTED(errno))
            {
                errno = 0;
                continue;
            }
            return true;
        }
    }

    *cursor = '\0';
    return false;
}
Exemplo n.º 10
0
static int nextchar()
{
/**************************************
 *
 *	n e x t c h a r
 *
 **************************************
 *
 * Functional description
 *	Get the next character from the input stream.
 *
 **************************************/
	SSHORT c;

/* mark the end of the buffer */

	const char* const end = DDL_buffer + sizeof(DDL_buffer);

/* If there isn't anything floating around, get a new line */

	while (!(c = *DDL_char++)) {
		DDL_char = DDL_buffer;
		if (dudleyGlob.DDL_interactive) {
			printf("%s", dudleyGlob.DDL_prompt);
			if (dudleyGlob.DDL_service)
				putc('\001', stdout);
			fflush(stdout);
		}
		while (c = getc(input_file)) {
			if (c == EOF && SYSCALL_INTERRUPTED(errno)) {
				errno = 0;
				continue;
			}
			if (c == EOF)
				break;
			if (DDL_char < end)
				*DDL_char++ = c;
			else
				DDL_err(279);
				/* msg 279: line too SLONG */
			if (c == '\n')
				break;
		}
		*DDL_char = 0;
		if (c == EOF && DDL_char == DDL_buffer) {
#ifdef UNIX
			if (dudleyGlob.DDL_interactive)
				printf("\n");
#endif
			dudleyGlob.DDL_eof = true;
			return EOF;
		}
		DDL_char = DDL_buffer;
		fputs(DDL_buffer, trace_file);
	}

	dudleyGlob.DDL_token.tok_position++;
	if (c == '\n') {
		++dudleyGlob.DDL_line;
#if (defined WIN_NT)
		/* need to account for extra linefeed on newline */

		dudleyGlob.DDL_token.tok_position++;
#endif
	}

	return c;
}