📄 os2io.c
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* * 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 Netscape are * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * This Original Code has been modified by IBM Corporation. * Modifications made by IBM described herein are * Copyright (c) International Business Machines * Corporation, 2000 * * Modifications to Mozilla code or documentation * identified per MPL Section 3.3 * * Date Modified by Description of modification * 03/23/2000 IBM Corp. Changed write() to DosWrite(). EMX i/o * calls cannot be intermixed with DosXXX * calls since EMX remaps file/socket * handles. * 04/27/2000 IBM Corp. Changed open file to be more like NT and * better handle PR_TRUNCATE | PR_CREATE_FILE * and also fixed _PR_MD_SET_FD_INHERITABLE *//* OS2 IO module * * Assumes synchronous I/O. * */#include "primpl.h"#include "prio.h"#include <ctype.h>#ifdef XP_OS2_VACPP#include <direct.h>#else#include <limits.h>#include <dirent.h>#include <fcntl.h>#include <io.h>#endifstruct _MDLock _pr_ioq_lock;PRStatus_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks){ PRInt32 rv; ULONG count; PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks); rv = DosWaitEventSem(thread->md.blocked_sema, msecs); DosResetEventSem(thread->md.blocked_sema, &count); switch(rv) { case NO_ERROR: return PR_SUCCESS; break; case ERROR_TIMEOUT: _PR_THREAD_LOCK(thread); if (thread->state == _PR_IO_WAIT) { ; } else { if (thread->wait.cvar != NULL) { thread->wait.cvar = NULL; _PR_THREAD_UNLOCK(thread); } else { /* The CVAR was notified just as the timeout * occurred. This led to us being notified twice. * call SemRequest() to clear the semaphore. */ _PR_THREAD_UNLOCK(thread); rv = DosWaitEventSem(thread->md.blocked_sema, 0); DosResetEventSem(thread->md.blocked_sema, &count); PR_ASSERT(rv == NO_ERROR); } } return PR_SUCCESS; break; default: break; } return PR_FAILURE;}PRStatus_PR_MD_WAKEUP_WAITER(PRThread *thread){ if ( _PR_IS_NATIVE_THREAD(thread) ) { if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR) return PR_FAILURE; else return PR_SUCCESS; }}/* --- FILE IO ----------------------------------------------------------- *//* * _PR_MD_OPEN() -- Open a file * * returns: a fileHandle * * The NSPR open flags (osflags) are translated into flags for OS/2 * * Mode seems to be passed in as a unix style file permissions argument * as in 0666, in the case of opening the logFile. * */PRInt32_PR_MD_OPEN(const char *name, PRIntn osflags, int mode){ HFILE file; PRInt32 access = OPEN_SHARE_DENYNONE; PRInt32 flags = 0L; APIRET rc = 0; PRUword actionTaken; ULONG CurMaxFH = 0; LONG ReqCount = 1; ULONG fattr; if (osflags & PR_SYNC) access |= OPEN_FLAGS_WRITE_THROUGH; if (osflags & PR_RDONLY) access |= OPEN_ACCESS_READONLY; else if (osflags & PR_WRONLY) access |= OPEN_ACCESS_WRITEONLY; else if(osflags & PR_RDWR) access |= OPEN_ACCESS_READWRITE; if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) { flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; } else if (osflags & PR_CREATE_FILE) { if (osflags & PR_TRUNCATE) flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS; else flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; } else { if (osflags & PR_TRUNCATE) flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS; else flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; } if (isxdigit(mode) == 0) /* file attribs are hex, UNIX modes octal */ fattr = ((ULONG)mode == FILE_HIDDEN) ? FILE_HIDDEN : FILE_NORMAL; else fattr = FILE_NORMAL; do { rc = DosOpen((char*)name, &file, /* file handle if successful */ &actionTaken, /* reason for failure */ 0, /* initial size of new file */ fattr, /* file system attributes */ flags, /* Open flags */ access, /* Open mode and rights */ 0); /* OS/2 Extended Attributes */ if (rc == ERROR_TOO_MANY_OPEN_FILES) { ULONG CurMaxFH = 0; LONG ReqCount = 20; APIRET rc2; rc2 = DosSetRelMaxFH(&ReqCount, &CurMaxFH); if (rc2 != NO_ERROR) { break; } } } while (rc == ERROR_TOO_MANY_OPEN_FILES); if (rc != NO_ERROR) { _PR_MD_MAP_OPEN_ERROR(rc); return -1; } return (PRInt32)file;}PRInt32_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len){ ULONG bytes; int rv; rv = DosRead((HFILE)fd->secret->md.osfd, (PVOID)buf, len, &bytes); if (rv != NO_ERROR) { /* ERROR_HANDLE_EOF can only be returned by async io */ PR_ASSERT(rv != ERROR_HANDLE_EOF); if (rv == ERROR_BROKEN_PIPE) return 0; else { _PR_MD_MAP_READ_ERROR(rv); return -1; } } return (PRInt32)bytes;}PRInt32_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len){ PRInt32 bytes; int rv; rv = DosWrite((HFILE)fd->secret->md.osfd, (PVOID)buf, len, (PULONG)&bytes); if (rv != NO_ERROR) { _PR_MD_MAP_WRITE_ERROR(rv); return -1; } if (len != bytes) { rv = ERROR_DISK_FULL; _PR_MD_MAP_WRITE_ERROR(rv); return -1; } return bytes;} /* --- end _PR_MD_WRITE() --- */PRInt32_PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence){ PRInt32 rv; PRUword newLocation; rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, offset, whence, &newLocation); if (rv != NO_ERROR) { _PR_MD_MAP_LSEEK_ERROR(rv); return -1; } else return newLocation;}PRInt64_PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence){#ifdef NO_LONG_LONG PRInt64 result; PRInt32 rv, low = offset.lo, hi = offset.hi; PRUword newLocation; rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, low, whence, &newLocation); rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, hi, FILE_CURRENT, &newLocation); if (rv != NO_ERROR) { _PR_MD_MAP_LSEEK_ERROR(rv); hi = newLocation = -1; } result.lo = newLocation; result.hi = hi; return result;#else PRInt32 where, rc, lo = (PRInt32)offset, hi = (PRInt32)(offset >> 32); PRUint64 rv; PRUint32 newLocation, uhi; switch (whence) { case PR_SEEK_SET: where = FILE_BEGIN; break; case PR_SEEK_CUR: where = FILE_CURRENT; break; case PR_SEEK_END: where = FILE_END; break; default: PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return -1;} rc = DosSetFilePtr((HFILE)fd->secret->md.osfd, lo, where, (PULONG)&newLocation); if (rc != NO_ERROR) { _PR_MD_MAP_LSEEK_ERROR(rc); return -1; } uhi = (PRUint32)hi; PR_ASSERT((PRInt32)uhi >= 0); rv = uhi; PR_ASSERT((PRInt64)rv >= 0); rv = (rv << 32); PR_ASSERT((PRInt64)rv >= 0); rv += newLocation; PR_ASSERT((PRInt64)rv >= 0); return (PRInt64)rv;#endif}PRInt32_PR_MD_FSYNC(PRFileDesc *fd){ PRInt32 rc = DosResetBuffer((HFILE)fd->secret->md.osfd); if (rc != NO_ERROR) { if (rc != ERROR_ACCESS_DENIED) { _PR_MD_MAP_FSYNC_ERROR(rc); return -1; } } return 0;}PRInt32_MD_CloseFile(PRInt32 osfd){ PRInt32 rv; rv = DosClose((HFILE)osfd); if (rv != NO_ERROR) _PR_MD_MAP_CLOSE_ERROR(rv); return rv;}/* --- DIR IO ------------------------------------------------------------ */#define GetFileFromDIR(d) (d)->d_entry.achName#define GetFileAttr(d) (d)->d_entry.attrFilevoid FlipSlashes(char *cp, int len){ while (--len >= 0) { if (cp[0] == '/') { cp[0] = PR_DIRECTORY_SEPARATOR; } cp++; }}/***** Local implementations of standard Unix RTL functions which are not provided** by the VAC RTL.***/PRInt32_PR_MD_CLOSE_DIR(_MDDir *d){ PRInt32 rc; if ( d ) { rc = DosFindClose(d->d_hdl); if(rc == NO_ERROR){ d->magic = (PRUint32)-1; return PR_SUCCESS; } else { _PR_MD_MAP_CLOSEDIR_ERROR(rc); return PR_FAILURE; } } PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE;}PRStatus
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -