/*
 * This file was generated automatically by ExtUtils::ParseXS version 3.45 from the
 * contents of FD.xs. Do not edit this file, edit FD.xs instead.
 *
 *    ANY CHANGES MADE HERE WILL BE LOST!
 *
 */

#line 1 "FD.xs"
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"

#include "const-c.inc"
#include <fcntl.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <poll.h>

#include <sys/time.h>

#if defined(IO_FD_OS_DARWIN) || defined(IO_FD_OS_BSD)
#include <sys/event.h>
#endif

#include <sys/stat.h>

//Read from an fd until eof or error condition
//Returns SV containing all the data
// AKA "slurp";
SV * slurp(pTHX_ int fd, int read_size){
	SV* buffer;
	char *buf;
	int ret;
	int len=0;
	buffer=newSV(read_size);
	
	do {
		SvGROW(buffer, len+read_size);	//Grow the buffer if required
		buf=SvPVX(buffer);		//Get pointer to memory.. 
		ret=read(fd, buf+len, read_size);	//Do the read,offset to current traked len

		if(ret>=0){
			len+=ret;		//track total length
			buf=SvPVX(buffer);
			buf[len]='\0';		//Add null for shits and giggles
		}
		else{
			//break;
			//fprintf(stderr, "ERROR IN slurp\n");
			return &PL_sv_undef;
		}

	}
	while(ret>0);

	SvPOK_on(buffer);	//Make it a string
	SvCUR_set(buffer,len);	//Set the length
	sv_2mortal(buffer);	//Decrement ref count
	return buffer;
}


#if defined(IO_FD_OS_DARWIN)|| defined(IO_FD_OS_BSD)
#define IO_FD_ATIME atime=buf.st_atimespec.tv_sec+buf.st_atimespec.tv_nsec*1e-9;
#define IO_FD_MTIME mtime=buf.st_mtimespec.tv_sec+buf.st_mtimespec.tv_nsec*1e-9;
#define IO_FD_CTIME ctime=buf.st_ctimespec.tv_sec+buf.st_ctimespec.tv_nsec*1e-9;
#endif

#if defined(IO_FD_OS_LINUX)
#define IO_FD_ATIME atime=buf.st_atim.tv_sec+buf.st_atim.tv_nsec*1e-9;
#define IO_FD_MTIME mtime=buf.st_mtim.tv_sec+buf.st_mtim.tv_nsec*1e-9;
#define IO_FD_CTIME ctime=buf.st_ctim.tv_sec+buf.st_ctim.tv_nsec*1e-9;
#endif

#if defined(IO_FD_OS_DARWIN)
#define KEVENT kevent64
#define KEVENT_S struct kevent64_s
#endif
#if defined(IO_FD_OS_BSD)
#define KEVENT kevent
#define KEVENT_S struct kevent
#endif



#line 92 "FD.c"
#ifndef PERL_UNUSED_VAR
#  define PERL_UNUSED_VAR(var) if (0) var = var
#endif

#ifndef dVAR
#  define dVAR		dNOOP
#endif


/* This stuff is not part of the API! You have been warned. */
#ifndef PERL_VERSION_DECIMAL
#  define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
#endif
#ifndef PERL_DECIMAL_VERSION
#  define PERL_DECIMAL_VERSION \
	  PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
#endif
#ifndef PERL_VERSION_GE
#  define PERL_VERSION_GE(r,v,s) \
	  (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
#endif
#ifndef PERL_VERSION_LE
#  define PERL_VERSION_LE(r,v,s) \
	  (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
#endif

/* XS_INTERNAL is the explicit static-linkage variant of the default
 * XS macro.
 *
 * XS_EXTERNAL is the same as XS_INTERNAL except it does not include
 * "STATIC", ie. it exports XSUB symbols. You probably don't want that
 * for anything but the BOOT XSUB.
 *
 * See XSUB.h in core!
 */


/* TODO: This might be compatible further back than 5.10.0. */
#if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1)
#  undef XS_EXTERNAL
#  undef XS_INTERNAL
#  if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING)
#    define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
#    define XS_INTERNAL(name) STATIC XSPROTO(name)
#  endif
#  if defined(__SYMBIAN32__)
#    define XS_EXTERNAL(name) EXPORT_C XSPROTO(name)
#    define XS_INTERNAL(name) EXPORT_C STATIC XSPROTO(name)
#  endif
#  ifndef XS_EXTERNAL
#    if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
#      define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__)
#      define XS_INTERNAL(name) STATIC void name(pTHX_ CV* cv __attribute__unused__)
#    else
#      ifdef __cplusplus
#        define XS_EXTERNAL(name) extern "C" XSPROTO(name)
#        define XS_INTERNAL(name) static XSPROTO(name)
#      else
#        define XS_EXTERNAL(name) XSPROTO(name)
#        define XS_INTERNAL(name) STATIC XSPROTO(name)
#      endif
#    endif
#  endif
#endif

/* perl >= 5.10.0 && perl <= 5.15.1 */


/* The XS_EXTERNAL macro is used for functions that must not be static
 * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL
 * macro defined, the best we can do is assume XS is the same.
 * Dito for XS_INTERNAL.
 */
#ifndef XS_EXTERNAL
#  define XS_EXTERNAL(name) XS(name)
#endif
#ifndef XS_INTERNAL
#  define XS_INTERNAL(name) XS(name)
#endif

/* Now, finally, after all this mess, we want an ExtUtils::ParseXS
 * internal macro that we're free to redefine for varying linkage due
 * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use
 * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to!
 */

#undef XS_EUPXS
#if defined(PERL_EUPXS_ALWAYS_EXPORT)
#  define XS_EUPXS(name) XS_EXTERNAL(name)
#else
   /* default to internal */
#  define XS_EUPXS(name) XS_INTERNAL(name)
#endif

#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)

/* prototype to pass -Wmissing-prototypes */
STATIC void
S_croak_xs_usage(const CV *const cv, const char *const params);

STATIC void
S_croak_xs_usage(const CV *const cv, const char *const params)
{
    const GV *const gv = CvGV(cv);

    PERL_ARGS_ASSERT_CROAK_XS_USAGE;

    if (gv) {
        const char *const gvname = GvNAME(gv);
        const HV *const stash = GvSTASH(gv);
        const char *const hvname = stash ? HvNAME(stash) : NULL;

        if (hvname)
	    Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params);
        else
	    Perl_croak_nocontext("Usage: %s(%s)", gvname, params);
    } else {
        /* Pants. I don't think that it should be possible to get here. */
	Perl_croak_nocontext("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
    }
}
#undef  PERL_ARGS_ASSERT_CROAK_XS_USAGE

#define croak_xs_usage        S_croak_xs_usage

#endif

/* NOTE: the prototype of newXSproto() is different in versions of perls,
 * so we define a portable version of newXSproto()
 */
#ifdef newXS_flags
#define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
#else
#define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
#endif /* !defined(newXS_flags) */

#if PERL_VERSION_LE(5, 21, 5)
#  define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file)
#else
#  define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b)
#endif

#line 236 "FD.c"

/* INCLUDE:  Including 'const-xs.inc' from 'FD.xs' */


XS_EUPXS(XS_IO__FD_constant); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_constant)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
#line 4 "./const-xs.inc"
#ifdef dXSTARG
	dXSTARG; /* Faster if we have it.  */
#else
	dTARGET;
#endif
	STRLEN		len;
        int		type;
	/* IV		iv;	Uncomment this if you need to return IVs */
	/* NV		nv;	Uncomment this if you need to return NVs */
	/* const char	*pv;	Uncomment this if you need to return PVs */
#line 261 "FD.c"
	SV *	sv = ST(0)
;
	const char *	s = SvPV(sv, len);
#line 18 "./const-xs.inc"
	type = constant(aTHX_ s, len);
      /* Return 1 or 2 items. First is error message, or undef if no error.
           Second, if present, is found value */
        switch (type) {
        case PERL_constant_NOTFOUND:
          sv =
	    sv_2mortal(newSVpvf("%s is not a valid IO::FD macro", s));
          PUSHs(sv);
          break;
        case PERL_constant_NOTDEF:
          sv = sv_2mortal(newSVpvf(
	    "Your vendor has not defined IO::FD macro %s, used",
				   s));
          PUSHs(sv);
          break;
	/* Uncomment this if you need to return IVs
        case PERL_constant_ISIV:
          EXTEND(SP, 2);
          PUSHs(&PL_sv_undef);
          PUSHi(iv);
          break; */
	/* Uncomment this if you need to return NOs
        case PERL_constant_ISNO:
          EXTEND(SP, 2);
          PUSHs(&PL_sv_undef);
          PUSHs(&PL_sv_no);
          break; */
	/* Uncomment this if you need to return NVs
        case PERL_constant_ISNV:
          EXTEND(SP, 2);
          PUSHs(&PL_sv_undef);
          PUSHn(nv);
          break; */
	/* Uncomment this if you need to return PVs
        case PERL_constant_ISPV:
          EXTEND(SP, 2);
          PUSHs(&PL_sv_undef);
          PUSHp(pv, strlen(pv));
          break; */
	/* Uncomment this if you need to return PVNs
        case PERL_constant_ISPVN:
          EXTEND(SP, 2);
          PUSHs(&PL_sv_undef);
          PUSHp(pv, iv);
          break; */
	/* Uncomment this if you need to return SVs
        case PERL_constant_ISSV:
          EXTEND(SP, 2);
          PUSHs(&PL_sv_undef);
          PUSHs(sv);
          break; */
	/* Uncomment this if you need to return UNDEFs
        case PERL_constant_ISUNDEF:
          break; */
	/* Uncomment this if you need to return UVs
        case PERL_constant_ISUV:
          EXTEND(SP, 2);
          PUSHs(&PL_sv_undef);
          PUSHu((UV)iv);
          break; */
	/* Uncomment this if you need to return YESs
        case PERL_constant_ISYES:
          EXTEND(SP, 2);
          PUSHs(&PL_sv_undef);
          PUSHs(&PL_sv_yes);
          break; */
        default:
          sv = sv_2mortal(newSVpvf(
	    "Unexpected return type %d while processing IO::FD macro %s, used",
               type, s));
          PUSHs(sv);
        }
#line 338 "FD.c"
	PUTBACK;
	return;
    }
}


/* INCLUDE: Returning to 'FD.xs' from 'const-xs.inc' */


XS_EUPXS(XS_IO__FD_socket); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_socket)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "sock, af, type, proto");
    {
	SV*	sock = ST(0)
;
	int	af = (int)SvIV(ST(1))
;
	int	type = (int)SvIV(ST(2))
;
	int	proto = (int)SvIV(ST(3))
;
#line 97 "FD.xs"
			int fd;
			int s;
#line 366 "FD.c"
	SV *	RETVAL;
#line 100 "FD.xs"
			s=socket(af, type, proto);

			//Set error variable...
			if(s<0){

				RETVAL=&PL_sv_undef;
			}
			else{
				RETVAL=newSViv(s);
				if(SvOK(sock)){
					sv_setiv(sock,s);
				}
				else {
					sock=newSViv(s);
				}
			}

#line 386 "FD.c"
	sv_setsv_mg(ST(0), sock);
	SvSETMAGIC(ST(0));
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_listen); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_listen)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "listener, backlog");
    {
	int	listener = (int)SvIV(ST(0))
;
	int	backlog = (int)SvIV(ST(1))
;
	SV *	RETVAL;
#line 133 "FD.xs"
		int ret;

#line 411 "FD.c"
#line 137 "FD.xs"
		ret=listen(listener, backlog);

		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret+1);
		}

#line 422 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_accept); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_accept)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "new_fd, listen_fd");
    {
	SV*	new_fd = ST(0)
;
	int	listen_fd = (int)SvIV(ST(1))
;
#line 158 "FD.xs"
                        struct sockaddr *packed_addr;
                        int ret;
			SV *addr=newSV(sizeof(struct sockaddr));
			struct sockaddr *buf=(struct sockaddr *)SvPVX(addr);
			unsigned int len=sizeof(struct sockaddr);



#line 450 "FD.c"
	SV *	RETVAL;
#line 167 "FD.xs"
                ret=accept(listen_fd, buf, &len);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else {
			SvPOK_on(addr);
			SvCUR_set(addr,sizeof(struct sockaddr));
			RETVAL=addr;
			if(SvOK(new_fd)){
				sv_setiv(new_fd, ret);		
			}
			else{
				new_fd=newSViv(ret);
			}
		}


#line 470 "FD.c"
	sv_setsv_mg(ST(0), new_fd);
	SvSETMAGIC(ST(0));
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_connect); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_connect)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "fd, address");
    {
	SV*	fd = ST(0)
;
	SV *	address = ST(1)
;
#line 196 "FD.xs"
		int ret;
		int len=SvOK(address)?SvCUR(address):0;
		struct sockaddr *addr=(struct sockaddr *)SvPVX(address);

#line 496 "FD.c"
	SV *	RETVAL;
#line 202 "FD.xs"
		ret=connect(SvIVX(fd),addr,len);
		//fprintf(stderr,"CONNECT: %d\n",ret);
		if(ret<0){
			RETVAL=&PL_sv_undef;	
		}
		else{
			RETVAL=newSViv(ret+1);
		}
#line 507 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_sysopen); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_sysopen)
{
    dVAR; dXSARGS;
    if (items < 3)
       croak_xs_usage(cv,  "fd, path, mode, ...");
    {
	SV*	fd = ST(0)
;
	char *	path = (char *)SvPV_nolen(ST(1))
;
	int	mode = (int)SvIV(ST(2))
;
#line 223 "FD.xs"
			int f;
                	int permissions=0666;	//Default if not provided

#line 532 "FD.c"
	SV *	RETVAL;
#line 227 "FD.xs"
			if(items==4){
				permissions=SvIV(ST(3));
			}
			f=open(path, mode, permissions);
			if(f<0){
				RETVAL=&PL_sv_undef;
			}
			else{
				RETVAL=newSViv(f);
				if(SvOK(fd)){
					sv_setiv(fd,f);
				}
				else {
					fd= newSViv(f);
				}
			}

#line 552 "FD.c"
	sv_setsv_mg(ST(0), fd);
	SvSETMAGIC(ST(0));
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_sysopen4); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_sysopen4)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "fd, path, mode, permissions");
    {
	int	fd = (int)SvIV(ST(0))
;
	char *	path = (char *)SvPV_nolen(ST(1))
;
	int	mode = (int)SvIV(ST(2))
;
	int	permissions = (int)SvIV(ST(3))
;
#line 257 "FD.xs"
			int f;

#line 580 "FD.c"
	SV *	RETVAL;
#line 260 "FD.xs"
			fd=open(path, mode, permissions);
			if(fd<0){
				RETVAL=&PL_sv_undef;
			}
			else{
				RETVAL=newSViv(fd);
			}

#line 591 "FD.c"
	sv_setiv(ST(0), (IV)fd);
	SvSETMAGIC(ST(0));
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_close); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_close)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "fd");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV *	RETVAL;
#line 279 "FD.xs"
		int ret;

#line 614 "FD.c"
#line 282 "FD.xs"
		ret=close(fd);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret+1);
		}
#line 623 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_sysread); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_sysread)
{
    dVAR; dXSARGS;
    if (items < 3)
       croak_xs_usage(cv,  "fd, data, len, ...");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV*	data = ST(1)
;
	int	len = (int)SvIV(ST(2))
;
	SV *	RETVAL;
#line 305 "FD.xs"
			int ret;
			char *buf;
			int offset=0;

#line 650 "FD.c"
#line 310 "FD.xs"
			//TODO: allow unspecified len and offset

			//grow scalar to fit potental read

			if(items >=4 ){
				//len=SvIOK(ST(2))?SvIV(ST(2)):0;
				offset=SvIOK(ST(3))?SvIV(ST(3)):0;
			}

			int data_len=sv_len(data);
			int request_len;
			if(offset<0){
				offset=data_len-offset;
			}
			else{

			}
			request_len=len+offset;


			buf = SvPOK(data) ? SvGROW(data, request_len+1) : 0;

			data_len=sv_len(data);

			buf+=offset;

                        ret=read(fd, buf, len);
			if(ret<0){

				RETVAL=&PL_sv_undef;
			}
			else {
				buf[ret]='\0';
				SvCUR_set(data,ret+offset);
				RETVAL=newSViv(ret);
			}

#line 689 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_sysread3); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_sysread3)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "fd, data, len");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV*	data = ST(1)
;
	int	len = (int)SvIV(ST(2))
;
	SV *	RETVAL;
#line 361 "FD.xs"
			int ret;
			char *buf;
			int offset;

#line 716 "FD.c"
#line 366 "FD.xs"
			int data_len=SvCUR(data);


			buf = SvPOK(data) ? SvGROW(data,len+1) : 0;

			//data_len=SvPVX(data);


			ret=read(fd, buf, len);
			if(ret<0){

				RETVAL=&PL_sv_undef;
			}
			else {
				buf[ret]='\0';
				SvCUR_set(data,ret);
				RETVAL=newSViv(ret);
			}

#line 737 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_sysread4); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_sysread4)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "fd, data, len, offset");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV*	data = ST(1)
;
	int	len = (int)SvIV(ST(2))
;
	int	offset = (int)SvIV(ST(3))
;
	SV *	RETVAL;
#line 399 "FD.xs"
			int ret;
			char *buf;

#line 765 "FD.c"
#line 406 "FD.xs"
			int data_len=sv_len(data);
			int request_len;
			if(offset<0){
				offset=data_len-offset;
			}
			else{

			}
			request_len=len+offset;


			buf = SvPOK(data) ? SvGROW(data, request_len+1) : 0;

			data_len=sv_len(data);

			buf+=offset;

                        ret=read(fd, buf, len);
			if(ret<0){

				RETVAL=&PL_sv_undef;
			}
			else {
				buf[ret]='\0';
				SvCUR_set(data,ret+offset);
				RETVAL=newSViv(ret);
			}

#line 795 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_syswrite); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_syswrite)
{
    dVAR; dXSARGS;
    if (items < 2)
       croak_xs_usage(cv,  "fd, data, ...");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV*	data = ST(1)
;
	SV *	RETVAL;
#line 450 "FD.xs"
		int ret;
		char *buf;
		STRLEN max=SvCUR(data);
		int len;
		int offset;
#line 821 "FD.c"
#line 456 "FD.xs"
		if(items >=4 ){
			//length and  Offset provided
			len=SvIOK(ST(2))?SvIV(ST(2)):0;
			offset=SvIOK(ST(3))?SvIV(ST(3)):0;

		}
		else if(items == 3){
			//length provided	
			len=SvIOK(ST(2))?SvIV(ST(2)):0;
			offset=0;
		}
		else{
			//no length or offset
			len=SvCUR(data);
			offset=0;
		}


		offset=
			offset>max
				?max
				:offset;

		if((offset+len)>max){
			len=max-offset;
		}

		buf=SvPVX(data);
		buf+=offset;
		ret=write(fd, buf, len);
		if(ret<0){
			RETVAL=&PL_sv_undef;	
		}
		else{
			RETVAL=newSViv(ret);
		}

#line 860 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_syswrite2); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_syswrite2)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "fd, data");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV*	data = ST(1)
;
	SV *	RETVAL;
#line 506 "FD.xs"
		int ret;
		char *buf;
		int len;
#line 884 "FD.c"
#line 511 "FD.xs"
		len=SvPOK(data)?SvCUR(data):0;



		buf=SvPVX(data);
		ret=write(fd, buf, len);
		if(ret<0){
			RETVAL=&PL_sv_undef;	
		}
		else{
			RETVAL=newSViv(ret);
		}

#line 899 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_syswrite3); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_syswrite3)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "fd, data, len");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV*	data = ST(1)
;
	int	len = (int)SvIV(ST(2))
;
	SV *	RETVAL;
#line 537 "FD.xs"
		int ret;
		char *buf;
		STRLEN max=SvCUR(data);
		int offset=0;
#line 926 "FD.c"
#line 548 "FD.xs"
		if(len>max){
			len=max;
		}

		buf=SvPVX(data);
		ret=write(fd,buf,len);
		if(ret<0){
			RETVAL=&PL_sv_undef;	
		}
		else{
			RETVAL=newSViv(ret);
		}

#line 941 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_syswrite4); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_syswrite4)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "fd, data, len, offset");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV*	data = ST(1)
;
	int	len = (int)SvIV(ST(2))
;
	int	offset = (int)SvIV(ST(3))
;
	SV *	RETVAL;
#line 574 "FD.xs"
		int ret;
		char *buf;
		STRLEN max=SvCUR(data);
#line 969 "FD.c"
#line 583 "FD.xs"
		offset=
			offset>max
				?max
				:offset;

		if((offset+len)>max){
			len=max-offset;
		}

		buf=SvPVX(data);
		buf+=offset;
		ret=write(fd,buf,len);
		if(ret<0){
			RETVAL=&PL_sv_undef;	
		}
		else{
			RETVAL=newSViv(ret);
		}

#line 990 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_pipe); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_pipe)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "read_end, write_end");
    {
	SV*	read_end = ST(0)
;
	SV*	write_end = ST(1)
;
	SV *	RETVAL;
#line 619 "FD.xs"
		int ret;
		int fds[2];

#line 1015 "FD.c"
#line 623 "FD.xs"
		ret=pipe(fds);

		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret+1);
			if(SvOK(read_end)){
				sv_setiv(read_end, fds[0]);
			}
			else {
				read_end=newSViv(fds[0]);
			}

			if(SvOK(write_end)){
				sv_setiv(write_end,fds[1]);
			}
			else {
				write_end=newSViv(fds[1]);
			}
		}
#line 1038 "FD.c"
	sv_setsv_mg(ST(0), read_end);
	SvSETMAGIC(ST(0));
	sv_setsv_mg(ST(1), write_end);
	SvSETMAGIC(ST(1));
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_bind); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_bind)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "fd, address");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV*	address = ST(1)
;
	SV *	RETVAL;
#line 661 "FD.xs"
		int ret;
		int len=SvOK(address)?SvCUR(address):0;
		struct sockaddr *addr=(struct sockaddr *)SvPVX(address);
#line 1067 "FD.c"
#line 665 "FD.xs"
		//fprintf(stderr, "bind fd: %d\n",fd);
		//fprintf(stderr, "bind len: %d\n",len);
		ret=bind(fd, addr, len);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret+1);
		}

#line 1079 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_socketpair); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_socketpair)
{
    dVAR; dXSARGS;
    if (items != 5)
       croak_xs_usage(cv,  "fd1, fd2, domain, type, protocol");
    {
	int	fd1 = (int)SvIV(ST(0))
;
	int	fd2 = (int)SvIV(ST(1))
;
	int	domain = (int)SvIV(ST(2))
;
	int	type = (int)SvIV(ST(3))
;
	int	protocol = (int)SvIV(ST(4))
;
	SV *	RETVAL;
#line 692 "FD.xs"
		int ret;
		int fds[2];

#line 1109 "FD.c"
#line 697 "FD.xs"
		ret=socketpair(domain, type, protocol, fds);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret+1);
			fd1=fds[0];
			fd2=fds[1];
		}
#line 1120 "FD.c"
	sv_setiv(ST(0), (IV)fd1);
	SvSETMAGIC(ST(0));
	sv_setiv(ST(1), (IV)fd2);
	SvSETMAGIC(ST(1));
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_sysseek); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_sysseek)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "fd, offset, whence");
    {
	int	fd = (int)SvIV(ST(0))
;
	int	offset = (int)SvIV(ST(1))
;
	int	whence = (int)SvIV(ST(2))
;
	SV *	RETVAL;
#line 721 "FD.xs"
		int ret;

#line 1149 "FD.c"
#line 725 "FD.xs"
		ret=lseek(fd, offset,whence);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret);
		}

#line 1159 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_dup); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_dup)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "fd");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV *	RETVAL;
#line 744 "FD.xs"
		int ret;

#line 1180 "FD.c"
#line 747 "FD.xs"
		ret=dup(fd);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret);
		}

#line 1190 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_dup2); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_dup2)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "fd1, fd2");
    {
	int	fd1 = (int)SvIV(ST(0))
;
	int	fd2 = (int)SvIV(ST(1))
;
	SV *	RETVAL;
#line 768 "FD.xs"
		int ret;

#line 1213 "FD.c"
#line 771 "FD.xs"
		ret=dup2(fd1,fd2);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret);
		}

#line 1223 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_fcntl); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_fcntl)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 3)
       croak_xs_usage(cv,  "fd, cmd, arg");
    {
	int	fd = (int)SvIV(ST(0))
;
	int	cmd = (int)SvIV(ST(1))
;
	SV*	arg = ST(2)
;
	SV *	RETVAL;
#line 795 "FD.xs"
		int ret;
#line 1248 "FD.c"
#line 799 "FD.xs"
		if(SvOK(arg)){
			if(SvIOK(arg)){
				ret=fcntl(fd,cmd, SvIV(arg));
			}else if(SvPOK(arg)){
				ret=fcntl(fd,cmd,SvPVX(arg));
			}
			else {
				ret=-1;
			}
			if(ret==-1){
				RETVAL=&PL_sv_undef;
			}
			else {
				RETVAL=newSViv(ret);
			}
		}

#line 1267 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_ioctl); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_ioctl)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 3)
       croak_xs_usage(cv,  "fd, request, arg");
    {
	int	fd = (int)SvIV(ST(0))
;
	int	request = (int)SvIV(ST(1))
;
	int	arg = (int)SvIV(ST(2))
;
	SV *	RETVAL;
#line 836 "FD.xs"
#line 1291 "FD.c"
#line 837 "FD.xs"
		RETVAL=&PL_sv_undef;

#line 1295 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_getsockopt); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_getsockopt)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "fd, level, option");
    {
	int	fd = (int)SvIV(ST(0))
;
	int	level = (int)SvIV(ST(1))
;
	int	option = (int)SvIV(ST(2))
;
	SV *	RETVAL;
#line 851 "FD.xs"
		int ret;
		char * buf;
		unsigned int  len;
		SV *buffer;

#line 1323 "FD.c"
#line 857 "FD.xs"
		buffer=newSV(257);
		SvPOK_on(buffer);
		buf=SvPVX(buffer);
		len=256;

		ret=getsockopt(fd,level, option, buf, &len);	

		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else {
			SvCUR_set(buffer, len);
			*SvEND(buffer)='\0';
			RETVAL=buffer;
		}


#line 1342 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_setsockopt); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_setsockopt)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "fd, level, option, buffer");
    {
	int	fd = (int)SvIV(ST(0))
;
	int	level = (int)SvIV(ST(1))
;
	int	option = (int)SvIV(ST(2))
;
	SV*	buffer = ST(3)
;
	SV *	RETVAL;
#line 888 "FD.xs"
		int ret;
		char  *buf;
		unsigned int len;

		SV *_buffer;


#line 1374 "FD.c"
#line 896 "FD.xs"
		if(SvOK(buffer)){
			if(SvIOK(buffer)){
				//Do what perl does and convert integers
				_buffer=newSV(sizeof(int));
				len=sizeof(int);

				SvPOK_on(_buffer);
				SvCUR_set(_buffer, len);
				//*SvEND(_buffer)='\0';
				buf=SvPVX(_buffer);
				*((int *)buf)=SvIVX(buffer);

			}
			else if(SvPOK(buffer)){
				_buffer=buffer;

			}

			len=SvCUR(_buffer);
			buf=SvPVX(_buffer);
			ret=setsockopt(fd,level,option,buf, len);
			if(ret<0){
				//fprintf(stderr, "call failed\n");
				RETVAL=&PL_sv_undef;
			}
			else{
				//fprintf(stderr, "call succeeded\n");
				RETVAL=newSViv(ret+1);
			}

		}
		else{
			//fprintf(stderr, "no buffer");
			RETVAL=&PL_sv_undef;
		}	




#line 1415 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_select); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_select)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "readvec, writevec, errorvec, tout");
    {
	SV*	readvec = ST(0)
;
	SV*	writevec = ST(1)
;
	SV*	errorvec = ST(2)
;
	SV*	tout = ST(3)
;
	SV *	RETVAL;
#line 985 "FD.xs"
		fd_set *r;
		fd_set *w;
		fd_set *e;
		struct timeval timeout;
		int size=sizeof(fd_set)+1;
		double tval;
		int ret;
		int nfds=0;
		int bit_string_size=129;
		int tmp;

#line 1451 "FD.c"
#line 997 "FD.xs"
		//Ensure the vector can fit a fd_set
		//TODO: Need to make sure its null filled too
		//
		if(SvOK(readvec)){
			r=(fd_set *)SvGROW(readvec,bit_string_size);
			tmp=SvCUR(readvec);
			Zero(((char *)r)+tmp,bit_string_size-tmp,1);
			nfds=tmp;
		}
		else {
			r=NULL;
		}

		if(SvOK(writevec)){
			w=(fd_set *)SvGROW(writevec,bit_string_size);
			tmp=SvCUR(writevec);
			Zero(((char *)w)+tmp,bit_string_size-tmp,1);
			nfds=tmp>nfds?tmp:nfds;
		}
		else {
			w=NULL;
		}

		if(SvOK(errorvec)){
			e=(fd_set *)SvGROW(errorvec,bit_string_size);
			tmp=SvCUR(errorvec);
			Zero(((char *)e)+tmp, bit_string_size-tmp,1);
			nfds=tmp>nfds?tmp:nfds;
		}
		else {
			e=NULL;
		}

		nfds*=8;        //convert string (byte) length to bit length
				//This length has an implicit +1 for select call

		//Clamp the nfds to 1024
		if(nfds>1024){
			//TODO: Need to show an error here?
			nfds=1024;
		}
		//TODO: handle EAGAIN and EINT
		//nfds++;
		//fprintf(stderr, "Number of fds for select: %d\n", nfds);
		if(SvOK(tout) && (SvNOK(tout) || SvIOK(tout))){
			//Timeout value provided in fractional seconds
			tval=SvNV(tout);
			timeout.tv_sec=(unsigned int ) tval;
			tval-=timeout.tv_sec;
			tval*=1000000;
			timeout.tv_usec=(unsigned int) tval;

			//fprintf(stderr, "select with %fs timeout....\n", tval);
			ret=select(nfds,r,w,e,&timeout);
			//fprintf(stderr, "Returned number of fds %d\n", ret);
		}

		else{
			//Timeout is not a number
			//printf(stderr, "select with null timeout....\n");
			ret=select(nfds,r,w,e, NULL);
		}
		if(ret<0){
			//Undef on error
			RETVAL=&PL_sv_undef;
		}
		else{
			//0 on timeout expired
			//>0 number of found fds to test
			RETVAL=newSViv(ret);
		}


#line 1526 "FD.c"
	sv_setsv_mg(ST(0), readvec);
	SvSETMAGIC(ST(0));
	sv_setsv_mg(ST(1), writevec);
	SvSETMAGIC(ST(1));
	sv_setsv_mg(ST(2), errorvec);
	SvSETMAGIC(ST(2));
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_poll); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_poll)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "poll_list, s_timeout");
    {
	SV*	poll_list = ST(0)
;
	double	s_timeout = (double)SvNV(ST(1))
;
	SV *	RETVAL;
#line 1085 "FD.xs"
		int sz=sizeof(struct pollfd);
		int count;	
		int ret;
#line 1556 "FD.c"
#line 1089 "FD.xs"
		if(SvOK(poll_list) && SvPOK(poll_list)){
			count=SvCUR(poll_list)/sz;	 //Number of items in array
			//TODO: croak if not fully divisible
			ret=poll((struct pollfd *)SvPVX(poll_list), count, (int)s_timeout*1000);
		}
		else {
			//Used for timeout only
			ret=poll(NULL,0,(int)s_timeout*1000);
		}
		//TODO: need to process EAGAIN and INT somehow
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret);

		}


		//No length of list is required as we use the smallest multiple of sizeof(struct pollfd) which will fit in  the poll list

#line 1579 "FD.c"
	sv_setsv_mg(ST(0), poll_list);
	SvSETMAGIC(ST(0));
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_mkstemp); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_mkstemp)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "template");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	char *	template = (char *)SvPV_nolen(ST(0))
;
	SV *	RETVAL;
#line 1126 "FD.xs"
		int ret;
		SV *path_sv;
		char *path;
		int len=0;
		int min_ok=1;
#line 1607 "FD.c"
#line 1132 "FD.xs"
		len=strlen(template);
		if(len<6){
			Perl_croak(aTHX_ "The template must end with at least 6 'X' characters");
		}

		for(int i=1; i<=6; i++){
			min_ok=min_ok&&(template[len-i]=='X');
		}
		if(!min_ok){
			Perl_croak(aTHX_ "The template must end with at least 6 'X' characters");
		}


		ret=mkstemp(template);
		if(ret<0){
			Perl_croak(aTHX_ "Error creating temp file");
			//mXPUSHs(&PL_sv_undef);
		}	
		else{
			switch(GIMME_V){
				case G_SCALAR:
					mXPUSHs(newSViv(ret));
					break;
				case G_ARRAY:
					//path_sv=newSV(MAXPATHLEN);	
					//path=SvPVX(path_sv);
					//fcntl(ret, F_GETPATH, path);
					//SvCUR_set(path_sv, strlen(path));

					EXTEND(SP,2);
					mPUSHs(newSViv(ret));
					//mPUSHs(newSVpv(path,0));
					mPUSHs(&PL_sv_undef);
					break;

				default:
					break;

			}
		}
#line 1649 "FD.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_IO__FD_mktemp); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_mktemp)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "template");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	char *	template = (char *)SvPV_nolen(ST(0))
;
	SV *	RETVAL;
#line 1181 "FD.xs"
		char *ret;
		char *buf;
		int len=0;
		int min_ok=1;
#line 1673 "FD.c"
#line 1186 "FD.xs"
		len=strlen(template);
		if(len<6){
			Perl_croak(aTHX_ "The template must end with at least 6 'X' characters");
		}

		for(int i=1; i<=6; i++){
			min_ok=min_ok&&(template[len-i]=='X');
		}

		if(!min_ok){
			Perl_croak(aTHX_ "The template must end with at least 6 'X' characters");
		}

		ret=mktemp(template);
		if(ret==NULL){
			Perl_croak(aTHX_ "Error creating temp file");
		}
		else{
			mXPUSHs(newSVpv(ret, 0));
		}
#line 1695 "FD.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_IO__FD_recv); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_recv)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "fd, data, len, flags");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV *	data = ST(1)
;
	int	len = (int)SvIV(ST(2))
;
	int	flags = (int)SvIV(ST(3))
;
	SV *	RETVAL;
#line 1216 "FD.xs"
		int ret;
		SV* peer;	//Return addr like perl
		struct sockaddr *peer_buf; 
		unsigned int addr_len;
		char *buf;

#line 1725 "FD.c"
#line 1223 "FD.xs"
		//Makesure the buffer exists and is large enough to recv
		if(!SvOK(data)){
			data=newSV(len);
		}
		buf = SvPOK(data) ? SvGROW(data,len+1) : NULL;

		peer=newSV(sizeof(struct sockaddr));
		peer_buf=(struct sockaddr *)SvPVX(peer);

		addr_len=sizeof(struct sockaddr);
		ret=recvfrom(fd, buf, len, flags, peer_buf, &addr_len);

		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			SvCUR_set(data,ret);
			SvPOK_on(peer);
			SvCUR_set(peer, addr_len);
			RETVAL=peer;
		}
#line 1748 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_send); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_send)
{
    dVAR; dXSARGS;
    if (items < 3)
       croak_xs_usage(cv,  "fd, data, flags, ...");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV*	data = ST(1)
;
	int	flags = (int)SvIV(ST(2))
;
	SV *	RETVAL;
#line 1255 "FD.xs"
		char *buf;
		int len;

		struct sockaddr *dest;
		int ret;


#line 1778 "FD.c"
#line 1263 "FD.xs"
		if(SvOK(data) && SvPOK(data)){
			if((items == 4) && SvOK(ST(3)) && SvPOK(ST(3))){
				//Do sendto
				len=SvCUR(data);
				buf=SvPVX(data);

				dest=(struct sockaddr *)SvPVX(ST(3));

				ret=sendto(fd, buf, len, flags, dest, SvCUR(ST(3)));
			}
			else {
				//Regular send
				len=SvCUR(data);
				buf=SvPVX(data);
				ret=send(fd, buf, len, flags);
			}
		}
		if(ret<0){

			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret);
		}
#line 1804 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_getpeername); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_getpeername)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "fd");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV *	RETVAL;
#line 1296 "FD.xs"
		int ret;
		SV *addr=newSV(sizeof(struct sockaddr)+1);
		struct sockaddr *buf=(struct sockaddr *)SvPVX(addr);
		unsigned int len=sizeof(struct sockaddr);

#line 1828 "FD.c"
#line 1303 "FD.xs"
		ret=getpeername(fd,buf,&len);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else {
			SvCUR_set(addr,len);
			SvPOK_on(addr);

			RETVAL=addr;
		}

#line 1841 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_getsockname); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_getsockname)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "fd");
    {
	int	fd = (int)SvIV(ST(0))
;
	SV *	RETVAL;
#line 1322 "FD.xs"
		int ret;
		SV *addr=newSV(sizeof(struct sockaddr)+1);
		struct sockaddr *buf=(struct sockaddr *)SvPVX(addr);
		unsigned int len=sizeof(struct sockaddr);

#line 1865 "FD.c"
#line 1329 "FD.xs"
		ret=getsockname(fd,buf,&len);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else {
			SvCUR_set(addr,len);
			SvPOK_on(addr);

			RETVAL=addr;
		}

#line 1878 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_stat); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_stat)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 1)
       croak_xs_usage(cv,  "target");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	target = ST(0)
;
#line 1354 "FD.xs"
		int ret=-1;
		char *path;
		struct stat buf;
		int len;
		IV atime;
		IV mtime;
		IV ctime;
#line 1906 "FD.c"
#line 1363 "FD.xs"
		if(SvOK(target) && SvIOK(target)){
			//Integer => always an fstat
			ret=fstat(SvIV(target), &buf);
		}
		else if(SvOK(target)&& SvPOK(target)){
			//String => stat OR lstat

			len=SvCUR(target);
			Newx(path, len+1, char); 	//Allocate plus null
			Copy(SvPV_nolen(target), path, len, char);	//Copy
			*(path+len)='\0';	//set null	
			switch(ix){
				case 1:
					ret=stat(path, &buf);
					break;
				case 2:
					ret=lstat(path, &buf);
					break;

				default:
					break;
			}
			Safefree(path);


		}
		else {
			//Unkown
		}

		if(ret>=0){
			switch(GIMME_V){
				case G_ARRAY:
					//fprintf(stderr , "ARRAY CONTEXT. no error\n");


					//atime=buf.st_atimespec.tv_sec+buf.st_atimespec.tv_nsec*1e-9;
					//mtime=buf.st_mtimespec.tv_sec+buf.st_mtimespec.tv_nsec*1e-9;
					//ctime=buf.st_ctimespec.tv_sec+buf.st_ctimespec.tv_nsec*1e-9;
					IO_FD_ATIME
					IO_FD_MTIME
					IO_FD_CTIME





					//Work through the items in the struct
					//dSP;
					EXTEND(SP, 13);
					mPUSHs(newSViv(buf.st_dev));
					mPUSHs(newSVuv(buf.st_ino));
					mPUSHs(newSVuv(buf.st_mode));
					mPUSHs(newSViv(buf.st_nlink));
					mPUSHs(newSViv(buf.st_uid));
					mPUSHs(newSViv(buf.st_gid));
					mPUSHs(newSViv(buf.st_rdev));
					mPUSHs(newSViv(buf.st_size));
					mPUSHs(newSViv(atime));
					mPUSHs(newSViv(mtime));
					mPUSHs(newSViv(ctime));
					mPUSHs(newSViv(buf.st_blksize));
					mPUSHs(newSViv(buf.st_blocks));
					XSRETURN(13);
					break;
				case G_VOID:
					XSRETURN_EMPTY;
					break;
				case G_SCALAR:
				default:
					//fprintf(stderr , "SCALAR CONTEXT. no error\n");
					mXPUSHs(newSViv(1));
					XSRETURN(1);
					break;
			}



		}
		switch(GIMME_V){
			case G_SCALAR:
				mXPUSHs(&PL_sv_undef);
				break;
			case G_VOID:
			case G_ARRAY:
			default:
				XSRETURN_EMPTY;
				break;
		}
#line 1997 "FD.c"
	PUTBACK;
	return;
    }
}

#if defined(IO_FD_OS_DARWIN) || defined(IO_FD_OS_BSD)
#define XSubPPtmpAAAA 1


XS_EUPXS(XS_IO__FD_kqueue); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_kqueue)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	SV *	RETVAL;
#line 1459 "FD.xs"
		int ret;
#line 2017 "FD.c"
#line 1461 "FD.xs"
		ret=kqueue();
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSViv(ret);
		}
#line 2026 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_kevent); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_kevent)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "kq, change_list, event_list, timeout");
    {
	int	kq = (int)SvIV(ST(0))
;
	SV *	change_list = ST(1)
;
	SV *	event_list = ST(2)
;
	SV *	timeout = ST(3)
;
	SV *	RETVAL;
#line 1479 "FD.xs"
		int ret;
		int ncl, nel;
		KEVENT_S *cl, *el;
		struct timespec tspec;
		double tout;

#line 2057 "FD.c"
#line 1486 "FD.xs"
		//Calcuate from current length
		ncl=SvCUR(change_list)/sizeof(KEVENT_S);

		//Calculate from available length
		nel=SvLEN(event_list)/sizeof(KEVENT_S);

		cl=(KEVENT_S *)SvPVX(change_list);
		el=(KEVENT_S *)SvPVX(event_list);

		//fprintf(stderr, "change list len: %d, event list available: %d\n", ncl, nel);
		if(SvOK(timeout)&& SvNIOK(timeout)){
			tout=SvNV(timeout);
			tspec.tv_sec=tout;
			tspec.tv_nsec=1e9*(tout-tspec.tv_sec);
#if defined(IO_FD_OS_DARWIN)
			ret=KEVENT (kq, cl, ncl, el, nel, 0, &tspec);
#endif
#if defined(IO_FD_OS_BSD)
			ret=KEVENT(kq, cl, ncl, el, nel, &tspec);
	//}
#endif
		}
		else {
#if defined(IO_FD_OS_DARWIN)
			ret=KEVENT(kq,cl,ncl, el, nel,0, NULL);
#endif
#if defined(IO_FD_OS_BSD)
			ret=KEVENT(kq,cl,ncl, el, nel, NULL);
#endif
		}

		if(ret<0){
			SvCUR_set(event_list,0);
			RETVAL=&PL_sv_undef;
		}
		else {
			SvCUR_set(event_list,sizeof(KEVENT_S)*ret);
			RETVAL=newSViv(ret);
		}

#line 2099 "FD.c"
	sv_setsv_mg(ST(2), event_list);
	SvSETMAGIC(ST(2));
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_pack_kevent); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_pack_kevent)
{
    dVAR; dXSARGS;
    if (items < 6)
       croak_xs_usage(cv,  "ident, filter, flags, fflags, data, udata, ...");
    {
	unsigned long	ident = (unsigned long)SvUV(ST(0))
;
	I16	filter = (I16)SvIV(ST(1))
;
	U16	flags = (unsigned short)SvUV(ST(2))
;
	U32	fflags = (unsigned long)SvUV(ST(3))
;
	long	data = (long)SvIV(ST(4))
;
	SV *	udata = ST(5)
;
	SV *	RETVAL;
#line 1541 "FD.xs"
		KEVENT_S *e;

#line 2132 "FD.c"
#line 1544 "FD.xs"
		RETVAL=newSV(sizeof(KEVENT_S));	
		e=(KEVENT_S *)SvPVX(RETVAL);
		e->ident=ident;
		e->filter=filter;
		e->flags=flags;
		e->fflags=fflags;
		e->data=data;
		e->udata=SvRV(udata);
		SvCUR_set(RETVAL,sizeof(KEVENT_S));
		SvPOK_on(RETVAL);
		//Pack

#line 2146 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}

#endif

XS_EUPXS(XS_IO__FD_clock_gettime_monotonic); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_clock_gettime_monotonic)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	SV *	RETVAL;
#line 1565 "FD.xs"
		struct timespec tp;
		int ret;

#line 2167 "FD.c"
#line 1569 "FD.xs"
		ret=clock_gettime(CLOCK_MONOTONIC, &tp);
		if(ret<0){
			RETVAL=&PL_sv_undef;
		}
		else{
			RETVAL=newSVnv(tp.tv_sec + tp.tv_nsec * 1e-9);
		}


#line 2178 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_sv_to_pointer); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_sv_to_pointer)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
	long	RETVAL;
	dXSTARG;
#line 1587 "FD.xs"
#line 2198 "FD.c"
#line 1588 "FD.xs"
		//TODO: Increase the ref count	of input sv
		RETVAL=(long)SvRV(sv);
#line 2202 "FD.c"
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_pointer_to_sv); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_pointer_to_sv)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "pointer");
    {
	long	pointer = (long)SvIV(ST(0))
;
	SV *	RETVAL;
#line 1599 "FD.xs"
#line 2221 "FD.c"
#line 1600 "FD.xs"
		//TODO: check valid. decrement ref count;
		RETVAL=newRV((SV*)pointer);

#line 2226 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_SV); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_SV)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "size");
    {
	int	size = (int)SvIV(ST(0))
;
	SV *	RETVAL;
#line 1612 "FD.xs"
		RETVAL=newSV(size);

		//SvPOK_on(RETVAL);
		SvPVCLEAR(RETVAL);
#line 2249 "FD.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_IO__FD_readline); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_IO__FD_readline)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "fd");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	int	fd = (int)SvIV(ST(0))
;
#line 1630 "FD.xs"
		SV *irs;
		int ret;
		int count;
		SV* buffer;
		char *buf;
		int do_loop=1;

		int tmp;
#line 2277 "FD.c"
#line 1639 "FD.xs"
		irs=get_sv("/",0);
		if(irs){
			if(SvOK(irs)){
				if(SvROK(irs)){
					//fprintf(stderr, "DOING RECORD READ\n");
					//SLURP RECORDS

					SV* v=SvRV(irs);	//Dereference to get SV
					tmp=SvIV(v);		//The integer value of the sv
					buffer=newSV(tmp);	//Allocate buffer at record size
					buf=SvPVX(buffer);	//Get the pointer we  need
					ret=read(fd, buf, tmp);	//Do the read into buffer
					//fprintf(stderr, "read return: %d\n", ret);
					SvPOK_on(buffer);	//Make a string
					if(ret>=0){
						buf[ret]='\0';		//Set null just in case
						SvCUR_set(buffer,ret);	//Set the length of the string
						EXTEND(SP,1);		//Extend stack
						mPUSHs(buffer);		//Push record
					}
					else {
						XSRETURN_UNDEF;
					}

				}
				else {
					Perl_croak( aTHX_ "IO::FD::readline does not split lines");
				}
			}
			else{

				//fprintf(stderr, "DOING SLURP READ\n");
				//SLURP entire file
				EXTEND(SP,1);
				PUSHs(slurp(aTHX_ fd, 4096));
			}
		}
		else {

		}
#line 2319 "FD.c"
	PUTBACK;
	return;
    }
}

#ifdef __cplusplus
extern "C"
#endif
XS_EXTERNAL(boot_IO__FD); /* prototype to pass -Wmissing-prototypes */
XS_EXTERNAL(boot_IO__FD)
{
#if PERL_VERSION_LE(5, 21, 5)
    dVAR; dXSARGS;
#else
    dVAR; dXSBOOTARGSXSAPIVERCHK;
#endif
#if PERL_VERSION_LE(5, 8, 999) /* PERL_VERSION_LT is 5.33+ */
    char* file = __FILE__;
#else
    const char* file = __FILE__;
#endif

    PERL_UNUSED_VAR(file);

    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
#if PERL_VERSION_LE(5, 21, 5)
    XS_VERSION_BOOTCHECK;
#  ifdef XS_APIVERSION_BOOTCHECK
    XS_APIVERSION_BOOTCHECK;
#  endif
#endif

        newXS_deffile("IO::FD::constant", XS_IO__FD_constant);
        newXS_deffile("IO::FD::socket", XS_IO__FD_socket);
        newXS_deffile("IO::FD::listen", XS_IO__FD_listen);
        newXS_deffile("IO::FD::accept", XS_IO__FD_accept);
        newXS_deffile("IO::FD::connect", XS_IO__FD_connect);
        newXS_deffile("IO::FD::sysopen", XS_IO__FD_sysopen);
        newXS_deffile("IO::FD::sysopen4", XS_IO__FD_sysopen4);
        newXS_deffile("IO::FD::close", XS_IO__FD_close);
        newXS_deffile("IO::FD::sysread", XS_IO__FD_sysread);
        newXS_deffile("IO::FD::sysread3", XS_IO__FD_sysread3);
        newXS_deffile("IO::FD::sysread4", XS_IO__FD_sysread4);
        newXS_deffile("IO::FD::syswrite", XS_IO__FD_syswrite);
        newXS_deffile("IO::FD::syswrite2", XS_IO__FD_syswrite2);
        newXS_deffile("IO::FD::syswrite3", XS_IO__FD_syswrite3);
        newXS_deffile("IO::FD::syswrite4", XS_IO__FD_syswrite4);
        cv = newXS_deffile("IO::FD::pipe", XS_IO__FD_pipe);
        XSANY.any_i32 = 0;
        cv = newXS_deffile("IO::FD::syspipe", XS_IO__FD_pipe);
        XSANY.any_i32 = 1;
        cv = newXS_deffile("IO::FD::bind", XS_IO__FD_bind);
        XSANY.any_i32 = 0;
        cv = newXS_deffile("IO::FD::sysbind", XS_IO__FD_bind);
        XSANY.any_i32 = 1;
        newXS_deffile("IO::FD::socketpair", XS_IO__FD_socketpair);
        newXS_deffile("IO::FD::sysseek", XS_IO__FD_sysseek);
        newXS_deffile("IO::FD::dup", XS_IO__FD_dup);
        newXS_deffile("IO::FD::dup2", XS_IO__FD_dup2);
        cv = newXS_deffile("IO::FD::fcntl", XS_IO__FD_fcntl);
        XSANY.any_i32 = 0;
        cv = newXS_deffile("IO::FD::sysfctrl", XS_IO__FD_fcntl);
        XSANY.any_i32 = 1;
        cv = newXS_deffile("IO::FD::ioctl", XS_IO__FD_ioctl);
        XSANY.any_i32 = 0;
        cv = newXS_deffile("IO::FD::sysioctl", XS_IO__FD_ioctl);
        XSANY.any_i32 = 1;
        newXS_deffile("IO::FD::getsockopt", XS_IO__FD_getsockopt);
        newXS_deffile("IO::FD::setsockopt", XS_IO__FD_setsockopt);
        newXS_deffile("IO::FD::select", XS_IO__FD_select);
        newXS_deffile("IO::FD::poll", XS_IO__FD_poll);
        newXS_deffile("IO::FD::mkstemp", XS_IO__FD_mkstemp);
        newXS_deffile("IO::FD::mktemp", XS_IO__FD_mktemp);
        newXS_deffile("IO::FD::recv", XS_IO__FD_recv);
        newXS_deffile("IO::FD::send", XS_IO__FD_send);
        newXS_deffile("IO::FD::getpeername", XS_IO__FD_getpeername);
        newXS_deffile("IO::FD::getsockname", XS_IO__FD_getsockname);
        cv = newXS_deffile("IO::FD::lstat", XS_IO__FD_stat);
        XSANY.any_i32 = 2;
        cv = newXS_deffile("IO::FD::stat", XS_IO__FD_stat);
        XSANY.any_i32 = 1;
#if XSubPPtmpAAAA
        newXS_deffile("IO::FD::kqueue", XS_IO__FD_kqueue);
        newXS_deffile("IO::FD::kevent", XS_IO__FD_kevent);
        newXS_deffile("IO::FD::pack_kevent", XS_IO__FD_pack_kevent);
#endif
        newXS_deffile("IO::FD::clock_gettime_monotonic", XS_IO__FD_clock_gettime_monotonic);
        newXS_deffile("IO::FD::sv_to_pointer", XS_IO__FD_sv_to_pointer);
        newXS_deffile("IO::FD::pointer_to_sv", XS_IO__FD_pointer_to_sv);
        newXS_deffile("IO::FD::SV", XS_IO__FD_SV);
        newXS_deffile("IO::FD::readline", XS_IO__FD_readline);

    /* Initialisation Section */

#if XSubPPtmpAAAA
#endif
#line 2417 "FD.c"

    /* End of Initialisation Section */

#if PERL_VERSION_LE(5, 21, 5)
#  if PERL_VERSION_GE(5, 9, 0)
    if (PL_unitcheckav)
        call_list(PL_scopestack_ix, PL_unitcheckav);
#  endif
    XSRETURN_YES;
#else
    Perl_xs_boot_epilog(aTHX_ ax);
#endif
}

