#ifndef __SAL_SYSLIMITS_DEFINES_HEADER
#define __SAL_SYSLIMITS_DEFINES_HEADER

/*
 * libsal/syslimit/defines.h
 * Define availability for system limits
 */

/*
 * Author(s)
 * 
 * Stuart Herbert (S.Herbert@sheffield.ac.uk)
 * Academic Computing Services
 * University of Sheffield
 */

#include <SETUP/autoconf.h>

/*
 * STEP ONE : determine what interfaces are available
 * 
 * For this, we will cheat, and ask the person compiling the software
 * to supply us with this information.
 *
 * To add support for a new limit interface, simply insert the lines
 * to include the appropriate header files, and then wrap it in a
 * #ifdef HAS_NEW_INTERFACE / #endif clause.
 */
 
#if	HAS_BSD_LIMITS | IS_BSD
#include <sys/time.h>
#ifdef	IS_HPUX
#include <libsal/syslimit/hpux.h>
#endif /* IS_HPUX */
#ifdef	IS_UNICOS
#include <time.h>
#include <sys/category.h>
#endif /* IS_UNICOS */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>

/* These work as follows :
 * 
 * SAL_LIMIT_MAXLIMIT / SAL_CPU_DIVTOSEC will convert the limit into
 * seconds.
 * 
 * SAL_LIMIT_MAXLIMIT / SAL_BLOCK_DIVTOBYTE will convert the limit
 * into bytes.
 */

#define SAL_CPU_DIVTOSEC 1
#define SAL_BLOCK_DIVTOBYTE 1

#define SAL_LIMIT_INFINITY RLIM_INFINITY
#define SAL_LIMIT_GTIALLOWED 1

#endif /* HAS_BSD_LIMITS | IS_BSD */

#ifdef	HAS_SYSV_LIMITS
#include <ulimit.h>
#endif

#ifdef	HAS_LIMIT_LIMITS
#include <time.h>
#include <sys/category.h>
#include <sys/resource.h>

#define SAL_LIMIT_INFINITY RLIM_INFINITY
#define SAL_LIMIT_GTIALLOWED 0

#endif /* HAS_LIMIT_LIMITS */

#ifdef	HAS_NICE_LIMITS
#include <unistd.h>
#endif /* HAS_NICE_LIMITS */

/*
 * STEP TWO : We test for the presence of every known resource limit.  If
 * the limit is present, we #define a symbol to indicate this.
 * 
 * Yes, this is the long way to do it, but at least it works, and is easy
 * to maintain.
 */

#if	HAS_BSD_LIMITS | IS_BSD

#ifdef RLIMIT_CPU
#define SAL_LIMIT_CPU_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_CPU_RLIMIT_PRESENT 0
#define RLIMIT_CPU 255
#endif

#ifdef RLIMIT_FSIZE
#define SAL_LIMIT_FSIZE_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_FSIZE_RLIMIT_PRESENT 0
#define RLIMIT_FSIZE 255
#endif

#ifdef RLIMIT_DATA
#define SAL_LIMIT_DATA_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_DATA_RLIMIT_PRESENT 0
#define RLIMIT_DATA 255
#endif

#ifdef RLIMIT_STACK
#define SAL_LIMIT_STACK_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_STACK_RLIMIT_PRESENT 0
#define RLIMIT_STACK 255
#endif

#ifdef RLIMIT_CORE
#define SAL_LIMIT_CORE_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_CORE_RLIMIT_PRESENT 0
#define RLIMIT_CORE 255
#endif

#ifdef RLIMIT_RSS
#define SAL_LIMIT_RSS_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_RSS_RLIMIT_PRESENT 0
#define RLIMIT_RSS 255
#endif

#ifdef RLIMIT_MEMLOCK
#define SAL_LIMIT_MEMLOCK_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_MEMLOCK_RLIMIT_PRESENT 0
#define RLIMIT_MEMLOCK 255
#endif

#ifdef RLIMIT_NPROC
#define SAL_LIMIT_NPROC_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_NPROC_RLIMIT_PRESENT 0
#define RLIMIT_NPROC 255
#endif

#ifdef RLIMIT_OFILE
#define SAL_LIMIT_OFILE_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_OFILE_RLIMIT_PRESENT 0
#define RLIMIT_OFILE 255
#endif

#ifdef RLIMIT_NOFILE
#define SAL_LIMIT_NOFILE_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_NOFILE_RLIMIT_PRESENT 0
#define RLIMIT_NOFILE 255
#endif

#ifdef RLIMIT_VMEM
#define SAL_LIMIT_VMEM_RLIMIT_PRESENT 1
#else
#define SAL_LIMIT_VMEM_RLIMIT_PRESENT 0
#define RLIMIT_VMEM 255
#endif

#else /* HAS_BSD_LIMITS | IS_BSD */

#define RLIMIT_CPU				255
#define SAL_LIMIT_CPU_RLIMIT_PRESENT		0
#define RLIMIT_FSIZE				255
#define SAL_LIMIT_FSIZE_RLIMIT_PRESENT		0
#define RLIMIT_DATA				255
#define SAL_LIMIT_FSIZE_RLIMIT_PRESENT		0
#define RLIMIT_STACK				255
#define SAL_LIMIT_STACK_RLIMIT_PRESENT		0
#define RLIMIT_CORE				255
#define SAL_LIMIT_CORE_RLIMIT_PRESENT		0
#define RLIMIT_RSS				255
#define SAL_LIMIT_RSS_RLIMIT_PRESENT		0
#define RLIMIT_MEMLOCK				255
#define SAL_LIMIT_MEMLOCK_RLIMIT_PRESENT	0
#define RLIMIT_NPROC				255
#define SAL_LIMIT_NPROC_RLIMIT_PRESENT		0
#define RLIMIT_OFILE				255
#define SAL_LIMIT_OFILE_RLIMIT_PRESENT		0
#define RLIMIT_NOFILE				255
#define SAL_LIMIT_NOFILE_RLIMIT_PRESENT		0
#define RLIMIT_VMEM				255
#define SAL_LIMIT_VMEM_RLIMIT_PRESENT		0

#endif /* HAS_BSD_LIMITS | IS_BSD */

#if	HAS_LIMIT_LIMITS | IS_UNICOS

#ifdef L_CPU
#define SAL_LIMIT_CORE_LIMIT_PRESENT 1
#define SAL_LIMIT_RCORE_LIMIT_PRESENT 1
#else
#define SAL_LIMIT_CORE_LIMIT_PRESENT 0
#define SAL_LIMIT_RCORE_LIMIT_PRESENT 0
#define L_CPU 255
#endif

#ifdef L_CORE
#define SAL_LIMIT_CORE_LIMIT_PRESENT 1
#else
#define SAL_LIMIT_CORE_LIMIT_PRESENT 0
#define L_CORE 255
#endif

#ifdef L_MEM
#define SAL_LIMIT_VMEM_LIMIT_PRESENT 1
#define SAL_LIMIT_RVMEM_LIMIT_PRESENT 1
#else
#define SAL_LIMIT_VMEM_LIMIT_PRESENT 0
#define SAL_LIMIT_RVMEM_LIMIT_PRESENT 0
#define L_MEM 255
#endif

#ifdef L_FSBLK
#define SAL_LIMIT_FSIZE_LIMIT_PRESENT 1
#define SAL_LIMIT_RFSIZE_LIMIT_PRESENT 1
#else
#define SAL_LIMIT_FSIZE_LIMIT_PRESENT 0
#define SAL_LIMIT_RFSIZE_LIMIT_PRESENT 0
#define L_FSBLK 0
#endif

#else /* HAS_LIMIT_LIMITS | IS_UNICOS */

#define L_CPU		255
#define SAL_LIMIT_CPU_LIMIT_PRESENT 0
#define SAL_LIMIT_RCPU_LIMIT_PRESENT 0
#define L_CORE		255
#define SAL_LIMIT_CORE_LIMIT_PRESENT 0
#define SAL_LIMIT_RCORE_LIMIT_PRESENT 0
#define L_MEM		255
#define SAL_LIMIT_VMEM_LIMIT_PRESENT 0
#define SAL_LIMIT_RVMEM_LIMIT_PRESENT 0
#define L_FSBLK		255
#define SAL_LIMIT_FSIZE_LIMIT_PRESENT 0
#define SAL_LIMIT_RFSIZE_LIMIT_PRESENT 0
#define C_PROC		0
#define C_JOB		0

#endif /* HAS_LIMIT_LIMITS | IS_UNICOS */

#if	HAS_NICE_LIMITS
#define	SAL_LIMIT_NICE_NICE_PRESENT 1
#else
#define SAL_LIMIT_NICE_NICE_PRESENT 0
#endif
#define NICE_NICE 0

#if	HAS_SETPRIORITY_LIMITS
#define SAL_LIMIT_NICE_SETPRIORITY_PRESENT 1
#else
#define SAL_LIMIT_NICE_SETPRIORITY_PRESENT 0
#endif
#define SETPRIORITY_NICE 0

/*
 * a - a short string with the limit's name
 * b - the SAL_LIMIT_ macro name for this limit
 * c - is the limit by size, or by time?
 * d - which limit interface to use
 * e - what is the per-job/per-process ID the interface recognises?
 * f - what is the limit ID the interface recognises for this limit?
 * g - is this limit inherited by child processes?
 * h - a text description of the limit
 */

#define START_LIMTBL \
{ NULL, SAL_LIMIT_START, 0, 0, 0, 0, 0, 0, NULL }

#define MAKE_LIMTBL_ENTRY(a,b,c,d,e,f,g,h) \
{ a, b, c, SAL_LIMIT_USES_ ## d, e, f, b ## _ ## d ## _PRESENT, g, h }

#define END_LIMTBL { NULL, SAL_LIMIT_END, 0, 0, 0, 0, 0, 0, NULL }

#endif /* __SAL_SYSLIMITS_DEFINES_HEADER */
