// -*- c++ -*-
//------------------------------------------------------------------------------
//                            SigSet.h
//------------------------------------------------------------------------------
//  Copyright (c) 1997 by Vladislav Grinchenko
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//------------------------------------------------------------------------------
#ifndef _SigSet_h
#define _SigSet_h

// System includes
//
#include <signal.h>
#include <errno.h>

namespace ASSA {

/** @file SigSet.h 

SigSet is a wrapper for UNIX sigset_t structure.

providing all manipulators on this structure as well.

Conversoin operator that converts <tt>SigSet</tt> to a pointer to the
internal <tt>sigset_t</tt> data member for direct use with C-library
functions can be used as:

<pre>
   SigSet  source;
   sigset_t*  targetp;

   targetp = source;
</pre>

Because <tt>lvalue</tt> is expected to be <tt>sigset_t*</tt>, and there is
a conversion operator defined for <tt>SigSet</tt>, the conversion will
happen automatically.
<p>
Another example would be to use it in conjunction with <tt>struct sigaction<tt>:

<pre>
   struct sigaction action;
   SigSet siganls_to_block;

   // manipulat signal set in some meaningful way

   action.sa_mask = *signals_to_block;
</pre>
*/

class SigSet
{
public:
	/** Default constructor creates SigSet object with
	    an empty signal set. 
	*/
	SigSet();

	/** Copy constructor from <tt>source_</tt>.
	 */
	SigSet(sigset_t* source_);
	
	/** Destructor
	 */
	~SigSet();

	/** This function initializes a signal set to be empty,
	    no signals in it.

	    @return 0 on success, -1 on error, with errno set to
	    error number.
	*/
	int empty (void);

	/** This function initializes a signal set to be full;
	    all the signals defined by POSIX will be in the set.

	    @return 0 on success, -1 on error, with errno set to
	    error number.
	*/
	int fill(void);

	/** This function adds the signal numbered <tt>signo_</tt>
	    to the set.

	    @return 0 on success, -1 on error, with errno set to
	    error number.
	*/
	int add(int signo_);

	/** This function removes the signal <tt>signo_</tt> from
	    the set.
	    @return 0 on success, -1 on error, with errno set to
	    error number.
	*/
	int del(int signo_);

	/** Use this function to tell whether the signal <tt>signo_</tt>
	    is in the set.
	    @return 0 on success, -1 on error, with errno set to
	    error number.
	*/
	int is_member(int signo_);

	/** Conversion operator to <tt>sigset_t</tt> structure.
	    @return pointer to the internal <tt>sigset_t</tt> structure.
	 */
	operator sigset_t *();

private:
	/** POSIX signal set */
	sigset_t m_sigset; 
};

inline
SigSet::
SigSet() { 	(int) sigemptyset(&m_sigset); }

inline
SigSet::
SigSet(sigset_t* s_) { m_sigset = *s_; }

inline 
SigSet::
~SigSet() { /* no-op */ }

inline int
SigSet::
empty(void) { return sigemptyset(&m_sigset); }

inline int
SigSet::
fill(void) { return sigfillset(&m_sigset); }

inline int
SigSet::
add(int signo_) { return sigaddset(&m_sigset,signo_); }

inline int
SigSet::
del(int signo_) { return sigdelset(&m_sigset,signo_); }

inline int
SigSet::
is_member(int signo_) { return sigismember(&m_sigset,signo_); }

inline 
SigSet::
operator sigset_t *() {	return &m_sigset; }

} // end namespace ASSA

#endif /* _SigSet_h */
