#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "gskerrno.h"
/**
* gsk_errno_is_ignorable:
* @errno_value: errno value.
*
* Determine whether an errno code is insignificant.
*
* returns: whether the error is a transient ignorable error.
*/
gboolean
gsk_errno_is_ignorable (int errno_value)
{
#ifdef EWOULDBLOCK
if (errno_value == EWOULDBLOCK)
return TRUE;
#endif
return errno_value == EINTR || errno_value == EAGAIN;
}
/**
* gsk_errno_from_fd:
* @fd: a file descriptor.
*
* Query the file descriptor for the last error which occurred on it.
*
* returns: the errno code for the last error on the file descriptor.
*/
int
gsk_errno_from_fd (int fd)
{
socklen_t size_int = sizeof (int);
int value = EINVAL;
if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &value, &size_int) < 0)
{
/* Note: this behavior is vaguely hypothetically broken,
* in terms of ignoring getsockopt's error;
* however, this shouldn't happen, and EINVAL is ok if it does.
* Furthermore some broken OS's return an error code when
* fetching SO_ERROR!
*/
return value;
}
return value;
}
/* --- "Too Many Open Files" Handling --- */
static void
fd_creation_failed_default_handler (gboolean system_wide)
{
if (system_wide)
g_error ("too many open files on system");
else
g_error ("too many open files in this process (pid=%u)", (guint) getpid ());
}
static GskErrnoFdCreateFailedFunc fd_creation_failed_handler
= fd_creation_failed_default_handler;
/* ENFILE = too many files open in system
EMFILE = too many files open in process */
void gsk_errno_fd_creation_failed (void)
{
int e = errno;
if (e == ENFILE || e == EMFILE)
{
if (fd_creation_failed_handler)
(*fd_creation_failed_handler) (e == ENFILE);
errno = e;
}
}
void gsk_errno_fd_creation_failed_errno (int e)
{
if (e == ENFILE || e == EMFILE)
{
if (fd_creation_failed_handler)
(*fd_creation_failed_handler) (e == ENFILE);
}
}
void
gsk_errno_trap_fd_creation_failed (GskErrnoFdCreateFailedFunc func)
{
fd_creation_failed_handler = func;
}
syntax highlighted by Code2HTML, v. 0.9.1