~ubuntu-branches/ubuntu/gutsy/virtualbox-ose/gutsy

« back to all changes in this revision

Viewing changes to src/libs/xpcom18a4/nsprpub/pr/src/io/prfile.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-09-08 16:44:58 UTC
  • Revision ID: james.westby@ubuntu.com-20070908164458-wao29470vqtr8ksy
Tags: upstream-1.5.0-dfsg2
ImportĀ upstreamĀ versionĀ 1.5.0-dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Mozilla Public License Version
 
6
 * 1.1 (the "License"); you may not use this file except in compliance with
 
7
 * the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/MPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is the Netscape Portable Runtime (NSPR).
 
16
 *
 
17
 * The Initial Developer of the Original Code is
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the MPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the MPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
 
 
38
#include "primpl.h"
 
39
 
 
40
#include <string.h>
 
41
#include <fcntl.h>
 
42
 
 
43
#ifdef XP_UNIX
 
44
#if defined(AIX) || defined(QNX)
 
45
/* To pick up sysconf */
 
46
#include <unistd.h>
 
47
#else
 
48
/* To pick up getrlimit, setrlimit */
 
49
#include <sys/time.h>
 
50
#include <sys/resource.h>
 
51
#endif
 
52
#endif /* XP_UNIX */
 
53
 
 
54
extern PRLock *_pr_flock_lock;
 
55
extern PRCondVar *_pr_flock_cv;
 
56
 
 
57
static PRInt32 PR_CALLBACK FileRead(PRFileDesc *fd, void *buf, PRInt32 amount)
 
58
{
 
59
    PRInt32 rv = 0;
 
60
    PRThread *me = _PR_MD_CURRENT_THREAD();
 
61
 
 
62
    if (_PR_PENDING_INTERRUPT(me)) {
 
63
                me->flags &= ~_PR_INTERRUPT;
 
64
                PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
 
65
                rv = -1;
 
66
    }
 
67
    if (_PR_IO_PENDING(me)) {
 
68
        PR_SetError(PR_IO_PENDING_ERROR, 0);
 
69
        rv = -1;
 
70
    }
 
71
    if (rv == -1)
 
72
        return rv;
 
73
 
 
74
    PR_LOG(_pr_io_lm, PR_LOG_MAX,
 
75
               ("read: fd=%p osfd=%d buf=%p amount=%d",
 
76
                    fd, fd ? fd->secret->md.osfd : 0, buf, amount));
 
77
 
 
78
        rv = _PR_MD_READ(fd, buf, amount);
 
79
        if (rv < 0) {
 
80
                PR_ASSERT(rv == -1);
 
81
        }
 
82
    PR_LOG(_pr_io_lm, PR_LOG_MAX, ("read -> %d", rv));
 
83
    return rv;
 
84
}
 
85
 
 
86
static PRInt32 PR_CALLBACK FileWrite(PRFileDesc *fd, const void *buf, PRInt32 amount)
 
87
{
 
88
    PRInt32 rv = 0;
 
89
    PRInt32 temp, count;
 
90
    PRThread *me = _PR_MD_CURRENT_THREAD();
 
91
 
 
92
    if (_PR_PENDING_INTERRUPT(me)) {
 
93
        me->flags &= ~_PR_INTERRUPT;
 
94
        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
 
95
            rv = -1;
 
96
    }
 
97
    if (_PR_IO_PENDING(me)) {
 
98
        PR_SetError(PR_IO_PENDING_ERROR, 0);
 
99
            rv = -1;
 
100
    }
 
101
    if (rv != 0)
 
102
        return rv;
 
103
 
 
104
    count = 0;
 
105
#if !defined(XP_UNIX)  /* BugZilla: 4090 */
 
106
    if ( PR_TRUE == fd->secret->appendMode ) {
 
107
        rv = PR_Seek(fd, 0, PR_SEEK_END );
 
108
        if ( -1 == rv )  {
 
109
            return rv;
 
110
        }
 
111
    } /* if (fd->secret->appendMode...) */
 
112
#endif /* XP_UNIX */
 
113
    while (amount > 0) {
 
114
        PR_LOG(_pr_io_lm, PR_LOG_MAX,
 
115
                   ("write: fd=%p osfd=%d buf=%p amount=%d",
 
116
                        fd, fd ? fd->secret->md.osfd : 0, buf, amount));
 
117
                temp = _PR_MD_WRITE(fd, buf, amount);
 
118
                if (temp < 0) {
 
119
                        count = -1;
 
120
                        break;
 
121
                }
 
122
                count += temp;
 
123
                if (fd->secret->nonblocking) {
 
124
                        break;
 
125
                }
 
126
                buf = (const void*) ((const char*)buf + temp);
 
127
                amount -= temp;
 
128
    }
 
129
    PR_LOG(_pr_io_lm, PR_LOG_MAX, ("write -> %d", count));
 
130
    return count;
 
131
}
 
132
 
 
133
static PROffset32 PR_CALLBACK FileSeek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
 
134
{
 
135
    PROffset32 result;
 
136
 
 
137
    result = _PR_MD_LSEEK(fd, offset, whence);
 
138
    return result;
 
139
}
 
140
 
 
141
static PROffset64 PR_CALLBACK FileSeek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
 
142
{
 
143
#ifdef XP_MAC
 
144
#pragma unused( fd, offset, whence )
 
145
#endif
 
146
    PROffset64 result;
 
147
 
 
148
    result = _PR_MD_LSEEK64(fd, offset, whence);
 
149
    return result;
 
150
}
 
151
 
 
152
static PRInt32 PR_CALLBACK FileAvailable(PRFileDesc *fd)
 
153
{
 
154
    PRInt32 result, cur, end;
 
155
 
 
156
    cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR);
 
157
 
 
158
        if (cur >= 0)
 
159
        end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);
 
160
 
 
161
    if ((cur < 0) || (end < 0)) {
 
162
        return -1;
 
163
    }
 
164
 
 
165
    result = end - cur;
 
166
    _PR_MD_LSEEK(fd, cur, PR_SEEK_SET);
 
167
 
 
168
    return result;
 
169
}
 
170
 
 
171
static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd)
 
172
{
 
173
#ifdef XP_MAC
 
174
#pragma unused( fd )
 
175
#endif
 
176
    PRInt64 result, cur, end;
 
177
    PRInt64 minus_one;
 
178
 
 
179
    LL_I2L(minus_one, -1);
 
180
    cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);
 
181
 
 
182
    if (LL_GE_ZERO(cur))
 
183
        end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);
 
184
 
 
185
    if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one;
 
186
 
 
187
    LL_SUB(result, end, cur);
 
188
    (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);
 
189
 
 
190
    return result;
 
191
}
 
192
 
 
193
static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc *fd)
 
194
{
 
195
        PRInt32 rv;
 
196
        rv =  _PR_MD_PIPEAVAILABLE(fd);
 
197
        return rv;              
 
198
}
 
199
 
 
200
static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc *fd)
 
201
{
 
202
    PRInt64 rv;
 
203
    LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd));
 
204
        return rv;              
 
205
}
 
206
 
 
207
static PRStatus PR_CALLBACK PipeSync(PRFileDesc *fd)
 
208
{
 
209
#if defined(XP_MAC)
 
210
#pragma unused (fd)
 
211
#endif
 
212
 
 
213
        return PR_SUCCESS;
 
214
}
 
215
 
 
216
static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc *fd, PRFileInfo *info)
 
217
{
 
218
        PRInt32 rv;
 
219
 
 
220
    rv = _PR_MD_GETOPENFILEINFO(fd, info);
 
221
    if (rv < 0) {
 
222
        return PR_FAILURE;
 
223
    } else
 
224
        return PR_SUCCESS;
 
225
}
 
226
 
 
227
static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc *fd, PRFileInfo64 *info)
 
228
{
 
229
#ifdef XP_MAC
 
230
#pragma unused( fd, info )
 
231
#endif
 
232
    /* $$$$ NOT YET IMPLEMENTED */
 
233
        PRInt32 rv;
 
234
 
 
235
    rv = _PR_MD_GETOPENFILEINFO64(fd, info);
 
236
    if (rv < 0) return PR_FAILURE;
 
237
    else return PR_SUCCESS;
 
238
}
 
239
 
 
240
static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd)
 
241
{
 
242
    PRInt32 result;
 
243
    result = _PR_MD_FSYNC(fd);
 
244
    if (result < 0) {
 
245
                return PR_FAILURE;
 
246
    }
 
247
    return PR_SUCCESS;
 
248
}
 
249
 
 
250
static PRStatus PR_CALLBACK FileClose(PRFileDesc *fd)
 
251
{
 
252
    if (!fd || !fd->secret
 
253
            || (fd->secret->state != _PR_FILEDESC_OPEN
 
254
            && fd->secret->state != _PR_FILEDESC_CLOSED)) {
 
255
        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
 
256
        return PR_FAILURE;
 
257
    }
 
258
 
 
259
    if (fd->secret->state == _PR_FILEDESC_OPEN) {
 
260
        if (_PR_MD_CLOSE_FILE(fd->secret->md.osfd) < 0) {
 
261
            return PR_FAILURE;
 
262
        }
 
263
        fd->secret->state = _PR_FILEDESC_CLOSED;
 
264
    }
 
265
    PR_FreeFileDesc(fd);
 
266
    return PR_SUCCESS;
 
267
}
 
268
 
 
269
static PRInt16 PR_CALLBACK FilePoll(
 
270
    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
 
271
{
 
272
#ifdef XP_MAC
 
273
#pragma unused( fd, in_flags )
 
274
#endif
 
275
    *out_flags = 0;
 
276
    return in_flags;
 
277
}  /* FilePoll */
 
278
 
 
279
static PRIOMethods _pr_fileMethods = {
 
280
    PR_DESC_FILE,
 
281
    FileClose,
 
282
    FileRead,
 
283
    FileWrite,
 
284
    FileAvailable,
 
285
    FileAvailable64,
 
286
    FileSync,
 
287
    FileSeek,
 
288
    FileSeek64,
 
289
    FileGetInfo,
 
290
    FileGetInfo64,
 
291
    (PRWritevFN)_PR_InvalidInt,         
 
292
    (PRConnectFN)_PR_InvalidStatus,             
 
293
    (PRAcceptFN)_PR_InvalidDesc,                
 
294
    (PRBindFN)_PR_InvalidStatus,                
 
295
    (PRListenFN)_PR_InvalidStatus,              
 
296
    (PRShutdownFN)_PR_InvalidStatus,    
 
297
    (PRRecvFN)_PR_InvalidInt,           
 
298
    (PRSendFN)_PR_InvalidInt,           
 
299
    (PRRecvfromFN)_PR_InvalidInt,       
 
300
    (PRSendtoFN)_PR_InvalidInt,         
 
301
    FilePoll,         
 
302
    (PRAcceptreadFN)_PR_InvalidInt,   
 
303
    (PRTransmitfileFN)_PR_InvalidInt, 
 
304
    (PRGetsocknameFN)_PR_InvalidStatus, 
 
305
    (PRGetpeernameFN)_PR_InvalidStatus, 
 
306
    (PRReservedFN)_PR_InvalidInt,       
 
307
    (PRReservedFN)_PR_InvalidInt,       
 
308
    (PRGetsocketoptionFN)_PR_InvalidStatus,     
 
309
    (PRSetsocketoptionFN)_PR_InvalidStatus,
 
310
    (PRSendfileFN)_PR_InvalidInt, 
 
311
    (PRConnectcontinueFN)_PR_InvalidStatus, 
 
312
    (PRReservedFN)_PR_InvalidInt, 
 
313
    (PRReservedFN)_PR_InvalidInt, 
 
314
    (PRReservedFN)_PR_InvalidInt, 
 
315
    (PRReservedFN)_PR_InvalidInt
 
316
};
 
317
 
 
318
PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
 
319
{
 
320
    return &_pr_fileMethods;
 
321
}
 
322
 
 
323
static PRIOMethods _pr_pipeMethods = {
 
324
    PR_DESC_PIPE,
 
325
    FileClose,
 
326
    FileRead,
 
327
    FileWrite,
 
328
    PipeAvailable,
 
329
    PipeAvailable64,
 
330
    PipeSync,
 
331
    (PRSeekFN)_PR_InvalidInt,
 
332
    (PRSeek64FN)_PR_InvalidInt64,
 
333
    (PRFileInfoFN)_PR_InvalidStatus,
 
334
    (PRFileInfo64FN)_PR_InvalidStatus,
 
335
    (PRWritevFN)_PR_InvalidInt,         
 
336
    (PRConnectFN)_PR_InvalidStatus,             
 
337
    (PRAcceptFN)_PR_InvalidDesc,                
 
338
    (PRBindFN)_PR_InvalidStatus,                
 
339
    (PRListenFN)_PR_InvalidStatus,              
 
340
    (PRShutdownFN)_PR_InvalidStatus,    
 
341
    (PRRecvFN)_PR_InvalidInt,           
 
342
    (PRSendFN)_PR_InvalidInt,           
 
343
    (PRRecvfromFN)_PR_InvalidInt,       
 
344
    (PRSendtoFN)_PR_InvalidInt,         
 
345
    FilePoll,         
 
346
    (PRAcceptreadFN)_PR_InvalidInt,   
 
347
    (PRTransmitfileFN)_PR_InvalidInt, 
 
348
    (PRGetsocknameFN)_PR_InvalidStatus, 
 
349
    (PRGetpeernameFN)_PR_InvalidStatus, 
 
350
    (PRReservedFN)_PR_InvalidInt,       
 
351
    (PRReservedFN)_PR_InvalidInt,       
 
352
    (PRGetsocketoptionFN)_PR_InvalidStatus,     
 
353
    (PRSetsocketoptionFN)_PR_InvalidStatus,
 
354
    (PRSendfileFN)_PR_InvalidInt, 
 
355
    (PRConnectcontinueFN)_PR_InvalidStatus, 
 
356
    (PRReservedFN)_PR_InvalidInt, 
 
357
    (PRReservedFN)_PR_InvalidInt, 
 
358
    (PRReservedFN)_PR_InvalidInt, 
 
359
    (PRReservedFN)_PR_InvalidInt
 
360
};
 
361
 
 
362
PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void)
 
363
{
 
364
    return &_pr_pipeMethods;
 
365
}
 
366
 
 
367
PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
 
368
{
 
369
    PRInt32 osfd;
 
370
    PRFileDesc *fd = 0;
 
371
#if !defined(XP_UNIX) /* BugZilla: 4090 */
 
372
    PRBool  appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
 
373
#endif
 
374
 
 
375
    if (!_pr_initialized) _PR_ImplicitInitialization();
 
376
 
 
377
    /* Map pr open flags and mode to os specific flags */
 
378
 
 
379
    osfd = _PR_MD_OPEN(name, flags, mode);
 
380
    if (osfd != -1) {
 
381
        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
 
382
        if (!fd) {
 
383
            (void) _PR_MD_CLOSE_FILE(osfd);
 
384
        } else {
 
385
#if !defined(XP_UNIX) /* BugZilla: 4090 */
 
386
            fd->secret->appendMode = appendMode;
 
387
#endif
 
388
            _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
 
389
        }
 
390
    }
 
391
    return fd;
 
392
}
 
393
 
 
394
PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
 
395
    const char *name, PRIntn flags, PRIntn mode)
 
396
{
 
397
    PRInt32 osfd;
 
398
    PRFileDesc *fd = 0;
 
399
#if !defined(XP_UNIX) /* BugZilla: 4090 */
 
400
    PRBool  appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
 
401
#endif
 
402
 
 
403
    if (!_pr_initialized) _PR_ImplicitInitialization();
 
404
 
 
405
    /* Map pr open flags and mode to os specific flags */
 
406
 
 
407
    osfd = _PR_MD_OPEN_FILE(name, flags, mode);
 
408
    if (osfd != -1) {
 
409
        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
 
410
        if (!fd) {
 
411
            (void) _PR_MD_CLOSE_FILE(osfd);
 
412
        } else {
 
413
#if !defined(XP_UNIX) /* BugZilla: 4090 */
 
414
            fd->secret->appendMode = appendMode;
 
415
#endif
 
416
            _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
 
417
        }
 
418
    }
 
419
    return fd;
 
420
}
 
421
 
 
422
PRInt32 PR_GetSysfdTableMax(void)
 
423
{
 
424
#if defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX)
 
425
    struct rlimit rlim;
 
426
 
 
427
    if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
 
428
       /* XXX need to call PR_SetError() */
 
429
       return -1;
 
430
    }
 
431
 
 
432
    return rlim.rlim_max;
 
433
#elif defined(AIX) || defined(NEXTSTEP) || defined(QNX)
 
434
    return sysconf(_SC_OPEN_MAX);
 
435
#elif defined(WIN32)
 
436
    /*
 
437
     * There is a systemwide limit of 65536 user handles.
 
438
     */
 
439
    return 16384;
 
440
#elif defined (WIN16)
 
441
    return FOPEN_MAX;
 
442
#elif defined(XP_OS2)
 
443
    ULONG ulReqCount = 0;
 
444
    ULONG ulCurMaxFH = 0;
 
445
    DosSetRelMaxFH(&ulReqCount, &ulCurMaxFH);
 
446
    return ulCurMaxFH;
 
447
#elif defined (XP_MAC) || defined(XP_BEOS)
 
448
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
 
449
   return -1;
 
450
#else
 
451
    write me;
 
452
#endif
 
453
}
 
454
 
 
455
PRInt32 PR_SetSysfdTableSize(int table_size)
 
456
{
 
457
#if defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX)
 
458
    struct rlimit rlim;
 
459
    PRInt32 tableMax = PR_GetSysfdTableMax();
 
460
 
 
461
    if (tableMax < 0) 
 
462
        return -1;
 
463
 
 
464
    if (tableMax > FD_SETSIZE)
 
465
        tableMax = FD_SETSIZE;
 
466
 
 
467
    rlim.rlim_max = tableMax;
 
468
 
 
469
    /* Grow as much as we can; even if too big */
 
470
    if ( rlim.rlim_max < table_size )
 
471
        rlim.rlim_cur = rlim.rlim_max;
 
472
    else
 
473
        rlim.rlim_cur = table_size;
 
474
 
 
475
    if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
 
476
        /* XXX need to call PR_SetError() */
 
477
        return -1;
 
478
    }
 
479
 
 
480
    return rlim.rlim_cur;
 
481
#elif defined(XP_OS2)
 
482
    PRInt32 tableMax = PR_GetSysfdTableMax();
 
483
    if (table_size > tableMax) {
 
484
      APIRET rc = NO_ERROR;
 
485
      rc = DosSetMaxFH(table_size);
 
486
      if (rc == NO_ERROR)
 
487
        return table_size;
 
488
      else
 
489
        return -1;
 
490
    } 
 
491
    return tableMax;
 
492
#elif defined(AIX) || defined(NEXTSTEP) || defined(QNX) \
 
493
        || defined(WIN32) || defined(WIN16) || defined(XP_BEOS)
 
494
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
 
495
    return -1;
 
496
#elif defined (XP_MAC)
 
497
#pragma unused (table_size)
 
498
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
 
499
   return -1;
 
500
#else
 
501
    write me;
 
502
#endif
 
503
}
 
504
 
 
505
PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
 
506
{
 
507
        PRInt32 rv;
 
508
 
 
509
        rv = _PR_MD_DELETE(name);
 
510
        if (rv < 0) {
 
511
                return PR_FAILURE;
 
512
        } else
 
513
                return PR_SUCCESS;
 
514
}
 
515
 
 
516
PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info)
 
517
{
 
518
        PRInt32 rv;
 
519
 
 
520
        rv = _PR_MD_GETFILEINFO(fn, info);
 
521
        if (rv < 0) {
 
522
                return PR_FAILURE;
 
523
        } else
 
524
                return PR_SUCCESS;
 
525
}
 
526
 
 
527
PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info)
 
528
{
 
529
#ifdef XP_MAC
 
530
#pragma unused (fn, info)
 
531
#endif
 
532
    PRInt32 rv;
 
533
 
 
534
    if (!_pr_initialized) _PR_ImplicitInitialization();
 
535
    rv = _PR_MD_GETFILEINFO64(fn, info);
 
536
    if (rv < 0) {
 
537
        return PR_FAILURE;
 
538
    } else {
 
539
        return PR_SUCCESS;
 
540
    }
 
541
}
 
542
 
 
543
PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to)
 
544
{
 
545
        PRInt32 rv;
 
546
 
 
547
        rv = _PR_MD_RENAME(from, to);
 
548
        if (rv < 0) {
 
549
                return PR_FAILURE;
 
550
        } else
 
551
                return PR_SUCCESS;
 
552
}
 
553
 
 
554
PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how)
 
555
{
 
556
PRInt32 rv;
 
557
 
 
558
        rv = _PR_MD_ACCESS(name, how);
 
559
        if (rv < 0) {
 
560
                return PR_FAILURE;
 
561
        } else
 
562
                return PR_SUCCESS;
 
563
}
 
564
 
 
565
/*
 
566
** Import an existing OS file to NSPR 
 
567
*/
 
568
PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PRInt32 osfd)
 
569
{
 
570
    PRFileDesc *fd = NULL;
 
571
 
 
572
    if (!_pr_initialized) _PR_ImplicitInitialization();
 
573
 
 
574
    fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
 
575
    if( !fd ) {
 
576
        (void) _PR_MD_CLOSE_FILE(osfd);
 
577
    } else {
 
578
        _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
 
579
    }
 
580
 
 
581
    return fd;
 
582
}
 
583
 
 
584
/*
 
585
** Import an existing OS pipe to NSPR 
 
586
*/
 
587
PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PRInt32 osfd)
 
588
{
 
589
    PRFileDesc *fd = NULL;
 
590
 
 
591
    if (!_pr_initialized) _PR_ImplicitInitialization();
 
592
 
 
593
    fd = PR_AllocFileDesc(osfd, &_pr_pipeMethods);
 
594
    if( !fd ) {
 
595
        (void) _PR_MD_CLOSE_FILE(osfd);
 
596
    } else {
 
597
        _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
 
598
#ifdef WINNT
 
599
        fd->secret->md.sync_file_io = PR_TRUE;
 
600
#endif
 
601
    }
 
602
 
 
603
    return fd;
 
604
}
 
605
 
 
606
#ifndef NO_NSPR_10_SUPPORT
 
607
/*
 
608
** PR_Stat() for Win16 is defined in w16io.c
 
609
** it is a hack to circumvent problems in Gromit and Java
 
610
** See also: BugSplat: 98516.
 
611
*/
 
612
#if !defined(WIN16)
 
613
/*
 
614
 * This function is supposed to be for backward compatibility with
 
615
 * nspr 1.0.  Therefore, it still uses the nspr 1.0 error-reporting
 
616
 * mechanism -- returns a PRInt32, which is the error code when the call
 
617
 * fails.
 
618
 * 
 
619
 * If we need this function in nspr 2.0, it should be changed to
 
620
 * return PRStatus, as follows:
 
621
 *
 
622
 * PR_IMPLEMENT(PRStatus) PR_Stat(const char *name, struct stat *buf)
 
623
 * {
 
624
 *     PRInt32 rv;
 
625
 *
 
626
 *     rv = _PR_MD_STAT(name, buf);
 
627
 *     if (rv < 0)
 
628
 *         return PR_FAILURE;
 
629
 *     else
 
630
 *         return PR_SUCCESS;
 
631
 * }
 
632
 *
 
633
 * -- wtc, 2/14/97.
 
634
 */
 
635
PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
 
636
{
 
637
    PRInt32 rv;
 
638
 
 
639
    rv = _PR_MD_STAT(name, buf);
 
640
        return rv;
 
641
}
 
642
 
 
643
#endif /* !defined(WIN16)  */
 
644
#endif /* ! NO_NSPR_10_SUPPORT */
 
645
 
 
646
PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd)
 
647
{
 
648
    PRStatus status = PR_SUCCESS;
 
649
 
 
650
#ifdef WINNT
 
651
    if (!fd->secret->md.io_model_committed) {
 
652
        PRInt32 rv;
 
653
        rv = _md_Associate((HANDLE)fd->secret->md.osfd);
 
654
        PR_ASSERT(0 != rv);
 
655
        fd->secret->md.io_model_committed = PR_TRUE;
 
656
    }
 
657
#endif
 
658
 
 
659
    PR_Lock(_pr_flock_lock);
 
660
    while (fd->secret->lockCount == -1)
 
661
        PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT);
 
662
    if (fd->secret->lockCount == 0) {
 
663
        fd->secret->lockCount = -1;
 
664
        PR_Unlock(_pr_flock_lock);
 
665
        status = _PR_MD_LOCKFILE(fd->secret->md.osfd);
 
666
        PR_Lock(_pr_flock_lock);
 
667
        fd->secret->lockCount = (status == PR_SUCCESS) ? 1 : 0;
 
668
        PR_NotifyAllCondVar(_pr_flock_cv);
 
669
    } else {
 
670
        fd->secret->lockCount++;
 
671
    }
 
672
    PR_Unlock(_pr_flock_lock);
 
673
 
 
674
    return status;
 
675
}
 
676
 
 
677
PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd)
 
678
{
 
679
    PRStatus status = PR_SUCCESS;
 
680
 
 
681
#ifdef WINNT
 
682
    if (!fd->secret->md.io_model_committed) {
 
683
        PRInt32 rv;
 
684
        rv = _md_Associate((HANDLE)fd->secret->md.osfd);
 
685
        PR_ASSERT(0 != rv);
 
686
        fd->secret->md.io_model_committed = PR_TRUE;
 
687
    }
 
688
#endif
 
689
 
 
690
    PR_Lock(_pr_flock_lock);
 
691
    if (fd->secret->lockCount == 0) {
 
692
        status = _PR_MD_TLOCKFILE(fd->secret->md.osfd);
 
693
        PR_ASSERT(status == PR_SUCCESS || fd->secret->lockCount == 0);
 
694
        if (status == PR_SUCCESS)
 
695
            fd->secret->lockCount = 1;
 
696
    } else {
 
697
        fd->secret->lockCount++;
 
698
    }
 
699
    PR_Unlock(_pr_flock_lock);
 
700
 
 
701
    return status;
 
702
}
 
703
 
 
704
PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd)
 
705
{
 
706
    PRStatus rv = PR_SUCCESS;
 
707
 
 
708
    PR_Lock(_pr_flock_lock);
 
709
    if (fd->secret->lockCount == 1) {
 
710
        rv = _PR_MD_UNLOCKFILE(fd->secret->md.osfd);
 
711
        if (rv == PR_SUCCESS) 
 
712
            fd->secret->lockCount = 0;
 
713
    } else {
 
714
        fd->secret->lockCount--;
 
715
    }
 
716
    PR_Unlock(_pr_flock_lock);
 
717
 
 
718
    return rv;
 
719
}
 
720
 
 
721
PR_IMPLEMENT(PRStatus) PR_CreatePipe(
 
722
    PRFileDesc **readPipe,
 
723
    PRFileDesc **writePipe
 
724
)
 
725
{
 
726
#if defined(XP_MAC)
 
727
#pragma unused (readPipe, writePipe)
 
728
#endif
 
729
 
 
730
#ifdef WIN32
 
731
    HANDLE readEnd, writeEnd;
 
732
    SECURITY_ATTRIBUTES pipeAttributes;
 
733
 
 
734
    if (!_pr_initialized) _PR_ImplicitInitialization();
 
735
 
 
736
    ZeroMemory(&pipeAttributes, sizeof(pipeAttributes));
 
737
    pipeAttributes.nLength = sizeof(pipeAttributes);
 
738
    pipeAttributes.bInheritHandle = TRUE;
 
739
    if (CreatePipe(&readEnd, &writeEnd, &pipeAttributes, 0) == 0) {
 
740
        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
 
741
        return PR_FAILURE;
 
742
    }
 
743
    *readPipe = PR_AllocFileDesc((PRInt32)readEnd, &_pr_pipeMethods);
 
744
    if (NULL == *readPipe) {
 
745
        CloseHandle(readEnd);
 
746
        CloseHandle(writeEnd);
 
747
        return PR_FAILURE;
 
748
    }
 
749
    *writePipe = PR_AllocFileDesc((PRInt32)writeEnd, &_pr_pipeMethods);
 
750
    if (NULL == *writePipe) {
 
751
        PR_Close(*readPipe);
 
752
        CloseHandle(writeEnd);
 
753
        return PR_FAILURE;
 
754
    }
 
755
#ifdef WINNT
 
756
    (*readPipe)->secret->md.sync_file_io = PR_TRUE;
 
757
    (*writePipe)->secret->md.sync_file_io = PR_TRUE;
 
758
#endif
 
759
    (*readPipe)->secret->inheritable = _PR_TRI_TRUE;
 
760
    (*writePipe)->secret->inheritable = _PR_TRI_TRUE;
 
761
    return PR_SUCCESS;
 
762
#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
 
763
#ifdef XP_OS2
 
764
    HFILE pipefd[2];
 
765
#else
 
766
    int pipefd[2];
 
767
#endif
 
768
 
 
769
    if (!_pr_initialized) _PR_ImplicitInitialization();
 
770
 
 
771
#ifdef XP_OS2
 
772
    if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) {
 
773
#else
 
774
    if (pipe(pipefd) == -1) {
 
775
#endif
 
776
        /* XXX map pipe error */
 
777
        PR_SetError(PR_UNKNOWN_ERROR, errno);
 
778
        return PR_FAILURE;
 
779
    }
 
780
    *readPipe = PR_AllocFileDesc(pipefd[0], &_pr_pipeMethods);
 
781
    if (NULL == *readPipe) {
 
782
        close(pipefd[0]);
 
783
        close(pipefd[1]);
 
784
        return PR_FAILURE;
 
785
    }
 
786
    *writePipe = PR_AllocFileDesc(pipefd[1], &_pr_pipeMethods);
 
787
    if (NULL == *writePipe) {
 
788
        PR_Close(*readPipe);
 
789
        close(pipefd[1]);
 
790
        return PR_FAILURE;
 
791
    }
 
792
#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
 
793
    _PR_MD_MAKE_NONBLOCK(*readPipe);
 
794
#endif
 
795
    _PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE);
 
796
#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
 
797
    _PR_MD_MAKE_NONBLOCK(*writePipe);
 
798
#endif
 
799
    _PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE);
 
800
    return PR_SUCCESS;
 
801
#else
 
802
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
 
803
    return PR_FAILURE;
 
804
#endif
 
805
}
 
806
 
 
807
#ifdef MOZ_UNICODE
 
808
/* ================ UTF16 Interfaces ================================ */
 
809
PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
 
810
    const PRUnichar *name, PRIntn flags, PRIntn mode)
 
811
 
812
    PRInt32 osfd;
 
813
    PRFileDesc *fd = 0;
 
814
#if !defined(XP_UNIX) /* BugZilla: 4090 */
 
815
    PRBool  appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
 
816
#endif
 
817
   
 
818
    if (!_pr_initialized) _PR_ImplicitInitialization();
 
819
  
 
820
    /* Map pr open flags and mode to os specific flags */
 
821
    osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode);
 
822
    if (osfd != -1) {
 
823
        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
 
824
        if (!fd) {
 
825
            (void) _PR_MD_CLOSE_FILE(osfd);
 
826
        } else {
 
827
#if !defined(XP_UNIX) /* BugZilla: 4090 */
 
828
            fd->secret->appendMode = appendMode;
 
829
#endif
 
830
            _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
 
831
        }
 
832
    }
 
833
    return fd;
 
834
}
 
835
 
 
836
PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info)
 
837
{
 
838
#ifdef XP_MAC
 
839
#pragma unused (fn, info)
 
840
#endif
 
841
    PRInt32 rv;
 
842
 
 
843
    if (!_pr_initialized) _PR_ImplicitInitialization();
 
844
    rv = _PR_MD_GETFILEINFO64_UTF16(fn, info);
 
845
    if (rv < 0) {
 
846
        return PR_FAILURE;
 
847
    } else {
 
848
        return PR_SUCCESS;
 
849
    }
 
850
}
 
851
 
 
852
/* ================ UTF16 Interfaces ================================ */
 
853
#endif /* MOZ_UNICODE */