~ubuntu-branches/ubuntu/vivid/389-ds-base/vivid-proposed

« back to all changes in this revision

Viewing changes to .pc/support-kfreebsd.patch/lib/base/file.cpp

  • Committer: Package Import Robot
  • Author(s): Benjamin Drung
  • Date: 2014-09-03 15:32:22 UTC
  • Revision ID: package-import@ubuntu.com-20140903153222-f5t5kovnj3wr4s38
Tags: 1.3.2.23-2
* Team upload.
* Add fix-bsd.patch and support-kfreebsd.patch to fix the build failure
  on kFreeBSD.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** BEGIN COPYRIGHT BLOCK
 
2
 * This Program is free software; you can redistribute it and/or modify it under
 
3
 * the terms of the GNU General Public License as published by the Free Software
 
4
 * Foundation; version 2 of the License.
 
5
 * 
 
6
 * This Program is distributed in the hope that it will be useful, but WITHOUT
 
7
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
8
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
9
 * 
 
10
 * You should have received a copy of the GNU General Public License along with
 
11
 * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
12
 * Place, Suite 330, Boston, MA 02111-1307 USA.
 
13
 * 
 
14
 * In addition, as a special exception, Red Hat, Inc. gives You the additional
 
15
 * right to link the code of this Program with code not covered under the GNU
 
16
 * General Public License ("Non-GPL Code") and to distribute linked combinations
 
17
 * including the two, subject to the limitations in this paragraph. Non-GPL Code
 
18
 * permitted under this exception must only link to the code of this Program
 
19
 * through those well defined interfaces identified in the file named EXCEPTION
 
20
 * found in the source code files (the "Approved Interfaces"). The files of
 
21
 * Non-GPL Code may instantiate templates or use macros or inline functions from
 
22
 * the Approved Interfaces without causing the resulting work to be covered by
 
23
 * the GNU General Public License. Only Red Hat, Inc. may make changes or
 
24
 * additions to the list of Approved Interfaces. You must obey the GNU General
 
25
 * Public License in all respects for all of the Program code and other code used
 
26
 * in conjunction with the Program except the Non-GPL Code covered by this
 
27
 * exception. If you modify this file, you may extend this exception to your
 
28
 * version of the file, but you are not obligated to do so. If you do not wish to
 
29
 * provide this exception without modification, you must delete this exception
 
30
 * statement from your version and license this file solely under the GPL without
 
31
 * exception. 
 
32
 * 
 
33
 * 
 
34
 * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
 
35
 * Copyright (C) 2005 Red Hat, Inc.
 
36
 * All rights reserved.
 
37
 * END COPYRIGHT BLOCK **/
 
38
 
 
39
#ifdef HAVE_CONFIG_H
 
40
#  include <config.h>
 
41
#endif
 
42
 
 
43
/*
 
44
 * file.c: system specific functions for reading/writing files
 
45
 * 
 
46
 * See file.h for formal definitions of what these functions do
 
47
 *
 
48
 * Rob McCool
 
49
 */
 
50
 
 
51
 
 
52
#include "base/file.h"
 
53
#ifdef BSD_RLIMIT
 
54
#include <sys/time.h>
 
55
#include <sys/resource.h>
 
56
#else
 
57
#include <stdlib.h>
 
58
#include <signal.h>
 
59
#endif
 
60
#ifdef XP_WIN32
 
61
#include <time.h>  /* time */
 
62
#include <sys/stat.h> /* stat */
 
63
#include <errno.h>
 
64
#include <direct.h>
 
65
#include <base/nterr.h>
 
66
/* Removed for ns security integration
 
67
#include <xp_error.h>
 
68
*/
 
69
#endif
 
70
#include <prerror.h>
 
71
 
 
72
#include "private/pprio.h"
 
73
#include "prlock.h"
 
74
 
 
75
extern "C" char *nscperror_lookup(int err);
 
76
 
 
77
/* --- globals -------------------------------------------------------------*/
 
78
/* PRFileDesc * SYS_ERROR_FD = NULL; */
 
79
 
 
80
const int errbuf_size = 256;
 
81
const unsigned int LOCKFILERANGE=0x7FFFFFFF;
 
82
PRLock *_atomic_write_lock = NULL;
 
83
 
 
84
/* --------------------------------- stat --------------------------------- */
 
85
 
 
86
 
 
87
   /* XXXMB - Can't convert to PR_GetFileInfo because we directly exported
 
88
    * the stat interface... Damn.
 
89
    */
 
90
NSAPI_PUBLIC int system_stat(char *path, struct stat *finfo)
 
91
{
 
92
#ifdef XP_WIN32
 
93
 
 
94
    int chop, l;
 
95
 
 
96
/* The NT stat is very peculiar about directory names. */
 
97
/* XXX aruna - there is a bug here, maybe in the C runtime.
 
98
 * Stating the same path in a separate program succeeds. From
 
99
 * jblack's profiling, this needs to be replaced by the Win32
 
100
 * calls anyway.*/
 
101
 
 
102
    l = strlen(path);
 
103
    if((path[l - 1] == '/') && 
 
104
       (!(isalpha(path[0]) && (!strcmp(&path[1], ":/")))))
 
105
    {
 
106
        chop = 1;
 
107
        path[--l] = '\0';
 
108
    }
 
109
    else chop = 0;
 
110
#endif /* XP_WIN32 */
 
111
 
 
112
#ifdef XP_UNIX
 
113
    if(stat(path, finfo) == -1)
 
114
        return -1;
 
115
#else /* XP_WIN32 */
 
116
 
 
117
    if(_stat(path, (struct _stat *)finfo) == -1) {
 
118
        /* XXXMB - this sucks; 
 
119
         * try to convert to an error code we'll expect...
 
120
         */
 
121
        switch(errno) {
 
122
            case ENOENT: PR_SetError(PR_FILE_NOT_FOUND_ERROR, errno); break;
 
123
            default: PR_SetError(PR_UNKNOWN_ERROR, errno); break;
 
124
        }
 
125
        return -1;
 
126
    }
 
127
 
 
128
    /* NT sets the time fields to -1 if it thinks that the file
 
129
     * is a device ( like com1.html, lpt1.html etc)     In this case
 
130
     * simply set last modified time to the current time....
 
131
     */
 
132
 
 
133
    if (finfo->st_mtime == -1) {
 
134
        finfo->st_mtime = time(NULL);
 
135
    }
 
136
    if (finfo->st_atime == -1) {
 
137
        finfo->st_atime = 0;
 
138
    }
 
139
    if (finfo->st_ctime == -1) {
 
140
        finfo->st_ctime = 0;
 
141
    }
 
142
    if(chop)
 
143
        path[l++] = '/';
 
144
 
 
145
#endif /* XP_WIN32 */
 
146
 
 
147
    if(S_ISREG(finfo->st_mode) && (path[strlen(path) - 1] == '/')) {
 
148
        /* File with trailing slash */
 
149
        errno = ENOENT;
 
150
        return -1;
 
151
    }
 
152
    return 0;
 
153
}
 
154
 
 
155
 
 
156
NSAPI_PUBLIC int system_fread(SYS_FILE fd, char *buf, int sz) 
 
157
{
 
158
    /* XXXMB - this is the *one* function which does return a length
 
159
     * instead of the IO_ERROR/IO_OKAY.
 
160
     */
 
161
    return PR_Read(fd, buf, sz);
 
162
}
 
163
 
 
164
NSAPI_PUBLIC int system_fwrite(SYS_FILE fd, char *buf, int sz) {
 
165
    int n,o,w;
 
166
 
 
167
    for(n=sz,o=0; n; n-=w,o+=w) {
 
168
        if((w = PR_Write(fd, &buf[o], n)) < 0)
 
169
            return IO_ERROR;
 
170
    }
 
171
    return IO_OKAY;
 
172
}
 
173
 
 
174
/* ---------------------------- Standard UNIX ----------------------------- */
 
175
 
 
176
#ifdef XP_UNIX
 
177
 
 
178
#include <sys/file.h>   /* flock */
 
179
 
 
180
NSAPI_PUBLIC int system_fwrite_atomic(SYS_FILE fd, char *buf, int sz) 
 
181
{
 
182
    int ret;
 
183
#if 0
 
184
    if(flock(fd,LOCK_EX) == -1)
 
185
        return IO_ERROR;
 
186
#endif
 
187
    ret = system_fwrite(fd,buf,sz);
 
188
#if 0
 
189
    if(flock(fd,LOCK_UN) == -1)
 
190
        return IO_ERROR;  /* ??? */
 
191
#endif
 
192
    return ret;
 
193
}
 
194
 
 
195
/* -------------------------- system_nocoredumps -------------------------- */
 
196
 
 
197
 
 
198
NSAPI_PUBLIC int system_nocoredumps(void)
 
199
{
 
200
#ifdef BSD_RLIMIT
 
201
    struct rlimit rl;
 
202
 
 
203
    rl.rlim_cur = 0;
 
204
    rl.rlim_max = 0;
 
205
    return setrlimit(RLIMIT_CORE, &rl);
 
206
#else
 
207
#if defined(SNI)
 
208
/* C++ compiler seems to find more that one overloaded instance of exit() ?! */
 
209
#define EXITFUNC ::exit
 
210
#else
 
211
#define EXITFUNC exit
 
212
#endif
 
213
    signal(SIGQUIT, EXITFUNC);
 
214
    signal(SIGILL, EXITFUNC);
 
215
    signal(SIGTRAP, EXITFUNC);
 
216
    signal(SIGABRT, EXITFUNC);
 
217
    signal(SIGIOT, EXITFUNC);
 
218
    signal(SIGEMT, EXITFUNC);
 
219
    signal(SIGFPE, EXITFUNC);
 
220
    signal(SIGBUS, EXITFUNC);
 
221
    signal(SIGSEGV, EXITFUNC);
 
222
    signal(SIGSYS, EXITFUNC);
 
223
 
 
224
 
 
225
    return 0;
 
226
#endif
 
227
}
 
228
#endif /* XP_UNIX */
 
229
 
 
230
/* --------------------------- file_setinherit ---------------------------- */
 
231
 
 
232
NSAPI_PUBLIC int file_setinherit(SYS_FILE fd, int value)
 
233
{
 
234
#if defined(XP_WIN32)
 
235
    int ret;
 
236
 
 
237
//    ret = SetHandleInformation((HANDLE)PR_FileDesc2NativeHandle(fd), 0, value?HANDLE_FLAG_INHERIT:0);
 
238
        // This function did nothing before since the mask was set to 0.
 
239
    ret = SetHandleInformation((HANDLE)PR_FileDesc2NativeHandle(fd), HANDLE_FLAG_INHERIT, value?HANDLE_FLAG_INHERIT:0);
 
240
    return ret==0?-1:0;
 
241
#elif defined(XP_UNIX)
 
242
    int flags = 0;
 
243
    PRInt32 nativeFD;
 
244
    PRFileDesc *bottom = fd;
 
245
 
 
246
    while (bottom->lower != NULL) {
 
247
      bottom = bottom->lower;
 
248
    }
 
249
 
 
250
    nativeFD = PR_FileDesc2NativeHandle(bottom);
 
251
#if 0
 
252
fprintf(stderr, "\nInfo(file_setinherit): Native file descriptor is %d\n", nativeFD);
 
253
#endif
 
254
    flags = fcntl(nativeFD, F_GETFD, 0);
 
255
    if(flags == -1)
 
256
        return -1;
 
257
    if(value)
 
258
        flags &= (~FD_CLOEXEC);
 
259
    else
 
260
        flags |= FD_CLOEXEC;
 
261
    fcntl(nativeFD, F_SETFD, flags);
 
262
    return 0;
 
263
    
 
264
    /* Comment out for ns security/ nspr integration (HACK for NOW)
 
265
    int flags = fcntl(PR_FileDesc2NativeHandle(fd), F_GETFD, 0);
 
266
    if(flags == -1)
 
267
        return -1;
 
268
    if(value)
 
269
        flags &= (~FD_CLOEXEC);
 
270
    else
 
271
        flags |= FD_CLOEXEC;
 
272
    fcntl(PR_FileDesc2NativeHandle(fd), F_SETFD, flags);
 
273
    return 0;
 
274
    */
 
275
#endif
 
276
}
 
277
 
 
278
NSAPI_PUBLIC SYS_FILE system_fopenRO(char *p)
 
279
{
 
280
    SYS_FILE f = PR_Open(p, PR_RDONLY, 0);
 
281
 
 
282
    if (!f)
 
283
        return SYS_ERROR_FD;
 
284
    return f;
 
285
}
 
286
 
 
287
NSAPI_PUBLIC SYS_FILE system_fopenWA(char *p)
 
288
{
 
289
    SYS_FILE f = PR_Open(p, PR_RDWR|PR_CREATE_FILE|PR_APPEND, 0644);
 
290
 
 
291
    if (!f)
 
292
        return SYS_ERROR_FD;
 
293
    return f;
 
294
}
 
295
 
 
296
NSAPI_PUBLIC SYS_FILE system_fopenRW(char *p)
 
297
{
 
298
    SYS_FILE f = PR_Open(p, PR_RDWR|PR_CREATE_FILE, 0644);
 
299
 
 
300
    if (!f)
 
301
        return SYS_ERROR_FD;
 
302
    return f;
 
303
}
 
304
 
 
305
NSAPI_PUBLIC SYS_FILE system_fopenWT(char *p)
 
306
{
 
307
    SYS_FILE f = PR_Open(p, PR_RDWR|PR_CREATE_FILE|PR_TRUNCATE, 0644);
 
308
 
 
309
    if (!f)
 
310
        return SYS_ERROR_FD;
 
311
    return f;
 
312
}
 
313
 
 
314
NSAPI_PUBLIC int system_fclose(SYS_FILE fd)
 
315
{
 
316
    return (PR_Close(fd));
 
317
}
 
318
 
 
319
 
 
320
#ifdef FILE_WIN32
 
321
 
 
322
int CgiBuffering;
 
323
 
 
324
NSAPI_PUBLIC SYS_FILE system_fopen(char *path, int access, int flags)
 
325
{
 
326
    char p2[MAX_PATH];
 
327
    SYS_FILE ret;
 
328
    HANDLE fd;
 
329
 
 
330
        if (strlen(path) >= MAX_PATH) {
 
331
                return SYS_ERROR_FD;
 
332
        }
 
333
 
 
334
    file_unix2local(path, p2);
 
335
 
 
336
    fd = CreateFile(p2, access, FILE_SHARE_READ | FILE_SHARE_WRITE, 
 
337
                    NULL, flags, 0, NULL);
 
338
    ret = PR_ImportFile((int32)fd);
 
339
 
 
340
    if(ret == INVALID_HANDLE_VALUE)
 
341
        return SYS_ERROR_FD;
 
342
 
 
343
    return ret;
 
344
}
 
345
 
 
346
 
 
347
 
 
348
NSAPI_PUBLIC int system_pread(SYS_FILE fd, char *buf, int BytesToRead) {
 
349
    unsigned long BytesRead = 0;
 
350
    int result = 0;
 
351
    BOOLEAN TimeoutSet = FALSE;
 
352
 
 
353
    /* XXXMB - nspr20 should be able to do this; but right now it doesn't
 
354
     * return proper error info.
 
355
     * fix it later...
 
356
     */
 
357
    if(ReadFile((HANDLE)PR_FileDesc2NativeHandle(fd), (LPVOID)buf, BytesToRead, &BytesRead, NULL) == FALSE) {
 
358
        if (GetLastError() == ERROR_BROKEN_PIPE) {
 
359
            return IO_EOF;
 
360
        } else {
 
361
            return IO_ERROR;
 
362
        }
 
363
    }
 
364
    return (BytesRead ? BytesRead : IO_EOF);
 
365
}
 
366
 
 
367
NSAPI_PUBLIC int system_pwrite(SYS_FILE fd, char *buf, int BytesToWrite) 
 
368
{
 
369
    unsigned long BytesWritten;
 
370
    
 
371
    if (WriteFile((HANDLE)PR_FileDesc2NativeHandle(fd), (LPVOID)buf, 
 
372
                  BytesToWrite, &BytesWritten, NULL) == FALSE) {
 
373
        return IO_ERROR;
 
374
    }
 
375
    return BytesWritten;
 
376
}
 
377
 
 
378
 
 
379
NSAPI_PUBLIC int system_fwrite_atomic(SYS_FILE fd, char *buf, int sz) 
 
380
{
 
381
    int ret;
 
382
 
 
383
#if 0
 
384
    if(system_flock(fd) == IO_ERROR)
 
385
        return IO_ERROR;
 
386
#endif
 
387
    /* XXXMB - this is technically thread unsafe, but it catches any 
 
388
     * callers of fwrite_atomic when we're single threaded and just coming
 
389
     * to life.
 
390
     */
 
391
    if (!_atomic_write_lock) {
 
392
        _atomic_write_lock = PR_NewLock();
 
393
    }
 
394
    PR_Lock(_atomic_write_lock);
 
395
    ret = system_fwrite(fd,buf,sz);
 
396
    PR_Unlock(_atomic_write_lock);
 
397
#if 0
 
398
     if(system_ulock(fd) == IO_ERROR)
 
399
        return IO_ERROR;
 
400
#endif
 
401
    return ret;
 
402
}
 
403
 
 
404
 
 
405
NSAPI_PUBLIC void file_unix2local(char *path, char *p2)
 
406
{
 
407
    /* Try to handle UNIX-style paths */
 
408
    if((!strchr(path, FILE_PATHSEP))) {
 
409
        int x;
 
410
 
 
411
        for(x = 0; path[x]; x++)
 
412
            p2[x] = (path[x] == '/' ? '\\' : path[x]);
 
413
        p2[x] = '\0';
 
414
    }
 
415
    else
 
416
        strcpy(p2, path);
 
417
}
 
418
 
 
419
 
 
420
NSAPI_PUBLIC int system_nocoredumps(void)
 
421
{
 
422
    return 0;
 
423
}
 
424
 
 
425
/* --------------------------- system_winerr ------------------------------ */
 
426
 
 
427
 
 
428
#include <winsock.h>
 
429
#include <errno.h>
 
430
#include "util.h"
 
431
 
 
432
NSAPI_PUBLIC char *system_winsockerr(void)
 
433
{
 
434
        int errn = WSAGetLastError();
 
435
 
 
436
        return FindError(errn);
 
437
}
 
438
 
 
439
NSAPI_PUBLIC char *system_winerr(void)
 
440
{
 
441
        int errn = GetLastError();
 
442
 
 
443
        if (errn == 0)
 
444
                errn = WSAGetLastError();
 
445
        return FindError(errn);
 
446
}
 
447
 
 
448
/* ------------------------- Dir related stuff ---------------------------- */
 
449
 
 
450
 
 
451
NSAPI_PUBLIC SYS_DIR dir_open(char *pathp)
 
452
{
 
453
    dir_s *ret = (dir_s *) MALLOC(sizeof(dir_s));
 
454
    char path[MAX_PATH];
 
455
    int l;
 
456
 
 
457
        if (strlen(pathp) >= MAX_PATH) {
 
458
                return NULL;
 
459
        }
 
460
 
 
461
    l = util_sprintf(path, "%s", pathp) - 1;
 
462
        path[strlen(pathp)] = '\0';
 
463
    if(path[strlen(path) - 1] != FILE_PATHSEP)
 
464
                strcpy (path + strlen(path), "\\*.*");
 
465
        else
 
466
                util_sprintf(path, "%s*.*", path);
 
467
 
 
468
    ret->de.d_name = NULL;
 
469
    if( (ret->dp = FindFirstFile(path, &ret->fdata)) != INVALID_HANDLE_VALUE)
 
470
        return ret;
 
471
    FREE(ret);
 
472
    return NULL;
 
473
}
 
474
 
 
475
NSAPI_PUBLIC SYS_DIRENT *dir_read(SYS_DIR ds)
 
476
{
 
477
    if(FindNextFile(ds->dp, &ds->fdata) == FALSE)
 
478
        return NULL;
 
479
    if(ds->de.d_name)
 
480
        FREE(ds->de.d_name);
 
481
    ds->de.d_name = STRDUP(ds->fdata.cFileName);
 
482
 
 
483
    return &ds->de;
 
484
}
 
485
 
 
486
NSAPI_PUBLIC void dir_close(SYS_DIR ds)
 
487
{
 
488
    FindClose(ds->dp);
 
489
    if(ds->de.d_name)
 
490
        FREE(ds->de.d_name);
 
491
    FREE(ds);
 
492
}
 
493
 
 
494
#endif /* FILE_WIN32 */
 
495
 
 
496
NSAPI_PUBLIC int file_notfound(void)
 
497
{
 
498
#ifdef FILE_WIN32
 
499
    int errn = PR_GetError();
 
500
    return (errn == PR_FILE_NOT_FOUND_ERROR);
 
501
#else
 
502
    return (errno == ENOENT);
 
503
#endif
 
504
}
 
505
 
 
506
#ifdef XP_UNIX
 
507
#if !defined(SNI) && !defined(LINUX)
 
508
extern char *sys_errlist[];
 
509
#endif /* SNI */
 
510
#endif
 
511
 
 
512
#define ERRMSG_SIZE 35
 
513
#ifdef THREAD_ANY
 
514
static int errmsg_key = -1;
 
515
#include "systhr.h"
 
516
/* Removed for ns security integration
 
517
#include "xp_error.h"
 
518
*/
 
519
#else /* THREAD_ANY */
 
520
static char errmsg[ERRMSG_SIZE];
 
521
#endif /* THREAD_ANY */
 
522
 
 
523
#include "util.h"
 
524
 
 
525
void system_errmsg_init(void)
 
526
{
 
527
    if (errmsg_key == -1) {
 
528
#if defined(THREAD_ANY)
 
529
        errmsg_key = systhread_newkey();
 
530
#endif
 
531
#ifdef XP_WIN32
 
532
        HashNtErrors();
 
533
#endif
 
534
        if (!_atomic_write_lock)
 
535
            _atomic_write_lock = PR_NewLock();
 
536
    }
 
537
}
 
538
 
 
539
NSAPI_PUBLIC int system_errmsg_fn(char **buff, size_t maxlen)
 
540
{
 
541
    char static_error[128];
 
542
    char *lmsg = 0; /* Local message pointer */
 
543
    size_t msglen = 0;
 
544
    PRErrorCode nscp_error;
 
545
#ifdef XP_WIN32
 
546
    LPTSTR sysmsg = 0;
 
547
#endif
 
548
 
 
549
    nscp_error = PR_GetError();
 
550
 
 
551
    /* If there is a NSPR error, but it is "unknown", try to get the OSError
 
552
     * and use that instead.
 
553
     */
 
554
    if (nscp_error == PR_UNKNOWN_ERROR)
 
555
        errno = PR_GetOSError();
 
556
 
 
557
    if (nscp_error != 0 && nscp_error != PR_UNKNOWN_ERROR){
 
558
        char *nscp_error_msg;
 
559
 
 
560
        nscp_error_msg = nscperror_lookup(nscp_error);
 
561
        if(nscp_error_msg){
 
562
            PR_SetError(0, 0);
 
563
            lmsg = nscp_error_msg;
 
564
        } else {
 
565
            util_snprintf(static_error, sizeof(static_error), "unknown error %d", nscp_error);
 
566
            lmsg = static_error;
 
567
        }
 
568
    } else {
 
569
#if defined(XP_WIN32)
 
570
        msglen = FormatMessage(
 
571
                    FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
 
572
                    NULL, 
 
573
                    GetLastError(), 
 
574
                    LOCALE_SYSTEM_DEFAULT, 
 
575
                    (LPTSTR)&sysmsg, 
 
576
                    0, 
 
577
                    0);
 
578
        if (msglen > 0)
 
579
            lmsg = sysmsg;
 
580
        else
 
581
            lmsg = system_winerr();
 
582
        SetLastError(0);
 
583
#else
 
584
/* replaced
 
585
#if defined(SNI) || defined(LINUX)
 
586
        / C++ platform has no definition for sys_errlist /
 
587
        lmsg = strerror(errno);
 
588
#else
 
589
        lmsg = sys_errlist[errno];
 
590
#endif
 
591
with lmsg =strerror(errno);*/
 
592
        lmsg=strerror(errno);
 
593
        errno = 0;
 
594
#endif
 
595
    }
 
596
 
 
597
    /* At this point lmsg points to something. */
 
598
    msglen = strlen(lmsg);
 
599
 
 
600
    if (*buff == NULL)
 
601
        *buff = STRDUP(lmsg);
 
602
    else if (maxlen > msglen)
 
603
        memcpy(*buff, lmsg, msglen+1);
 
604
    else
 
605
        msglen = 0;
 
606
 
 
607
#ifdef XP_WIN32
 
608
    /* NT's FormatMessage() dynamically allocated the msg; free it */
 
609
    if (sysmsg)
 
610
        LocalFree(sysmsg);
 
611
#endif
 
612
 
 
613
    return msglen;
 
614
}
 
615
 
 
616
NSAPI_PUBLIC const char *
 
617
system_errmsg(void)
 
618
{
 
619
    char *buff = 0;
 
620
 
 
621
    if (errmsg_key == -1)
 
622
        return "unknown early startup error";
 
623
 
 
624
    // rmaxwell - This is extremely lame.
 
625
    // Allocate a buffer in thread local storage to 
 
626
    // hold the last error message.
 
627
    // The whole error message facility is broken and should be
 
628
    // updated to get error strings out of the code.
 
629
    if(!(buff = (char *) systhread_getdata(errmsg_key))) {
 
630
        buff = (char *) PERM_MALLOC(errbuf_size);
 
631
        systhread_setdata(errmsg_key, (void *)buff);
 
632
    }
 
633
    system_errmsg_fn(&buff, errbuf_size);
 
634
    if (buff == 0)
 
635
        return "Could not retrieve system error message";
 
636
    return buff;
 
637
}
 
638
 
 
639
NSAPI_PUBLIC int
 
640
system_rename(char *oldpath, char *newpath)
 
641
{
 
642
    return rename(oldpath, newpath);
 
643
}
 
644
 
 
645
NSAPI_PUBLIC int
 
646
system_unlink(char *path)
 
647
{
 
648
    return PR_Delete(path)==PR_FAILURE?-1:0;
 
649
}
 
650
 
 
651
NSAPI_PUBLIC int system_lseek(SYS_FILE fd, int off, int wh)
 
652
{
 
653
  switch (wh) {
 
654
  case 0:
 
655
    return PR_Seek(fd, off, PR_SEEK_SET);
 
656
    break;
 
657
  case 1:
 
658
    return PR_Seek(fd, off, PR_SEEK_CUR);
 
659
    break;
 
660
  case 2:
 
661
    return PR_Seek(fd, off, PR_SEEK_END);
 
662
    break;
 
663
  default:
 
664
    return  -1;
 
665
  }
 
666
}
 
667
 
 
668
NSAPI_PUBLIC int
 
669
system_tlock(SYS_FILE fd)
 
670
{
 
671
    return PR_TLockFile(fd);
 
672
}
 
673
 
 
674
NSAPI_PUBLIC int
 
675
system_flock(SYS_FILE fd)
 
676
{
 
677
    return PR_LockFile(fd);
 
678
}
 
679
 
 
680
NSAPI_PUBLIC int 
 
681
system_ulock(SYS_FILE fd)
 
682
{
 
683
    return PR_UnlockFile(fd);
 
684
}