/* This replacement of the Manx 'close' function is here to support the
   versions "dup" and "dup2" I wrote below.  It relies on the use of an
   otherwise unused bit in the Manx filehandle structure's mode field.

   Manx should have supported "dup" and "dup2" in the first place,
   considering how easy (I didn't say efficient.) they were to write.

   Unfortunately, I have to include the "#asm" stuff here.  If it is not here
   'ld' tries to link in the "close" module to resolve "__close", dragging in
   the "close" function too, which causes a "multiply defined" error.
*/
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <functions.h>

#asm
	xdef __close
__close:
	jmp	_close
#endasm

int close(int fd)
{
    struct _dev *dp, *base;
    int i;

    if (fd < 0 || fd >= _numdev || !((dp = &_devtab[fd])->fd)) {
	errno = EBADF;
	return(-1);
    }
    if (!(dp->mode & O_STDIO)) {	/* If marked, don't close at all */
	if (dp->mode & 0x2000) {	/* If dup'd or dup2'd, check first */
	    base = _devtab;
	    for (i = 0; i < _numdev; i++) {
		if (i != fd && base[i].fd == dp->fd)
		    goto noclose;
	    }
	}
	Close((BPTR)dp->fd);
    }
noclose:
    dp->fd = 0;
    return(0);
}
