/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "primpl.h"

#include <signal.h>
#include <unistd.h>
#include <memory.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <errno.h>

/*
 * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or
 * PRInt32* pointer to a _PRSockLen_t* pointer.
 */
#define _PRSockLen_t int

/*
** Global lock variable used to bracket calls into rusty libraries that
** aren't thread safe (like libc, libX, etc).
*/
static PRLock *_pr_rename_lock = NULL;
static PRMonitor *_pr_Xfe_mon = NULL;

/*
 * Variables used by the GC code, initialized in _MD_InitSegs().
 * _pr_zero_fd should be a static variable.  Unfortunately, there is
 * still some Unix-specific code left in function PR_GrowSegment()
 * in file memory/prseg.c that references it, so it needs
 * to be a global variable for now.
 */
PRInt32 _pr_zero_fd = -1;
static PRLock *_pr_md_lock = NULL;

sigset_t timer_set;

void _PR_UnixInit()
{
	struct sigaction sigact;
	int rv;

	sigemptyset(&timer_set);

	sigact.sa_handler = SIG_IGN;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	rv = sigaction(SIGPIPE, &sigact, 0);
	PR_ASSERT(0 == rv);

	_pr_rename_lock = PR_NewLock();
	PR_ASSERT(NULL != _pr_rename_lock);
	_pr_Xfe_mon = PR_NewMonitor();
	PR_ASSERT(NULL != _pr_Xfe_mon);
}

/*
 *-----------------------------------------------------------------------
 *
 * PR_Now --
 *
 *     Returns the current time in microseconds since the epoch.
 *     The epoch is midnight January 1, 1970 GMT.
 *     The implementation is machine dependent.  This is the Unix
 *     implementation.
 *     Cf. time_t time(time_t *tp)
 *
 *-----------------------------------------------------------------------
 */

PR_IMPLEMENT(PRTime)
PR_Now(void)
{
	struct timeval tv;
	PRInt64 s, us, s2us;

	GETTIMEOFDAY(&tv);
	LL_I2L(s2us, PR_USEC_PER_SEC);
	LL_I2L(s, tv.tv_sec);
	LL_I2L(us, tv.tv_usec);
	LL_MUL(s, s, s2us);
	LL_ADD(s, s, us);
	return s;
}

PRIntervalTime
_PR_UNIX_GetInterval()
{
	struct timeval time;
	PRIntervalTime ticks;

	(void)GETTIMEOFDAY(&time);  /* fallicy of course */
	ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
	ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC;  /* so's that */
	return ticks;
}  /* _PR_SUNOS_GetInterval */

PRIntervalTime _PR_UNIX_TicksPerSecond()
{
	return 1000;  /* this needs some work :) */
}

/************************************************************************/

/*
** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread
** safe.  Unfortunately, neither is mozilla. To make these programs work
** in a pre-emptive threaded environment, we need to use a lock.
*/

void PR_XLock()
{
	PR_EnterMonitor(_pr_Xfe_mon);
}

void PR_XUnlock()
{
	PR_ExitMonitor(_pr_Xfe_mon);
}

PRBool PR_XIsLocked()
{
	return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE;
}

void PR_XWait(int ms)
{
	PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms));
}

void PR_XNotify(void)
{
	PR_Notify(_pr_Xfe_mon);
}

void PR_XNotifyAll(void)
{
	PR_NotifyAll(_pr_Xfe_mon);
}

#if !defined(BEOS)
#ifdef HAVE_BSD_FLOCK

#include <sys/file.h>

PR_IMPLEMENT(PRStatus)
_MD_LOCKFILE (PRInt32 f)
{
	PRInt32 rv;
	rv = flock(f, LOCK_EX);
	if (rv == 0)
		return PR_SUCCESS;
	_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
	return PR_FAILURE;
}

PR_IMPLEMENT(PRStatus)
_MD_TLOCKFILE (PRInt32 f)
{
	PRInt32 rv;
	rv = flock(f, LOCK_EX|LOCK_NB);
	if (rv == 0)
		return PR_SUCCESS;
	_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
	return PR_FAILURE;
}

PR_IMPLEMENT(PRStatus)
_MD_UNLOCKFILE (PRInt32 f)
{
	PRInt32 rv;
	rv = flock(f, LOCK_UN);
	if (rv == 0)
		return PR_SUCCESS;
	_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
	return PR_FAILURE;
}
#else

PR_IMPLEMENT(PRStatus)
_MD_LOCKFILE (PRInt32 f)
{
	PRInt32 rv;
	rv = lockf(f, F_LOCK, 0);
	if (rv == 0)
		return PR_SUCCESS;
	_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
	return PR_FAILURE;
}

PR_IMPLEMENT(PRStatus)
_MD_TLOCKFILE (PRInt32 f)
{
	PRInt32 rv;
	rv = lockf(f, F_TLOCK, 0);
	if (rv == 0)
		return PR_SUCCESS;
	_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
	return PR_FAILURE;
}

PR_IMPLEMENT(PRStatus)
_MD_UNLOCKFILE (PRInt32 f)
{
	PRInt32 rv;
	rv = lockf(f, F_ULOCK, 0);
	if (rv == 0)
		return PR_SUCCESS;
	_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
	return PR_FAILURE;
}
#endif

PR_IMPLEMENT(PRStatus)
  _MD_GETHOSTNAME (char *name, PRUint32 namelen)
{
    PRIntn rv;

    rv = gethostname(name, namelen);
    if (0 == rv) {
		return PR_SUCCESS;
    }
	_PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO());
    return PR_FAILURE;
}

#endif
