Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | /* OS2 IO module |
michael@0 | 7 | * |
michael@0 | 8 | * Assumes synchronous I/O. |
michael@0 | 9 | * |
michael@0 | 10 | */ |
michael@0 | 11 | |
michael@0 | 12 | #include "primpl.h" |
michael@0 | 13 | #include "prio.h" |
michael@0 | 14 | #include <ctype.h> |
michael@0 | 15 | #include <string.h> |
michael@0 | 16 | #include <limits.h> |
michael@0 | 17 | #include <dirent.h> |
michael@0 | 18 | #include <fcntl.h> |
michael@0 | 19 | #include <io.h> |
michael@0 | 20 | |
michael@0 | 21 | struct _MDLock _pr_ioq_lock; |
michael@0 | 22 | |
michael@0 | 23 | static PRBool isWSEB = PR_FALSE; /* whether we are using an OS/2 kernel that supports large files */ |
michael@0 | 24 | |
michael@0 | 25 | typedef APIRET (*DosOpenLType)(PSZ pszFileName, PHFILE pHf, PULONG pulAction, |
michael@0 | 26 | LONGLONG cbFile, ULONG ulAttribute, |
michael@0 | 27 | ULONG fsOpenFlags, ULONG fsOpenMode, |
michael@0 | 28 | PEAOP2 peaop2); |
michael@0 | 29 | |
michael@0 | 30 | typedef APIRET (*DosSetFileLocksLType)(HFILE hFile, PFILELOCKL pflUnlock, |
michael@0 | 31 | PFILELOCKL pflLock, ULONG timeout, |
michael@0 | 32 | ULONG flags); |
michael@0 | 33 | |
michael@0 | 34 | typedef APIRET (*DosSetFilePtrLType)(HFILE hFile, LONGLONG ib, ULONG method, |
michael@0 | 35 | PLONGLONG ibActual); |
michael@0 | 36 | |
michael@0 | 37 | DosOpenLType myDosOpenL; |
michael@0 | 38 | DosSetFileLocksLType myDosSetFileLocksL; |
michael@0 | 39 | DosSetFilePtrLType myDosSetFilePtrL; |
michael@0 | 40 | |
michael@0 | 41 | void |
michael@0 | 42 | _PR_MD_INIT_IO() |
michael@0 | 43 | { |
michael@0 | 44 | APIRET rc; |
michael@0 | 45 | HMODULE module; |
michael@0 | 46 | |
michael@0 | 47 | sock_init(); |
michael@0 | 48 | |
michael@0 | 49 | rc = DosLoadModule(NULL, 0, "DOSCALL1", &module); |
michael@0 | 50 | if (rc != NO_ERROR) |
michael@0 | 51 | { |
michael@0 | 52 | return; |
michael@0 | 53 | } |
michael@0 | 54 | rc = DosQueryProcAddr(module, 981, NULL, (PFN*) &myDosOpenL); |
michael@0 | 55 | if (rc != NO_ERROR) |
michael@0 | 56 | { |
michael@0 | 57 | return; |
michael@0 | 58 | } |
michael@0 | 59 | rc = DosQueryProcAddr(module, 986, NULL, (PFN*) &myDosSetFileLocksL); |
michael@0 | 60 | if (rc != NO_ERROR) |
michael@0 | 61 | { |
michael@0 | 62 | return; |
michael@0 | 63 | } |
michael@0 | 64 | rc = DosQueryProcAddr(module, 988, NULL, (PFN*) &myDosSetFilePtrL); |
michael@0 | 65 | if (rc != NO_ERROR) |
michael@0 | 66 | { |
michael@0 | 67 | return; |
michael@0 | 68 | } |
michael@0 | 69 | isWSEB = PR_TRUE; |
michael@0 | 70 | } |
michael@0 | 71 | |
michael@0 | 72 | PRStatus |
michael@0 | 73 | _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) |
michael@0 | 74 | { |
michael@0 | 75 | PRInt32 rv; |
michael@0 | 76 | ULONG count; |
michael@0 | 77 | |
michael@0 | 78 | PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? |
michael@0 | 79 | SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks); |
michael@0 | 80 | rv = DosWaitEventSem(thread->md.blocked_sema, msecs); |
michael@0 | 81 | DosResetEventSem(thread->md.blocked_sema, &count); |
michael@0 | 82 | switch(rv) |
michael@0 | 83 | { |
michael@0 | 84 | case NO_ERROR: |
michael@0 | 85 | return PR_SUCCESS; |
michael@0 | 86 | break; |
michael@0 | 87 | case ERROR_TIMEOUT: |
michael@0 | 88 | _PR_THREAD_LOCK(thread); |
michael@0 | 89 | if (thread->state == _PR_IO_WAIT) { |
michael@0 | 90 | ; |
michael@0 | 91 | } else { |
michael@0 | 92 | if (thread->wait.cvar != NULL) { |
michael@0 | 93 | thread->wait.cvar = NULL; |
michael@0 | 94 | _PR_THREAD_UNLOCK(thread); |
michael@0 | 95 | } else { |
michael@0 | 96 | /* The CVAR was notified just as the timeout |
michael@0 | 97 | * occurred. This led to us being notified twice. |
michael@0 | 98 | * call SemRequest() to clear the semaphore. |
michael@0 | 99 | */ |
michael@0 | 100 | _PR_THREAD_UNLOCK(thread); |
michael@0 | 101 | rv = DosWaitEventSem(thread->md.blocked_sema, 0); |
michael@0 | 102 | DosResetEventSem(thread->md.blocked_sema, &count); |
michael@0 | 103 | PR_ASSERT(rv == NO_ERROR); |
michael@0 | 104 | } |
michael@0 | 105 | } |
michael@0 | 106 | return PR_SUCCESS; |
michael@0 | 107 | break; |
michael@0 | 108 | default: |
michael@0 | 109 | break; |
michael@0 | 110 | } |
michael@0 | 111 | return PR_FAILURE; |
michael@0 | 112 | } |
michael@0 | 113 | PRStatus |
michael@0 | 114 | _PR_MD_WAKEUP_WAITER(PRThread *thread) |
michael@0 | 115 | { |
michael@0 | 116 | if ( _PR_IS_NATIVE_THREAD(thread) ) |
michael@0 | 117 | { |
michael@0 | 118 | if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR) |
michael@0 | 119 | return PR_FAILURE; |
michael@0 | 120 | else |
michael@0 | 121 | return PR_SUCCESS; |
michael@0 | 122 | } |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | |
michael@0 | 126 | /* --- FILE IO ----------------------------------------------------------- */ |
michael@0 | 127 | /* |
michael@0 | 128 | * _PR_MD_OPEN() -- Open a file |
michael@0 | 129 | * |
michael@0 | 130 | * returns: a fileHandle |
michael@0 | 131 | * |
michael@0 | 132 | * The NSPR open flags (osflags) are translated into flags for OS/2 |
michael@0 | 133 | * |
michael@0 | 134 | * Mode seems to be passed in as a unix style file permissions argument |
michael@0 | 135 | * as in 0666, in the case of opening the logFile. |
michael@0 | 136 | * |
michael@0 | 137 | */ |
michael@0 | 138 | PRInt32 |
michael@0 | 139 | _PR_MD_OPEN(const char *name, PRIntn osflags, int mode) |
michael@0 | 140 | { |
michael@0 | 141 | HFILE file; |
michael@0 | 142 | PRInt32 access = OPEN_SHARE_DENYNONE; |
michael@0 | 143 | PRInt32 flags = 0L; |
michael@0 | 144 | APIRET rc = 0; |
michael@0 | 145 | PRUword actionTaken; |
michael@0 | 146 | |
michael@0 | 147 | #ifdef MOZ_OS2_HIGH_MEMORY |
michael@0 | 148 | /* |
michael@0 | 149 | * All the pointer arguments (&file, &actionTaken and name) have to be in |
michael@0 | 150 | * low memory for DosOpen to use them. |
michael@0 | 151 | * The following moves name to low memory. |
michael@0 | 152 | */ |
michael@0 | 153 | if ((ULONG)name >= 0x20000000) |
michael@0 | 154 | { |
michael@0 | 155 | size_t len = strlen(name) + 1; |
michael@0 | 156 | char *copy = (char *)alloca(len); |
michael@0 | 157 | memcpy(copy, name, len); |
michael@0 | 158 | name = copy; |
michael@0 | 159 | } |
michael@0 | 160 | #endif |
michael@0 | 161 | |
michael@0 | 162 | if (osflags & PR_SYNC) access |= OPEN_FLAGS_WRITE_THROUGH; |
michael@0 | 163 | |
michael@0 | 164 | if (osflags & PR_RDONLY) |
michael@0 | 165 | access |= OPEN_ACCESS_READONLY; |
michael@0 | 166 | else if (osflags & PR_WRONLY) |
michael@0 | 167 | access |= OPEN_ACCESS_WRITEONLY; |
michael@0 | 168 | else if(osflags & PR_RDWR) |
michael@0 | 169 | access |= OPEN_ACCESS_READWRITE; |
michael@0 | 170 | |
michael@0 | 171 | if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) |
michael@0 | 172 | { |
michael@0 | 173 | flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; |
michael@0 | 174 | } |
michael@0 | 175 | else if (osflags & PR_CREATE_FILE) |
michael@0 | 176 | { |
michael@0 | 177 | if (osflags & PR_TRUNCATE) |
michael@0 | 178 | flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS; |
michael@0 | 179 | else |
michael@0 | 180 | flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; |
michael@0 | 181 | } |
michael@0 | 182 | else |
michael@0 | 183 | { |
michael@0 | 184 | if (osflags & PR_TRUNCATE) |
michael@0 | 185 | flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS; |
michael@0 | 186 | else |
michael@0 | 187 | flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; |
michael@0 | 188 | } |
michael@0 | 189 | |
michael@0 | 190 | do { |
michael@0 | 191 | if (isWSEB) |
michael@0 | 192 | { |
michael@0 | 193 | rc = myDosOpenL((char*)name, |
michael@0 | 194 | &file, /* file handle if successful */ |
michael@0 | 195 | &actionTaken, /* reason for failure */ |
michael@0 | 196 | 0, /* initial size of new file */ |
michael@0 | 197 | FILE_NORMAL, /* file system attributes */ |
michael@0 | 198 | flags, /* Open flags */ |
michael@0 | 199 | access, /* Open mode and rights */ |
michael@0 | 200 | 0); /* OS/2 Extended Attributes */ |
michael@0 | 201 | } |
michael@0 | 202 | else |
michael@0 | 203 | { |
michael@0 | 204 | rc = DosOpen((char*)name, |
michael@0 | 205 | &file, /* file handle if successful */ |
michael@0 | 206 | &actionTaken, /* reason for failure */ |
michael@0 | 207 | 0, /* initial size of new file */ |
michael@0 | 208 | FILE_NORMAL, /* file system attributes */ |
michael@0 | 209 | flags, /* Open flags */ |
michael@0 | 210 | access, /* Open mode and rights */ |
michael@0 | 211 | 0); /* OS/2 Extended Attributes */ |
michael@0 | 212 | }; |
michael@0 | 213 | if (rc == ERROR_TOO_MANY_OPEN_FILES) { |
michael@0 | 214 | ULONG CurMaxFH = 0; |
michael@0 | 215 | LONG ReqCount = 20; |
michael@0 | 216 | APIRET rc2; |
michael@0 | 217 | rc2 = DosSetRelMaxFH(&ReqCount, &CurMaxFH); |
michael@0 | 218 | if (rc2 != NO_ERROR) { |
michael@0 | 219 | break; |
michael@0 | 220 | } |
michael@0 | 221 | } |
michael@0 | 222 | } while (rc == ERROR_TOO_MANY_OPEN_FILES); |
michael@0 | 223 | |
michael@0 | 224 | if (rc != NO_ERROR) { |
michael@0 | 225 | _PR_MD_MAP_OPEN_ERROR(rc); |
michael@0 | 226 | return -1; |
michael@0 | 227 | } |
michael@0 | 228 | |
michael@0 | 229 | return (PRInt32)file; |
michael@0 | 230 | } |
michael@0 | 231 | |
michael@0 | 232 | PRInt32 |
michael@0 | 233 | _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len) |
michael@0 | 234 | { |
michael@0 | 235 | ULONG bytes; |
michael@0 | 236 | int rv; |
michael@0 | 237 | |
michael@0 | 238 | rv = DosRead((HFILE)fd->secret->md.osfd, |
michael@0 | 239 | (PVOID)buf, |
michael@0 | 240 | len, |
michael@0 | 241 | &bytes); |
michael@0 | 242 | |
michael@0 | 243 | if (rv != NO_ERROR) |
michael@0 | 244 | { |
michael@0 | 245 | /* ERROR_HANDLE_EOF can only be returned by async io */ |
michael@0 | 246 | PR_ASSERT(rv != ERROR_HANDLE_EOF); |
michael@0 | 247 | if (rv == ERROR_BROKEN_PIPE) |
michael@0 | 248 | return 0; |
michael@0 | 249 | else { |
michael@0 | 250 | _PR_MD_MAP_READ_ERROR(rv); |
michael@0 | 251 | return -1; |
michael@0 | 252 | } |
michael@0 | 253 | } |
michael@0 | 254 | return (PRInt32)bytes; |
michael@0 | 255 | } |
michael@0 | 256 | |
michael@0 | 257 | PRInt32 |
michael@0 | 258 | _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len) |
michael@0 | 259 | { |
michael@0 | 260 | PRInt32 bytes; |
michael@0 | 261 | int rv; |
michael@0 | 262 | |
michael@0 | 263 | rv = DosWrite((HFILE)fd->secret->md.osfd, |
michael@0 | 264 | (PVOID)buf, |
michael@0 | 265 | len, |
michael@0 | 266 | (PULONG)&bytes); |
michael@0 | 267 | |
michael@0 | 268 | if (rv != NO_ERROR) |
michael@0 | 269 | { |
michael@0 | 270 | _PR_MD_MAP_WRITE_ERROR(rv); |
michael@0 | 271 | return -1; |
michael@0 | 272 | } |
michael@0 | 273 | |
michael@0 | 274 | if (len != bytes) { |
michael@0 | 275 | rv = ERROR_DISK_FULL; |
michael@0 | 276 | _PR_MD_MAP_WRITE_ERROR(rv); |
michael@0 | 277 | return -1; |
michael@0 | 278 | } |
michael@0 | 279 | |
michael@0 | 280 | return bytes; |
michael@0 | 281 | } /* --- end _PR_MD_WRITE() --- */ |
michael@0 | 282 | |
michael@0 | 283 | PRInt32 |
michael@0 | 284 | _PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence) |
michael@0 | 285 | { |
michael@0 | 286 | PRInt32 rv; |
michael@0 | 287 | PRUword newLocation; |
michael@0 | 288 | |
michael@0 | 289 | rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, offset, whence, &newLocation); |
michael@0 | 290 | |
michael@0 | 291 | if (rv != NO_ERROR) { |
michael@0 | 292 | _PR_MD_MAP_LSEEK_ERROR(rv); |
michael@0 | 293 | return -1; |
michael@0 | 294 | } else |
michael@0 | 295 | return newLocation; |
michael@0 | 296 | } |
michael@0 | 297 | |
michael@0 | 298 | PRInt64 |
michael@0 | 299 | _PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence) |
michael@0 | 300 | { |
michael@0 | 301 | #ifdef NO_LONG_LONG |
michael@0 | 302 | PRInt64 result; |
michael@0 | 303 | PRInt32 rv, low = offset.lo, hi = offset.hi; |
michael@0 | 304 | PRUword newLocation; |
michael@0 | 305 | |
michael@0 | 306 | rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, low, whence, &newLocation); |
michael@0 | 307 | rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, hi, FILE_CURRENT, &newLocation); |
michael@0 | 308 | |
michael@0 | 309 | if (rv != NO_ERROR) { |
michael@0 | 310 | _PR_MD_MAP_LSEEK_ERROR(rv); |
michael@0 | 311 | hi = newLocation = -1; |
michael@0 | 312 | } |
michael@0 | 313 | |
michael@0 | 314 | result.lo = newLocation; |
michael@0 | 315 | result.hi = hi; |
michael@0 | 316 | return result; |
michael@0 | 317 | |
michael@0 | 318 | #else |
michael@0 | 319 | PRInt32 where, rc, lo = (PRInt32)offset, hi = (PRInt32)(offset >> 32); |
michael@0 | 320 | PRUint64 rv; |
michael@0 | 321 | PRUint32 newLocation, uhi; |
michael@0 | 322 | PRUint64 newLocationL; |
michael@0 | 323 | |
michael@0 | 324 | switch (whence) |
michael@0 | 325 | { |
michael@0 | 326 | case PR_SEEK_SET: |
michael@0 | 327 | where = FILE_BEGIN; |
michael@0 | 328 | break; |
michael@0 | 329 | case PR_SEEK_CUR: |
michael@0 | 330 | where = FILE_CURRENT; |
michael@0 | 331 | break; |
michael@0 | 332 | case PR_SEEK_END: |
michael@0 | 333 | where = FILE_END; |
michael@0 | 334 | break; |
michael@0 | 335 | default: |
michael@0 | 336 | PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); |
michael@0 | 337 | return -1; |
michael@0 | 338 | } |
michael@0 | 339 | if (isWSEB) |
michael@0 | 340 | { |
michael@0 | 341 | rc = myDosSetFilePtrL((HFILE)fd->secret->md.osfd, offset, where, (PLONGLONG)&newLocationL); |
michael@0 | 342 | } |
michael@0 | 343 | else |
michael@0 | 344 | { |
michael@0 | 345 | rc = DosSetFilePtr((HFILE)fd->secret->md.osfd, lo, where, (PULONG)&newLocation); |
michael@0 | 346 | } |
michael@0 | 347 | |
michael@0 | 348 | if (rc != NO_ERROR) { |
michael@0 | 349 | _PR_MD_MAP_LSEEK_ERROR(rc); |
michael@0 | 350 | return -1; |
michael@0 | 351 | } |
michael@0 | 352 | |
michael@0 | 353 | if (isWSEB) |
michael@0 | 354 | { |
michael@0 | 355 | return newLocationL; |
michael@0 | 356 | } |
michael@0 | 357 | |
michael@0 | 358 | uhi = (PRUint32)hi; |
michael@0 | 359 | PR_ASSERT((PRInt32)uhi >= 0); |
michael@0 | 360 | rv = uhi; |
michael@0 | 361 | PR_ASSERT((PRInt64)rv >= 0); |
michael@0 | 362 | rv = (rv << 32); |
michael@0 | 363 | PR_ASSERT((PRInt64)rv >= 0); |
michael@0 | 364 | rv += newLocation; |
michael@0 | 365 | PR_ASSERT((PRInt64)rv >= 0); |
michael@0 | 366 | return (PRInt64)rv; |
michael@0 | 367 | #endif |
michael@0 | 368 | } |
michael@0 | 369 | |
michael@0 | 370 | PRInt32 |
michael@0 | 371 | _PR_MD_FSYNC(PRFileDesc *fd) |
michael@0 | 372 | { |
michael@0 | 373 | PRInt32 rc = DosResetBuffer((HFILE)fd->secret->md.osfd); |
michael@0 | 374 | |
michael@0 | 375 | if (rc != NO_ERROR) { |
michael@0 | 376 | if (rc != ERROR_ACCESS_DENIED) { |
michael@0 | 377 | _PR_MD_MAP_FSYNC_ERROR(rc); |
michael@0 | 378 | return -1; |
michael@0 | 379 | } |
michael@0 | 380 | } |
michael@0 | 381 | return 0; |
michael@0 | 382 | } |
michael@0 | 383 | |
michael@0 | 384 | PRInt32 |
michael@0 | 385 | _MD_CloseFile(PRInt32 osfd) |
michael@0 | 386 | { |
michael@0 | 387 | PRInt32 rv; |
michael@0 | 388 | |
michael@0 | 389 | rv = DosClose((HFILE)osfd); |
michael@0 | 390 | if (rv != NO_ERROR) |
michael@0 | 391 | _PR_MD_MAP_CLOSE_ERROR(rv); |
michael@0 | 392 | return rv; |
michael@0 | 393 | } |
michael@0 | 394 | |
michael@0 | 395 | |
michael@0 | 396 | /* --- DIR IO ------------------------------------------------------------ */ |
michael@0 | 397 | #define GetFileFromDIR(d) (isWSEB?(d)->d_entry.large.achName:(d)->d_entry.small.achName) |
michael@0 | 398 | #define GetFileAttr(d) (isWSEB?(d)->d_entry.large.attrFile:(d)->d_entry.small.attrFile) |
michael@0 | 399 | |
michael@0 | 400 | void FlipSlashes(char *cp, int len) |
michael@0 | 401 | { |
michael@0 | 402 | while (--len >= 0) { |
michael@0 | 403 | if (cp[0] == '/') { |
michael@0 | 404 | cp[0] = PR_DIRECTORY_SEPARATOR; |
michael@0 | 405 | } |
michael@0 | 406 | cp++; |
michael@0 | 407 | } |
michael@0 | 408 | } |
michael@0 | 409 | |
michael@0 | 410 | /* |
michael@0 | 411 | ** |
michael@0 | 412 | ** Local implementations of standard Unix RTL functions which are not provided |
michael@0 | 413 | ** by the VAC RTL. |
michael@0 | 414 | ** |
michael@0 | 415 | */ |
michael@0 | 416 | |
michael@0 | 417 | PRInt32 |
michael@0 | 418 | _PR_MD_CLOSE_DIR(_MDDir *d) |
michael@0 | 419 | { |
michael@0 | 420 | PRInt32 rc; |
michael@0 | 421 | |
michael@0 | 422 | if ( d ) { |
michael@0 | 423 | rc = DosFindClose(d->d_hdl); |
michael@0 | 424 | if(rc == NO_ERROR){ |
michael@0 | 425 | d->magic = (PRUint32)-1; |
michael@0 | 426 | return PR_SUCCESS; |
michael@0 | 427 | } else { |
michael@0 | 428 | _PR_MD_MAP_CLOSEDIR_ERROR(rc); |
michael@0 | 429 | return PR_FAILURE; |
michael@0 | 430 | } |
michael@0 | 431 | } |
michael@0 | 432 | PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); |
michael@0 | 433 | return PR_FAILURE; |
michael@0 | 434 | } |
michael@0 | 435 | |
michael@0 | 436 | |
michael@0 | 437 | PRStatus |
michael@0 | 438 | _PR_MD_OPEN_DIR(_MDDir *d, const char *name) |
michael@0 | 439 | { |
michael@0 | 440 | char filename[ CCHMAXPATH ]; |
michael@0 | 441 | PRUword numEntries, rc; |
michael@0 | 442 | |
michael@0 | 443 | numEntries = 1; |
michael@0 | 444 | |
michael@0 | 445 | PR_snprintf(filename, CCHMAXPATH, "%s%s%s", |
michael@0 | 446 | name, PR_DIRECTORY_SEPARATOR_STR, "*.*"); |
michael@0 | 447 | FlipSlashes( filename, strlen(filename) ); |
michael@0 | 448 | |
michael@0 | 449 | d->d_hdl = HDIR_CREATE; |
michael@0 | 450 | |
michael@0 | 451 | if (isWSEB) |
michael@0 | 452 | { |
michael@0 | 453 | rc = DosFindFirst( filename, |
michael@0 | 454 | &d->d_hdl, |
michael@0 | 455 | FILE_DIRECTORY | FILE_HIDDEN, |
michael@0 | 456 | &(d->d_entry.large), |
michael@0 | 457 | sizeof(d->d_entry.large), |
michael@0 | 458 | &numEntries, |
michael@0 | 459 | FIL_STANDARDL); |
michael@0 | 460 | } |
michael@0 | 461 | else |
michael@0 | 462 | { |
michael@0 | 463 | rc = DosFindFirst( filename, |
michael@0 | 464 | &d->d_hdl, |
michael@0 | 465 | FILE_DIRECTORY | FILE_HIDDEN, |
michael@0 | 466 | &(d->d_entry.small), |
michael@0 | 467 | sizeof(d->d_entry.small), |
michael@0 | 468 | &numEntries, |
michael@0 | 469 | FIL_STANDARD); |
michael@0 | 470 | } |
michael@0 | 471 | if ( rc != NO_ERROR ) { |
michael@0 | 472 | _PR_MD_MAP_OPENDIR_ERROR(rc); |
michael@0 | 473 | return PR_FAILURE; |
michael@0 | 474 | } |
michael@0 | 475 | d->firstEntry = PR_TRUE; |
michael@0 | 476 | d->magic = _MD_MAGIC_DIR; |
michael@0 | 477 | return PR_SUCCESS; |
michael@0 | 478 | } |
michael@0 | 479 | |
michael@0 | 480 | char * |
michael@0 | 481 | _PR_MD_READ_DIR(_MDDir *d, PRIntn flags) |
michael@0 | 482 | { |
michael@0 | 483 | PRUword numFiles = 1; |
michael@0 | 484 | BOOL rv; |
michael@0 | 485 | char *fileName; |
michael@0 | 486 | USHORT fileAttr; |
michael@0 | 487 | |
michael@0 | 488 | if ( d ) { |
michael@0 | 489 | while (1) { |
michael@0 | 490 | if (d->firstEntry) { |
michael@0 | 491 | d->firstEntry = PR_FALSE; |
michael@0 | 492 | rv = NO_ERROR; |
michael@0 | 493 | } else { |
michael@0 | 494 | rv = DosFindNext(d->d_hdl, |
michael@0 | 495 | &(d->d_entry), |
michael@0 | 496 | sizeof(d->d_entry), |
michael@0 | 497 | &numFiles); |
michael@0 | 498 | } |
michael@0 | 499 | if (rv != NO_ERROR) { |
michael@0 | 500 | break; |
michael@0 | 501 | } |
michael@0 | 502 | fileName = GetFileFromDIR(d); |
michael@0 | 503 | fileAttr = GetFileAttr(d); |
michael@0 | 504 | if ( (flags & PR_SKIP_DOT) && |
michael@0 | 505 | (fileName[0] == '.') && (fileName[1] == '\0')) |
michael@0 | 506 | continue; |
michael@0 | 507 | if ( (flags & PR_SKIP_DOT_DOT) && |
michael@0 | 508 | (fileName[0] == '.') && (fileName[1] == '.') && |
michael@0 | 509 | (fileName[2] == '\0')) |
michael@0 | 510 | continue; |
michael@0 | 511 | /* |
michael@0 | 512 | * XXX |
michael@0 | 513 | * Is this the correct definition of a hidden file on OS/2? |
michael@0 | 514 | */ |
michael@0 | 515 | if ((flags & PR_SKIP_NONE) && (fileAttr & FILE_HIDDEN)) |
michael@0 | 516 | return fileName; |
michael@0 | 517 | else if ((flags & PR_SKIP_HIDDEN) && (fileAttr & FILE_HIDDEN)) |
michael@0 | 518 | continue; |
michael@0 | 519 | return fileName; |
michael@0 | 520 | } |
michael@0 | 521 | PR_ASSERT(NO_ERROR != rv); |
michael@0 | 522 | _PR_MD_MAP_READDIR_ERROR(rv); |
michael@0 | 523 | return NULL; |
michael@0 | 524 | } |
michael@0 | 525 | PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); |
michael@0 | 526 | return NULL; |
michael@0 | 527 | } |
michael@0 | 528 | |
michael@0 | 529 | PRInt32 |
michael@0 | 530 | _PR_MD_DELETE(const char *name) |
michael@0 | 531 | { |
michael@0 | 532 | PRInt32 rc = DosDelete((char*)name); |
michael@0 | 533 | if(rc == NO_ERROR) { |
michael@0 | 534 | return 0; |
michael@0 | 535 | } else { |
michael@0 | 536 | _PR_MD_MAP_DELETE_ERROR(rc); |
michael@0 | 537 | return -1; |
michael@0 | 538 | } |
michael@0 | 539 | } |
michael@0 | 540 | |
michael@0 | 541 | PRInt32 |
michael@0 | 542 | _PR_MD_STAT(const char *fn, struct stat *info) |
michael@0 | 543 | { |
michael@0 | 544 | PRInt32 rv; |
michael@0 | 545 | char filename[CCHMAXPATH]; |
michael@0 | 546 | |
michael@0 | 547 | PR_snprintf(filename, CCHMAXPATH, "%s", fn); |
michael@0 | 548 | FlipSlashes(filename, strlen(filename)); |
michael@0 | 549 | |
michael@0 | 550 | rv = _stat((char*)filename, info); |
michael@0 | 551 | if (-1 == rv) { |
michael@0 | 552 | /* |
michael@0 | 553 | * Check for MSVC runtime library _stat() bug. |
michael@0 | 554 | * (It's really a bug in FindFirstFile().) |
michael@0 | 555 | * If a pathname ends in a backslash or slash, |
michael@0 | 556 | * e.g., c:\temp\ or c:/temp/, _stat() will fail. |
michael@0 | 557 | * Note: a pathname ending in a slash (e.g., c:/temp/) |
michael@0 | 558 | * can be handled by _stat() on NT but not on Win95. |
michael@0 | 559 | * |
michael@0 | 560 | * We remove the backslash or slash at the end and |
michael@0 | 561 | * try again. |
michael@0 | 562 | * |
michael@0 | 563 | * Not sure if this happens on OS/2 or not, |
michael@0 | 564 | * but it doesn't hurt to be careful. |
michael@0 | 565 | */ |
michael@0 | 566 | |
michael@0 | 567 | int len = strlen(fn); |
michael@0 | 568 | if (len > 0 && len <= _MAX_PATH |
michael@0 | 569 | && (fn[len - 1] == '\\' || fn[len - 1] == '/')) { |
michael@0 | 570 | char newfn[_MAX_PATH + 1]; |
michael@0 | 571 | |
michael@0 | 572 | strcpy(newfn, fn); |
michael@0 | 573 | newfn[len - 1] = '\0'; |
michael@0 | 574 | rv = _stat(newfn, info); |
michael@0 | 575 | } |
michael@0 | 576 | } |
michael@0 | 577 | |
michael@0 | 578 | if (-1 == rv) { |
michael@0 | 579 | _PR_MD_MAP_STAT_ERROR(errno); |
michael@0 | 580 | } |
michael@0 | 581 | return rv; |
michael@0 | 582 | } |
michael@0 | 583 | |
michael@0 | 584 | PRInt32 |
michael@0 | 585 | _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info) |
michael@0 | 586 | { |
michael@0 | 587 | struct stat sb; |
michael@0 | 588 | PRInt32 rv; |
michael@0 | 589 | PRInt64 s, s2us; |
michael@0 | 590 | |
michael@0 | 591 | if ( (rv = _PR_MD_STAT(fn, &sb)) == 0 ) { |
michael@0 | 592 | if (info) { |
michael@0 | 593 | if (S_IFREG & sb.st_mode) |
michael@0 | 594 | info->type = PR_FILE_FILE ; |
michael@0 | 595 | else if (S_IFDIR & sb.st_mode) |
michael@0 | 596 | info->type = PR_FILE_DIRECTORY; |
michael@0 | 597 | else |
michael@0 | 598 | info->type = PR_FILE_OTHER; |
michael@0 | 599 | info->size = sb.st_size; |
michael@0 | 600 | LL_I2L(s2us, PR_USEC_PER_SEC); |
michael@0 | 601 | LL_I2L(s, sb.st_mtime); |
michael@0 | 602 | LL_MUL(s, s, s2us); |
michael@0 | 603 | info->modifyTime = s; |
michael@0 | 604 | LL_I2L(s, sb.st_ctime); |
michael@0 | 605 | LL_MUL(s, s, s2us); |
michael@0 | 606 | info->creationTime = s; |
michael@0 | 607 | } |
michael@0 | 608 | } |
michael@0 | 609 | return rv; |
michael@0 | 610 | } |
michael@0 | 611 | |
michael@0 | 612 | PRInt32 |
michael@0 | 613 | _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info) |
michael@0 | 614 | { |
michael@0 | 615 | PRFileInfo info32; |
michael@0 | 616 | PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32); |
michael@0 | 617 | if (rv != 0) |
michael@0 | 618 | { |
michael@0 | 619 | return rv; |
michael@0 | 620 | } |
michael@0 | 621 | info->type = info32.type; |
michael@0 | 622 | LL_UI2L(info->size,info32.size); |
michael@0 | 623 | info->modifyTime = info32.modifyTime; |
michael@0 | 624 | info->creationTime = info32.creationTime; |
michael@0 | 625 | |
michael@0 | 626 | if (isWSEB) |
michael@0 | 627 | { |
michael@0 | 628 | APIRET rc ; |
michael@0 | 629 | FILESTATUS3L fstatus; |
michael@0 | 630 | |
michael@0 | 631 | rc = DosQueryPathInfo(fn, FIL_STANDARDL, &fstatus, sizeof(fstatus)); |
michael@0 | 632 | |
michael@0 | 633 | if (NO_ERROR != rc) |
michael@0 | 634 | { |
michael@0 | 635 | _PR_MD_MAP_OPEN_ERROR(rc); |
michael@0 | 636 | return -1; |
michael@0 | 637 | } |
michael@0 | 638 | |
michael@0 | 639 | if (! (fstatus.attrFile & FILE_DIRECTORY)) |
michael@0 | 640 | { |
michael@0 | 641 | info->size = fstatus.cbFile; |
michael@0 | 642 | } |
michael@0 | 643 | } |
michael@0 | 644 | |
michael@0 | 645 | return rv; |
michael@0 | 646 | } |
michael@0 | 647 | |
michael@0 | 648 | PRInt32 |
michael@0 | 649 | _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info) |
michael@0 | 650 | { |
michael@0 | 651 | /* For once, the VAC compiler/library did a nice thing. |
michael@0 | 652 | * The file handle used by the C runtime is the same one |
michael@0 | 653 | * returned by the OS when you call DosOpen(). This means |
michael@0 | 654 | * that you can take an OS HFILE and use it with C file |
michael@0 | 655 | * functions. The only caveat is that you have to call |
michael@0 | 656 | * _setmode() first to initialize some junk. This is |
michael@0 | 657 | * immensely useful because I did not have a clue how to |
michael@0 | 658 | * implement this function otherwise. The windows folks |
michael@0 | 659 | * took the source from the Microsoft C library source, but |
michael@0 | 660 | * IBM wasn't kind enough to ship the source with VAC. |
michael@0 | 661 | * On second thought, the needed function could probably |
michael@0 | 662 | * be gotten from the OS/2 GNU library source, but the |
michael@0 | 663 | * point is now moot. |
michael@0 | 664 | */ |
michael@0 | 665 | struct stat hinfo; |
michael@0 | 666 | PRInt64 s, s2us; |
michael@0 | 667 | |
michael@0 | 668 | _setmode(fd->secret->md.osfd, O_BINARY); |
michael@0 | 669 | if(fstat((int)fd->secret->md.osfd, &hinfo) != NO_ERROR) { |
michael@0 | 670 | _PR_MD_MAP_FSTAT_ERROR(errno); |
michael@0 | 671 | return -1; |
michael@0 | 672 | } |
michael@0 | 673 | |
michael@0 | 674 | if (hinfo.st_mode & S_IFDIR) |
michael@0 | 675 | info->type = PR_FILE_DIRECTORY; |
michael@0 | 676 | else |
michael@0 | 677 | info->type = PR_FILE_FILE; |
michael@0 | 678 | |
michael@0 | 679 | info->size = hinfo.st_size; |
michael@0 | 680 | LL_I2L(s2us, PR_USEC_PER_SEC); |
michael@0 | 681 | LL_I2L(s, hinfo.st_mtime); |
michael@0 | 682 | LL_MUL(s, s, s2us); |
michael@0 | 683 | info->modifyTime = s; |
michael@0 | 684 | LL_I2L(s, hinfo.st_ctime); |
michael@0 | 685 | LL_MUL(s, s, s2us); |
michael@0 | 686 | info->creationTime = s; |
michael@0 | 687 | |
michael@0 | 688 | return 0; |
michael@0 | 689 | } |
michael@0 | 690 | |
michael@0 | 691 | PRInt32 |
michael@0 | 692 | _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info) |
michael@0 | 693 | { |
michael@0 | 694 | PRFileInfo info32; |
michael@0 | 695 | PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32); |
michael@0 | 696 | if (0 == rv) |
michael@0 | 697 | { |
michael@0 | 698 | info->type = info32.type; |
michael@0 | 699 | LL_UI2L(info->size,info32.size); |
michael@0 | 700 | |
michael@0 | 701 | info->modifyTime = info32.modifyTime; |
michael@0 | 702 | info->creationTime = info32.creationTime; |
michael@0 | 703 | } |
michael@0 | 704 | |
michael@0 | 705 | if (isWSEB) |
michael@0 | 706 | { |
michael@0 | 707 | APIRET rc ; |
michael@0 | 708 | FILESTATUS3L fstatus; |
michael@0 | 709 | |
michael@0 | 710 | rc = DosQueryFileInfo(fd->secret->md.osfd, FIL_STANDARDL, &fstatus, sizeof(fstatus)); |
michael@0 | 711 | |
michael@0 | 712 | if (NO_ERROR != rc) |
michael@0 | 713 | { |
michael@0 | 714 | _PR_MD_MAP_OPEN_ERROR(rc); |
michael@0 | 715 | return -1; |
michael@0 | 716 | } |
michael@0 | 717 | |
michael@0 | 718 | if (! (fstatus.attrFile & FILE_DIRECTORY)) |
michael@0 | 719 | { |
michael@0 | 720 | info->size = fstatus.cbFile; |
michael@0 | 721 | } |
michael@0 | 722 | } |
michael@0 | 723 | |
michael@0 | 724 | return rv; |
michael@0 | 725 | } |
michael@0 | 726 | |
michael@0 | 727 | |
michael@0 | 728 | PRInt32 |
michael@0 | 729 | _PR_MD_RENAME(const char *from, const char *to) |
michael@0 | 730 | { |
michael@0 | 731 | PRInt32 rc; |
michael@0 | 732 | /* Does this work with dot-relative pathnames? */ |
michael@0 | 733 | if ( (rc = DosMove((char *)from, (char *)to)) == NO_ERROR) { |
michael@0 | 734 | return 0; |
michael@0 | 735 | } else { |
michael@0 | 736 | _PR_MD_MAP_RENAME_ERROR(rc); |
michael@0 | 737 | return -1; |
michael@0 | 738 | } |
michael@0 | 739 | } |
michael@0 | 740 | |
michael@0 | 741 | PRInt32 |
michael@0 | 742 | _PR_MD_ACCESS(const char *name, PRAccessHow how) |
michael@0 | 743 | { |
michael@0 | 744 | PRInt32 rv; |
michael@0 | 745 | switch (how) { |
michael@0 | 746 | case PR_ACCESS_WRITE_OK: |
michael@0 | 747 | rv = access(name, 02); |
michael@0 | 748 | break; |
michael@0 | 749 | case PR_ACCESS_READ_OK: |
michael@0 | 750 | rv = access(name, 04); |
michael@0 | 751 | break; |
michael@0 | 752 | case PR_ACCESS_EXISTS: |
michael@0 | 753 | return access(name, 00); |
michael@0 | 754 | break; |
michael@0 | 755 | default: |
michael@0 | 756 | PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); |
michael@0 | 757 | return -1; |
michael@0 | 758 | } |
michael@0 | 759 | if (rv < 0) |
michael@0 | 760 | _PR_MD_MAP_ACCESS_ERROR(errno); |
michael@0 | 761 | return rv; |
michael@0 | 762 | } |
michael@0 | 763 | |
michael@0 | 764 | PRInt32 |
michael@0 | 765 | _PR_MD_MKDIR(const char *name, PRIntn mode) |
michael@0 | 766 | { |
michael@0 | 767 | PRInt32 rc; |
michael@0 | 768 | /* XXXMB - how to translate the "mode"??? */ |
michael@0 | 769 | if ((rc = DosCreateDir((char *)name, NULL))== NO_ERROR) { |
michael@0 | 770 | return 0; |
michael@0 | 771 | } else { |
michael@0 | 772 | _PR_MD_MAP_MKDIR_ERROR(rc); |
michael@0 | 773 | return -1; |
michael@0 | 774 | } |
michael@0 | 775 | } |
michael@0 | 776 | |
michael@0 | 777 | PRInt32 |
michael@0 | 778 | _PR_MD_RMDIR(const char *name) |
michael@0 | 779 | { |
michael@0 | 780 | PRInt32 rc; |
michael@0 | 781 | if ( (rc = DosDeleteDir((char *)name)) == NO_ERROR) { |
michael@0 | 782 | return 0; |
michael@0 | 783 | } else { |
michael@0 | 784 | _PR_MD_MAP_RMDIR_ERROR(rc); |
michael@0 | 785 | return -1; |
michael@0 | 786 | } |
michael@0 | 787 | } |
michael@0 | 788 | |
michael@0 | 789 | PRStatus |
michael@0 | 790 | _PR_MD_LOCKFILE(PRInt32 f) |
michael@0 | 791 | { |
michael@0 | 792 | PRInt32 rv; |
michael@0 | 793 | FILELOCK lock, unlock; |
michael@0 | 794 | FILELOCKL lockL, unlockL; |
michael@0 | 795 | |
michael@0 | 796 | lock.lOffset = 0; |
michael@0 | 797 | lockL.lOffset = 0; |
michael@0 | 798 | lock.lRange = 0xffffffff; |
michael@0 | 799 | lockL.lRange = 0xffffffffffffffff; |
michael@0 | 800 | unlock.lOffset = 0; |
michael@0 | 801 | unlock.lRange = 0; |
michael@0 | 802 | unlockL.lOffset = 0; |
michael@0 | 803 | unlockL.lRange = 0; |
michael@0 | 804 | |
michael@0 | 805 | /* |
michael@0 | 806 | * loop trying to DosSetFileLocks(), |
michael@0 | 807 | * pause for a few miliseconds when can't get the lock |
michael@0 | 808 | * and try again |
michael@0 | 809 | */ |
michael@0 | 810 | for( rv = FALSE; rv == FALSE; /* do nothing */ ) |
michael@0 | 811 | { |
michael@0 | 812 | if (isWSEB) |
michael@0 | 813 | { |
michael@0 | 814 | rv = myDosSetFileLocksL( (HFILE) f, |
michael@0 | 815 | &unlockL, &lockL, |
michael@0 | 816 | 0, 0); |
michael@0 | 817 | } |
michael@0 | 818 | else |
michael@0 | 819 | { |
michael@0 | 820 | rv = DosSetFileLocks( (HFILE) f, |
michael@0 | 821 | &unlock, &lock, |
michael@0 | 822 | 0, 0); |
michael@0 | 823 | } |
michael@0 | 824 | if ( rv != NO_ERROR ) |
michael@0 | 825 | { |
michael@0 | 826 | DosSleep( 50 ); /* Sleep() a few milisecs and try again. */ |
michael@0 | 827 | } |
michael@0 | 828 | } /* end for() */ |
michael@0 | 829 | return PR_SUCCESS; |
michael@0 | 830 | } /* end _PR_MD_LOCKFILE() */ |
michael@0 | 831 | |
michael@0 | 832 | PRStatus |
michael@0 | 833 | _PR_MD_TLOCKFILE(PRInt32 f) |
michael@0 | 834 | { |
michael@0 | 835 | return _PR_MD_LOCKFILE(f); |
michael@0 | 836 | } /* end _PR_MD_TLOCKFILE() */ |
michael@0 | 837 | |
michael@0 | 838 | |
michael@0 | 839 | PRStatus |
michael@0 | 840 | _PR_MD_UNLOCKFILE(PRInt32 f) |
michael@0 | 841 | { |
michael@0 | 842 | PRInt32 rv; |
michael@0 | 843 | FILELOCK lock, unlock; |
michael@0 | 844 | FILELOCKL lockL, unlockL; |
michael@0 | 845 | |
michael@0 | 846 | lock.lOffset = 0; |
michael@0 | 847 | lockL.lOffset = 0; |
michael@0 | 848 | lock.lRange = 0; |
michael@0 | 849 | lockL.lRange = 0; |
michael@0 | 850 | unlock.lOffset = 0; |
michael@0 | 851 | unlockL.lOffset = 0; |
michael@0 | 852 | unlock.lRange = 0xffffffff; |
michael@0 | 853 | unlockL.lRange = 0xffffffffffffffff; |
michael@0 | 854 | |
michael@0 | 855 | if (isWSEB) |
michael@0 | 856 | { |
michael@0 | 857 | rv = myDosSetFileLocksL( (HFILE) f, |
michael@0 | 858 | &unlockL, &lockL, |
michael@0 | 859 | 0, 0); |
michael@0 | 860 | } |
michael@0 | 861 | else |
michael@0 | 862 | { |
michael@0 | 863 | rv = DosSetFileLocks( (HFILE) f, |
michael@0 | 864 | &unlock, &lock, |
michael@0 | 865 | 0, 0); |
michael@0 | 866 | } |
michael@0 | 867 | |
michael@0 | 868 | if ( rv != NO_ERROR ) |
michael@0 | 869 | { |
michael@0 | 870 | return PR_SUCCESS; |
michael@0 | 871 | } |
michael@0 | 872 | else |
michael@0 | 873 | { |
michael@0 | 874 | return PR_FAILURE; |
michael@0 | 875 | } |
michael@0 | 876 | } /* end _PR_MD_UNLOCKFILE() */ |
michael@0 | 877 | |
michael@0 | 878 | PRStatus |
michael@0 | 879 | _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable) |
michael@0 | 880 | { |
michael@0 | 881 | APIRET rc = 0; |
michael@0 | 882 | ULONG flags; |
michael@0 | 883 | switch (fd->methods->file_type) |
michael@0 | 884 | { |
michael@0 | 885 | case PR_DESC_PIPE: |
michael@0 | 886 | case PR_DESC_FILE: |
michael@0 | 887 | rc = DosQueryFHState((HFILE)fd->secret->md.osfd, &flags); |
michael@0 | 888 | if (rc != NO_ERROR) { |
michael@0 | 889 | PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); |
michael@0 | 890 | return PR_FAILURE; |
michael@0 | 891 | } |
michael@0 | 892 | |
michael@0 | 893 | if (inheritable) |
michael@0 | 894 | flags &= ~OPEN_FLAGS_NOINHERIT; |
michael@0 | 895 | else |
michael@0 | 896 | flags |= OPEN_FLAGS_NOINHERIT; |
michael@0 | 897 | |
michael@0 | 898 | /* Mask off flags DosSetFHState don't want. */ |
michael@0 | 899 | flags &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT); |
michael@0 | 900 | rc = DosSetFHState((HFILE)fd->secret->md.osfd, flags); |
michael@0 | 901 | if (rc != NO_ERROR) { |
michael@0 | 902 | PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); |
michael@0 | 903 | return PR_FAILURE; |
michael@0 | 904 | } |
michael@0 | 905 | break; |
michael@0 | 906 | |
michael@0 | 907 | case PR_DESC_LAYERED: |
michael@0 | 908 | /* what to do here? */ |
michael@0 | 909 | PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/); |
michael@0 | 910 | return PR_FAILURE; |
michael@0 | 911 | |
michael@0 | 912 | case PR_DESC_SOCKET_TCP: |
michael@0 | 913 | case PR_DESC_SOCKET_UDP: |
michael@0 | 914 | /* These are global on OS/2. */ |
michael@0 | 915 | break; |
michael@0 | 916 | } |
michael@0 | 917 | |
michael@0 | 918 | return PR_SUCCESS; |
michael@0 | 919 | } |
michael@0 | 920 | |
michael@0 | 921 | void |
michael@0 | 922 | _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported) |
michael@0 | 923 | { |
michael@0 | 924 | /* XXX this function needs to be implemented */ |
michael@0 | 925 | fd->secret->inheritable = _PR_TRI_UNKNOWN; |
michael@0 | 926 | } |
michael@0 | 927 | |
michael@0 | 928 | void |
michael@0 | 929 | _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd) |
michael@0 | 930 | { |
michael@0 | 931 | /* XXX this function needs to be reviewed */ |
michael@0 | 932 | ULONG flags; |
michael@0 | 933 | |
michael@0 | 934 | PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); |
michael@0 | 935 | if (DosQueryFHState((HFILE)fd->secret->md.osfd, &flags) == 0) { |
michael@0 | 936 | if (flags & OPEN_FLAGS_NOINHERIT) { |
michael@0 | 937 | fd->secret->inheritable = _PR_TRI_FALSE; |
michael@0 | 938 | } else { |
michael@0 | 939 | fd->secret->inheritable = _PR_TRI_TRUE; |
michael@0 | 940 | } |
michael@0 | 941 | } |
michael@0 | 942 | } |