/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Netscape Portable Runtime (NSPR).
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "primpl.h"

/*
** Global lock variable used to bracket calls into rusty libraries that
** aren't thread safe (like libc, libX, etc).
*/
static PRLock *_pr_rename_lock = NULL; 

void
_MD_InitIO (void)
{
}

PRStatus
_MD_open_dir (_MDDir *md,const char *name)
{
int err;

	md->d = opendir(name);
	if (!md->d) {
		err = _MD_ERRNO();
		_PR_MD_MAP_OPENDIR_ERROR(err);
		return PR_FAILURE;
	}
	return PR_SUCCESS;
}

char*
_MD_read_dir (_MDDir *md, PRIntn flags)
{
struct dirent *de;
int err;

	for (;;) {
		/*
		 * XXX: readdir() is not MT-safe
		 */
		_MD_ERRNO() = 0;
		de = readdir(md->d);

		if (!de) {
			err = _MD_ERRNO();
			_PR_MD_MAP_READDIR_ERROR(err);
			return 0;
		}

		if ((flags & PR_SKIP_DOT) &&
		    (de->d_name[0] == '.') && (de->d_name[1] == 0))
			continue;

		if ((flags & PR_SKIP_DOT_DOT) &&
		    (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
		    (de->d_name[2] == 0))
			continue;

		if ((flags & PR_SKIP_HIDDEN) && (de->d_name[1] == '.'))
			continue;

		break;
	}
	return de->d_name;
}


PRInt32
_MD_close_dir (_MDDir *md)
{
int rv = 0, err;

	if (md->d) {
		rv = closedir(md->d);
		if (rv == -1) {
			err = _MD_ERRNO();
			_PR_MD_MAP_CLOSEDIR_ERROR(err);
		}
	}
	return(rv);
}

void
_MD_make_nonblock (PRFileDesc *fd)
{
	int blocking = 1;
	setsockopt(fd->secret->md.osfd, SOL_SOCKET, SO_NONBLOCK, &blocking, sizeof(blocking));

}

PRStatus
_MD_set_fd_inheritable (PRFileDesc *fd, PRBool inheritable)
{
        int rv;
	
        rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC);
        if (-1 == rv) {
                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
                return PR_FAILURE;
        }
        return PR_SUCCESS;
}

void
_MD_init_fd_inheritable (PRFileDesc *fd, PRBool imported)
{
	if (imported) {
		fd->secret->inheritable = _PR_TRI_UNKNOWN;
	} else {
		int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
		if (flags == -1) {
			PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
			return;
		}
		fd->secret->inheritable = (flags & FD_CLOEXEC) ? 
			_PR_TRI_TRUE : _PR_TRI_FALSE;
	}
}

void
_MD_query_fd_inheritable (PRFileDesc *fd)
{
	int flags;
	
	PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
	flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
	PR_ASSERT(-1 != flags);
	fd->secret->inheritable = (flags & FD_CLOEXEC) ?
		_PR_TRI_FALSE : _PR_TRI_TRUE;
}

PRInt32
_MD_open (const char *name, PRIntn flags, PRIntn mode)
{
	PRInt32 osflags;
	PRInt32 rv, err;

	if (flags & PR_RDWR) {
		osflags = O_RDWR;
	} else if (flags & PR_WRONLY) {
		osflags = O_WRONLY;
	} else {
		osflags = O_RDONLY;
	}

	if (flags & PR_EXCL)
		osflags |= O_EXCL;
	if (flags & PR_APPEND)
		osflags |= O_APPEND;
	if (flags & PR_TRUNCATE)
		osflags |= O_TRUNC;
	if (flags & PR_SYNC) {
/* Ummmm.  BeOS doesn't appear to
   support sync in any way shape or
   form. */
		return PR_NOT_IMPLEMENTED_ERROR;
	}

	/*
	** On creations we hold the 'create' lock in order to enforce
	** the semantics of PR_Rename. (see the latter for more details)
	*/
	if (flags & PR_CREATE_FILE)
	{
		osflags |= O_CREAT ;
		if (NULL !=_pr_rename_lock)
		    PR_Lock(_pr_rename_lock);
	}

        rv = open(name, osflags, mode);

        if (rv < 0) {
                err = _MD_ERRNO();
                _PR_MD_MAP_OPEN_ERROR(err);
        }                                                                      

    if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock))
        PR_Unlock(_pr_rename_lock);
        return rv;
}

PRInt32
_MD_close_file (PRInt32 osfd)
{
PRInt32 rv, err;

	rv = close(osfd);
	if (rv == -1) {
		err = _MD_ERRNO();
		_PR_MD_MAP_CLOSE_ERROR(err);
	}
	return(rv);
}

PRInt32
_MD_read (PRFileDesc *fd, void *buf, PRInt32 amount)
{
    PRInt32 rv, err;
    PRInt32 osfd = fd->secret->md.osfd;

    rv = read( osfd, buf, amount );
    if (rv < 0) {
	err = _MD_ERRNO();
	_PR_MD_MAP_READ_ERROR(err);
    }
    return(rv);
}

PRInt32
_MD_write (PRFileDesc *fd, const void *buf, PRInt32 amount)
{
    PRInt32 rv, err;
    PRInt32 osfd = fd->secret->md.osfd;

    rv = write( osfd, buf, amount );

    if( rv < 0 ) {

	err = _MD_ERRNO();
	_PR_MD_MAP_WRITE_ERROR(err);
    }
    return( rv );
}

#ifndef BONE_VERSION /* Writev moves to bnet.c with BONE */
PRInt32
_MD_writev (PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
	    PRIntervalTime timeout)
{
    return PR_NOT_IMPLEMENTED_ERROR;
}
#endif

PRInt32
_MD_lseek (PRFileDesc *fd, PRInt32 offset, int whence)
{
PRInt32 rv, err;

    rv = lseek (fd->secret->md.osfd, offset, whence);
    if (rv == -1) {
        err = _MD_ERRNO();
	_PR_MD_MAP_LSEEK_ERROR(err);
    }
    return( rv );
}

PRInt64
_MD_lseek64 (PRFileDesc *fd, PRInt64 offset, int whence)
{
PRInt32 rv, err;

/* According to the BeOS headers, lseek accepts a
 * variable of type off_t for the offset, and off_t
 * is defined to be a 64-bit value.  So no special
 * cracking needs to be done on "offset".
 */

    rv = lseek (fd->secret->md.osfd, offset, whence);
    if (rv == -1) {
        err = _MD_ERRNO();
	_PR_MD_MAP_LSEEK_ERROR(err);
    }
    return( rv );
}

PRInt32
_MD_fsync (PRFileDesc *fd)
{
PRInt32 rv, err;

    rv = fsync(fd->secret->md.osfd);
    if (rv == -1) {
	err = _MD_ERRNO();
	_PR_MD_MAP_FSYNC_ERROR(err);
    }
    return(rv);
}

PRInt32
_MD_delete (const char *name)
{
PRInt32 rv, err;

    rv = unlink(name);
    if (rv == -1)
    {
	err = _MD_ERRNO();
        _PR_MD_MAP_UNLINK_ERROR(err);
    }
    return (rv);
}

PRInt32
_MD_getfileinfo (const char *fn, PRFileInfo *info)
{
struct stat sb;
PRInt32 rv, err;
PRInt64 s, s2us;

	rv = stat(fn, &sb);
	if (rv < 0) {
		err = _MD_ERRNO();
		_PR_MD_MAP_STAT_ERROR(err);
	} else if (info) {
		if (S_IFREG & sb.st_mode)
			info->type = PR_FILE_FILE;
		else if (S_IFDIR & sb.st_mode)
			info->type = PR_FILE_DIRECTORY;
		else
			info->type = PR_FILE_OTHER;

		/* Must truncate file size for the 32 bit
		   version */
		info->size = (sb.st_size & 0xffffffff);
		LL_I2L(s, sb.st_mtime);
		LL_I2L(s2us, PR_USEC_PER_SEC);
		LL_MUL(s, s, s2us);
		info->modifyTime = s;
		LL_I2L(s, sb.st_ctime);
		LL_MUL(s, s, s2us);
		info->creationTime = s;
	}
	return rv;
}

PRInt32
_MD_getfileinfo64 (const char *fn, PRFileInfo64 *info)
{
struct stat sb;
PRInt32 rv, err;
PRInt64 s, s2us;

	rv = stat(fn, &sb);
	if (rv < 0) {
		err = _MD_ERRNO();
		_PR_MD_MAP_STAT_ERROR(err);
	} else if (info) {
		if (S_IFREG & sb.st_mode)
			info->type = PR_FILE_FILE;
		else if (S_IFDIR & sb.st_mode)
			info->type = PR_FILE_DIRECTORY;
		else
			info->type = PR_FILE_OTHER;
	
		/* For the 64 bit version we can use
		 * the native st_size without modification
		 */
		info->size = sb.st_size;
		LL_I2L(s, sb.st_mtime);
		LL_I2L(s2us, PR_USEC_PER_SEC);
		LL_MUL(s, s, s2us);
		info->modifyTime = s;
		LL_I2L(s, sb.st_ctime);
		LL_MUL(s, s, s2us);
		info->creationTime = s;
	}
	return rv;
}

PRInt32
_MD_getopenfileinfo (const PRFileDesc *fd, PRFileInfo *info)
{
        struct stat sb;
        PRInt64 s, s2us;
        PRInt32 rv, err;

        rv = fstat(fd->secret->md.osfd, &sb);
        if (rv < 0) {
                        err = _MD_ERRNO();
                        _PR_MD_MAP_FSTAT_ERROR(err);
        } else if (info) {
                if (info) {
                        if (S_IFREG & sb.st_mode)
                                info->type = PR_FILE_FILE ;
                        else if (S_IFDIR & sb.st_mode)
                                info->type = PR_FILE_DIRECTORY;
                        else
                                info->type = PR_FILE_OTHER;
			/* Use lower 32 bits of file size */
                        info->size = ( sb.st_size & 0xffffffff);
                        LL_I2L(s, sb.st_mtime);
                        LL_I2L(s2us, PR_USEC_PER_SEC);
                        LL_MUL(s, s, s2us);
                        info->modifyTime = s;
                        LL_I2L(s, sb.st_ctime);
                        LL_MUL(s, s, s2us);
                        info->creationTime = s;
                }
        }
        return rv;
}

PRInt32
_MD_getopenfileinfo64 (const PRFileDesc *fd, PRFileInfo64 *info)
{
        struct stat sb;
        PRInt64 s, s2us;
        PRInt32 rv, err;

        rv = fstat(fd->secret->md.osfd, &sb);
        if (rv < 0) {
                        err = _MD_ERRNO();
                        _PR_MD_MAP_FSTAT_ERROR(err);
        } else if (info) {
                if (info) {
                        if (S_IFREG & sb.st_mode)
                                info->type = PR_FILE_FILE ;
                        else if (S_IFDIR & sb.st_mode)
                                info->type = PR_FILE_DIRECTORY;
                        else
                                info->type = PR_FILE_OTHER;
                        info->size = sb.st_size;
                        LL_I2L(s, sb.st_mtime);
                        LL_I2L(s2us, PR_USEC_PER_SEC);
                        LL_MUL(s, s, s2us);
                        info->modifyTime = s;
                        LL_I2L(s, sb.st_ctime);
                        LL_MUL(s, s, s2us);
                        info->creationTime = s;
                }
        }
        return rv;
}

PRInt32
_MD_rename (const char *from, const char *to)
{
    PRInt32 rv = -1, err;

    /*
    ** This is trying to enforce the semantics of WINDOZE' rename
    ** operation. That means one is not allowed to rename over top
    ** of an existing file. Holding a lock across these two function
    ** and the open function is known to be a bad idea, but ....
    */
    if (NULL != _pr_rename_lock)
        PR_Lock(_pr_rename_lock);
    if (0 == access(to, F_OK))
        PR_SetError(PR_FILE_EXISTS_ERROR, 0);
    else
    {
            rv = rename(from, to);
            if (rv < 0) {
                    err = _MD_ERRNO();
                    _PR_MD_MAP_RENAME_ERROR(err);
            }
    }
    if (NULL != _pr_rename_lock)
        PR_Unlock(_pr_rename_lock);
    return rv; 
}

PRInt32
_MD_access (const char *name, PRIntn how)
{
PRInt32 rv, err;
int checkFlags;
struct stat buf;

	switch (how) {
		case PR_ACCESS_WRITE_OK:
			checkFlags = S_IWUSR | S_IWGRP | S_IWOTH;
			break;
		
		case PR_ACCESS_READ_OK:
			checkFlags = S_IRUSR | S_IRGRP | S_IROTH;
			break;
		
		case PR_ACCESS_EXISTS:
			/* we don't need to examine st_mode. */
			break;
		
		default:
			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
			return -1;
	}

	rv = stat(name, &buf);
	if (rv == 0 && how != PR_ACCESS_EXISTS && (!(buf.st_mode & checkFlags))) {
		PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
		return -1;
	}

	if (rv < 0) {
		err = _MD_ERRNO();
		_PR_MD_MAP_STAT_ERROR(err);
	}

	return(rv);
}

PRInt32
_MD_stat (const char *name, struct stat *buf)
{
    return PR_NOT_IMPLEMENTED_ERROR;
}

PRInt32
_MD_mkdir (const char *name, PRIntn mode)
{
    status_t rv;
    int err;

    /*
    ** This lock is used to enforce rename semantics as described
    ** in PR_Rename. Look there for more fun details.
    */
    if (NULL !=_pr_rename_lock)
        PR_Lock(_pr_rename_lock);

    rv = mkdir(name, mode);
    if (rv < 0) {
	err = _MD_ERRNO();
	_PR_MD_MAP_MKDIR_ERROR(err);
    }
    if (NULL !=_pr_rename_lock)
        PR_Unlock(_pr_rename_lock);
    return rv; 
}

PRInt32
_MD_rmdir (const char *name)
{
int rv, err;

        rv = rmdir(name);
        if (rv == -1) {
                        err = _MD_ERRNO();
                        _PR_MD_MAP_RMDIR_ERROR(err);
        }
        return rv;
}

PRInt32
_MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
{
	PRInt32 rv = 0;
	PRThread *me = _PR_MD_CURRENT_THREAD();
	/*
	 * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
	 */
	fd_set rd, wt, ex;
	PRFileDesc *bottom;
	PRPollDesc *pd, *epd;
	PRInt32 maxfd = -1, ready, err;
	PRIntervalTime remaining, elapsed, start;

	struct timeval tv, *tvp = NULL;

	if (_PR_PENDING_INTERRUPT(me))
	{
		me->flags &= ~_PR_INTERRUPT;
		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
		return -1;
	}

	if (0 == npds) {
		PR_Sleep(timeout);
		return rv;
	}

	FD_ZERO(&rd);
	FD_ZERO(&wt);
	FD_ZERO(&ex);

	ready = 0;
	for (pd = pds, epd = pd + npds; pd < epd; pd++)
	{
		PRInt16 in_flags_read = 0, in_flags_write = 0;
		PRInt16 out_flags_read = 0, out_flags_write = 0; 
		
		if ((NULL != pd->fd) && (0 != pd->in_flags))
		{
			if (pd->in_flags & PR_POLL_READ)
			{
				in_flags_read = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
			}
			if (pd->in_flags & PR_POLL_WRITE)
			{
				in_flags_write = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
			}
			if ((0 != (in_flags_read & out_flags_read))
			    || (0 != (in_flags_write & out_flags_write)))
			{
				/* this one's ready right now */
				if (0 == ready)
				{
					/*
					 * We will have to return without calling the
					 * system poll/select function.  So zero the
					 * out_flags fields of all the poll descriptors
					 * before this one. 
					 */
					PRPollDesc *prev;
					for (prev = pds; prev < pd; prev++)
					{
						prev->out_flags = 0;
					}
				}
				ready += 1;
				pd->out_flags = out_flags_read | out_flags_write;
			}
			else
			{
				pd->out_flags = 0;  /* pre-condition */
				
				/* make sure this is an NSPR supported stack */
				bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
				PR_ASSERT(NULL != bottom);  /* what to do about that? */
				if ((NULL != bottom)
				    && (_PR_FILEDESC_OPEN == bottom->secret->state))
				{
					if (0 == ready)
					{
						PRInt32 osfd = bottom->secret->md.osfd; 
						if (osfd > maxfd) maxfd = osfd;
						if (in_flags_read & PR_POLL_READ)
						{
							pd->out_flags |= _PR_POLL_READ_SYS_READ;
							FD_SET(osfd, &rd);
						}
						if (in_flags_read & PR_POLL_WRITE)
						{
							pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
							FD_SET(osfd, &wt);
						}
						if (in_flags_write & PR_POLL_READ)
						{
							pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
							FD_SET(osfd, &rd);
						}
						if (in_flags_write & PR_POLL_WRITE)
						{
							pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
							FD_SET(osfd, &wt);
						}
						if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
					}
				}
				else
				{
					if (0 == ready)
					{
						PRPollDesc *prev;
						for (prev = pds; prev < pd; prev++)
						{
							prev->out_flags = 0;
						}
					}
					ready += 1;  /* this will cause an abrupt return */
					pd->out_flags = PR_POLL_NVAL;  /* bogii */
				}
			}
		}
		else
		{
			pd->out_flags = 0;
		}
	}

	if (0 != ready) return ready;  /* no need to block */

	remaining = timeout;
	start = PR_IntervalNow(); 

 retry:
	if (timeout != PR_INTERVAL_NO_TIMEOUT)
	{
		PRInt32 ticksPerSecond = PR_TicksPerSecond();
		tv.tv_sec = remaining / ticksPerSecond;
		tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
		tvp = &tv;
	}
	
	ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
	
	if (ready == -1 && errno == EINTR)
	{
		if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
		else
		{
			elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
			if (elapsed > timeout) ready = 0;  /* timed out */
			else
			{
				remaining = timeout - elapsed;
				goto retry; 
			}
		}
	} 

	/*
	** Now to unravel the select sets back into the client's poll
	** descriptor list. Is this possibly an area for pissing away
	** a few cycles or what?
	*/
	if (ready > 0)
	{
		ready = 0;
		for (pd = pds, epd = pd + npds; pd < epd; pd++)
		{
			PRInt16 out_flags = 0;
			if ((NULL != pd->fd) && (0 != pd->in_flags))
			{
				PRInt32 osfd;
				bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
				PR_ASSERT(NULL != bottom);
				
				osfd = bottom->secret->md.osfd; 
				
				if (FD_ISSET(osfd, &rd))
				{
					if (pd->out_flags & _PR_POLL_READ_SYS_READ)
						out_flags |= PR_POLL_READ;
					if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
						out_flags |= PR_POLL_WRITE;
				}
				if (FD_ISSET(osfd, &wt))
				{
					if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
						out_flags |= PR_POLL_READ;
					if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
						out_flags |= PR_POLL_WRITE;
				}
				if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;

/* Workaround for nonblocking connects under net_server */
#ifndef BONE_VERSION 		
				if (out_flags)
				{
					/* check if it is a pending connect */
					int i = 0, j = 0;
					PR_Lock( _connectLock );
					for( i = 0; i < connectCount; i++ ) 
					{
						if(connectList[i].osfd == osfd)
						{
							int connectError;
							int connectResult;
					
							connectResult = connect(connectList[i].osfd,
							                        &connectList[i].addr,
							                        connectList[i].addrlen);
							connectError = errno;
					
							if(connectResult < 0 ) 
							{
								if(connectError == EINTR || connectError == EWOULDBLOCK ||
					  		   connectError == EINPROGRESS || connectError == EALREADY)
								{
									break;
								}
							}
					
							if(i == (connectCount - 1))
							{
								connectList[i].osfd = -1;
							} else {
								for(j = i; j < connectCount; j++ )
								{
									memcpy( &connectList[j], &connectList[j+1],
									        sizeof(connectList[j]));
								}
							}
							connectCount--;
					
							bottom->secret->md.connectReturnValue = connectResult;
							bottom->secret->md.connectReturnError = connectError;
							bottom->secret->md.connectValueValid = PR_TRUE;
							break;
						}
					}
					PR_Unlock( _connectLock );
				}
#endif
			}
			pd->out_flags = out_flags;
			if (out_flags) ready++;
		}
		PR_ASSERT(ready > 0);
	}
	else if (ready < 0)
	{ 
		err = _MD_ERRNO();
		if (err == EBADF)
		{
			/* Find the bad fds */
			ready = 0;
			for (pd = pds, epd = pd + npds; pd < epd; pd++)
			{
				pd->out_flags = 0;
				if ((NULL != pd->fd) && (0 != pd->in_flags))
				{
					bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
					if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
					{
						pd->out_flags = PR_POLL_NVAL;
						ready++;
					}
				}
			}
			PR_ASSERT(ready > 0);
		}
		else _PR_MD_MAP_SELECT_ERROR(err);
	}
	
	return ready;
}  /* _MD_pr_poll */

/*
 * File locking.
 */

PRStatus
_MD_lockfile (PRInt32 osfd)
{
    PRInt32 rv;
    struct flock linfo;

    linfo.l_type = 
    linfo.l_whence = SEEK_SET;
    linfo.l_start = 0;
    linfo.l_len = 0;

    rv = fcntl(osfd, F_SETLKW, &linfo);
    if (rv == 0)
	return PR_SUCCESS;

    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
    return PR_FAILURE;
}

PRStatus
_MD_tlockfile (PRInt32 osfd)
{
    PRInt32 rv;
    struct flock linfo;

    linfo.l_type = 
    linfo.l_whence = SEEK_SET;
    linfo.l_start = 0;
    linfo.l_len = 0;

    rv = fcntl(osfd, F_SETLK, &linfo);
    if (rv == 0)
	return PR_SUCCESS;

    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
    return PR_FAILURE;
}

PRStatus
_MD_unlockfile (PRInt32 osfd)
{
    PRInt32 rv;
    struct flock linfo;

    linfo.l_type = 
    linfo.l_whence = SEEK_SET;
    linfo.l_start = 0;
    linfo.l_len = 0;

    rv = fcntl(osfd, F_UNLCK, &linfo);

    if (rv == 0)
	return PR_SUCCESS;

    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
    return PR_FAILURE;
}

