]> git.saurik.com Git - wxWidgets.git/blame - src/common/file.cpp
Get rid of wxUSE_GSOCKET_CPLUSPLUS
[wxWidgets.git] / src / common / file.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: file.cpp
3// Purpose: wxFile - encapsulates low-level "file descriptor"
4// wxTempFile
5// Author: Vadim Zeitlin
6// Modified by:
7// Created: 29/01/98
8// RCS-ID: $Id$
9// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 10// Licence: wxWindows licence
c801d85f
KB
11/////////////////////////////////////////////////////////////////////////////
12
6ba45edb
VZ
13/*
14 TODO: remove all the WinCE ugliness from here, implement the wxOpen(),
15 wxSeek(), ... functions in a separate file for WinCE instead!!!
16 */
17
c801d85f
KB
18// ----------------------------------------------------------------------------
19// headers
20// ----------------------------------------------------------------------------
21
14f355c2 22#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
3f4a0c5b 23 #pragma implementation "file.h"
c801d85f
KB
24#endif
25
26// For compilers that support precompilation, includes "wx.h".
27#include "wx/wxprec.h"
c801d85f
KB
28
29#ifdef __BORLANDC__
ce4169a4 30 #pragma hdrstop
c801d85f
KB
31#endif
32
ce4169a4
RR
33#if wxUSE_FILE
34
c801d85f 35// standard
1c193821 36#if defined(__WXMSW__) && !defined(__GNUWIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
c801d85f 37 #include <io.h>
30a5be97 38
a3ef5bf5 39#ifndef __SALFORDC__
49d5d881
VZ
40 #define WIN32_LEAN_AND_MEAN
41 #define NOSERVICE
42 #define NOIME
43 #define NOATOM
44 #define NOGDI
45 #define NOGDICAPMASKS
46 #define NOMETAFILE
47 #define NOMINMAX
48 #define NOMSG
49 #define NOOPENFILE
50 #define NORASTEROPS
51 #define NOSCROLL
52 #define NOSOUND
53 #define NOSYSMETRICS
54 #define NOTEXTMETRIC
55 #define NOWH
56 #define NOCOMM
57 #define NOKANJI
58 #define NOCRYPT
59 #define NOMCX
a3ef5bf5
JS
60#endif
61
1c193821
JS
62#elif defined(__WXMSW__) && defined(__WXWINCE__)
63 // TODO: what to include?
5a3912f2
SN
64#elif (defined(__OS2__))
65 #include <io.h>
c801d85f 66#elif (defined(__UNIX__) || defined(__GNUWIN32__))
3f4a0c5b 67 #include <unistd.h>
fd938b11 68 #include <time.h>
732b8386 69 #include <sys/stat.h>
3f4a0c5b 70 #ifdef __GNUWIN32__
9ed0d735 71 #include "wx/msw/wrapwin.h"
3f4a0c5b 72 #endif
d3b4d710
VS
73#elif defined(__DOS__)
74 #if defined(__WATCOMC__)
75 #include <io.h>
76 #elif defined(__DJGPP__)
77 #include <io.h>
78 #include <unistd.h>
79 #include <stdio.h>
80 #else
81 #error "Please specify the header with file functions declarations."
82 #endif
34138703 83#elif (defined(__WXSTUBS__))
3f4a0c5b
VZ
84 // Have to ifdef this for different environments
85 #include <io.h>
17dff81c 86#elif (defined(__WXMAC__))
5b781a67 87#if __MSL__ < 0x6000
3f4a0c5b 88 int access( const char *path, int mode ) { return 0 ; }
5b781a67
SC
89#else
90 int _access( const char *path, int mode ) { return 0 ; }
91#endif
3f4a0c5b 92 char* mktemp( char * path ) { return path ;}
5b781a67 93 #include <stat.h>
5b781a67 94 #include <unistd.h>
c801d85f 95#else
3f4a0c5b 96 #error "Please specify the header with file functions declarations."
c801d85f
KB
97#endif //Win/UNIX
98
99#include <stdio.h> // SEEK_xxx constants
1c193821
JS
100
101#ifndef __WXWINCE__
c801d85f 102#include <fcntl.h> // O_RDONLY &c
1c193821 103#endif
a3ef5bf5 104
1c193821
JS
105#ifdef __WXWINCE__
106// Nothing
107#elif !defined(__MWERKS__)
31907d03
SC
108 #include <sys/types.h> // needed for stat
109 #include <sys/stat.h> // stat
110#elif defined(__MWERKS__) && ( defined(__WXMSW__) || defined(__MACH__) )
de85a884
VZ
111 #include <sys/types.h> // needed for stat
112 #include <sys/stat.h> // stat
469e1e5c 113#endif
c801d85f 114
4ea2c29f
VZ
115// Windows compilers don't have these constants
116#ifndef W_OK
117 enum
118 {
119 F_OK = 0, // test for existence
120 X_OK = 1, // execute permission
121 W_OK = 2, // write
122 R_OK = 4 // read
123 };
124#endif // W_OK
34138703 125
b12915c1
VZ
126// there is no distinction between text and binary files under Unix, so define
127// O_BINARY as 0 if the system headers don't do it already
128#if defined(__UNIX__) && !defined(O_BINARY)
49d5d881 129 #define O_BINARY (0)
246037e2 130#endif //__UNIX__
c801d85f 131
a3ef5bf5 132#ifdef __SALFORDC__
3f4a0c5b 133 #include <unix.h>
a3ef5bf5
JS
134#endif
135
81d66cf3 136#ifndef MAX_PATH
3f4a0c5b 137 #define MAX_PATH 512
81d66cf3 138#endif
c801d85f 139
49d5d881
VZ
140// some broken compilers don't have 3rd argument in open() and creat()
141#ifdef __SALFORDC__
142 #define ACCESS(access)
143 #define stat _stat
144#else // normal compiler
145 #define ACCESS(access) , (access)
146#endif // Salford C
147
77ffb593 148// wxWidgets
ade35f11
VZ
149#ifndef WX_PRECOMP
150 #include "wx/string.h"
151 #include "wx/intl.h"
ade35f11
VZ
152 #include "wx/log.h"
153#endif // !WX_PRECOMP
154
155#include "wx/filename.h"
44d568b6 156#include "wx/file.h"
4ea2c29f 157#include "wx/filefn.h"
f6bcfd97 158
28f5082b
VS
159#ifdef __WXMSW__
160 #include "wx/msw/mslu.h"
161#endif
162
1c193821
JS
163#ifdef __WXWINCE__
164 #include "wx/msw/private.h"
165#endif
166
c801d85f
KB
167// ============================================================================
168// implementation of wxFile
169// ============================================================================
170
171// ----------------------------------------------------------------------------
172// static functions
173// ----------------------------------------------------------------------------
4ea2c29f 174
50920146 175bool wxFile::Exists(const wxChar *name)
246037e2 176{
4ea2c29f 177 return wxFileExists(name);
d1427b70
VZ
178}
179
50920146 180bool wxFile::Access(const wxChar *name, OpenMode mode)
d1427b70 181{
4ea2c29f
VZ
182 int how;
183
184 switch ( mode )
185 {
186 default:
187 wxFAIL_MSG(wxT("bad wxFile::Access mode parameter."));
188 // fall through
d1427b70 189
49d5d881
VZ
190 case read:
191 how = R_OK;
192 break;
d1427b70 193
49d5d881
VZ
194 case write:
195 how = W_OK;
196 break;
d1427b70 197
4ea2c29f
VZ
198 case read_write:
199 how = R_OK | W_OK;
200 break;
49d5d881 201 }
d1427b70 202
1c193821
JS
203#ifdef __WXWINCE__
204 // FIXME: use CreateFile with 0 access to query the file
205 return TRUE;
206#else
4ea2c29f 207 return wxAccess(name, how) == 0;
1c193821 208#endif
c801d85f
KB
209}
210
211// ----------------------------------------------------------------------------
212// opening/closing
213// ----------------------------------------------------------------------------
214
215// ctors
50920146 216wxFile::wxFile(const wxChar *szFileName, OpenMode mode)
c801d85f 217{
49d5d881
VZ
218 m_fd = fd_invalid;
219 m_error = FALSE;
c801d85f 220
49d5d881 221 Open(szFileName, mode);
c801d85f
KB
222}
223
c801d85f 224// create the file, fail if it already exists and bOverwrite
50920146 225bool wxFile::Create(const wxChar *szFileName, bool bOverwrite, int accessMode)
c801d85f 226{
49d5d881
VZ
227 // if bOverwrite we create a new file or truncate the existing one,
228 // otherwise we only create the new file and fail if it already exists
c4e41ce3 229#if defined(__WXMAC__) && !defined(__UNIX__) && !wxUSE_UNICODE
92980e90
RR
230 // Dominic Mazzoni [dmazzoni+@cs.cmu.edu] reports that open is still broken on the mac, so we replace
231 // int fd = open(wxUnix2MacFilename( szFileName ), O_CREAT | (bOverwrite ? O_TRUNC : O_EXCL), access);
232 int fd = creat( szFileName , accessMode);
1c193821
JS
233#else
234#ifdef __WXWINCE__
235 HANDLE fileHandle = ::CreateFile(szFileName, GENERIC_WRITE, 0, NULL,
236 bOverwrite ? CREATE_ALWAYS : CREATE_NEW, FILE_ATTRIBUTE_NORMAL,
237 0);
238 int fd = 0;
239 if (fileHandle == INVALID_HANDLE_VALUE)
240 fd = (int) fileHandle;
241 else
242 fd = -1;
7c74e7fe 243#else
92980e90
RR
244 int fd = wxOpen( szFileName,
245 O_BINARY | O_WRONLY | O_CREAT |
246 (bOverwrite ? O_TRUNC : O_EXCL)
247 ACCESS(accessMode) );
1c193821 248#endif
7c74e7fe 249#endif
92980e90
RR
250 if ( fd == -1 )
251 {
49d5d881
VZ
252 wxLogSysError(_("can't create file '%s'"), szFileName);
253 return FALSE;
254 }
92980e90
RR
255 else
256 {
49d5d881
VZ
257 Attach(fd);
258 return TRUE;
259 }
c801d85f
KB
260}
261
262// open the file
50920146 263bool wxFile::Open(const wxChar *szFileName, OpenMode mode, int accessMode)
c801d85f 264{
1c193821
JS
265#ifdef __WXWINCE__
266 DWORD access = 0;
267 DWORD shareMode = 0;
268 DWORD disposition = 0;
269
270 int flags = O_BINARY;
271
272 switch ( mode )
273 {
274 case read:
275 access = GENERIC_READ;
276 shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
277 disposition = OPEN_EXISTING;
278 break;
279
280 case write_append:
281 if ( wxFile::Exists(szFileName) )
282 {
283 access = GENERIC_READ|GENERIC_WRITE;
284 shareMode = FILE_SHARE_READ;
285 disposition = 0;
286 break;
287 }
288 //else: fall through as write_append is the same as write if the
289 // file doesn't exist
290
291 case write:
292 access = GENERIC_WRITE;
293 shareMode = 0;
294 disposition = TRUNCATE_EXISTING;
295 break;
296
297 case write_excl:
298 access = GENERIC_WRITE;
299 shareMode = 0;
300 disposition = TRUNCATE_EXISTING;
301 break;
302
303 case read_write:
304 access = GENERIC_READ|GENERIC_WRITE;
305 shareMode = 0;
306 disposition = 0;
307 break;
308 }
309
310 int fd = 0;
311 HANDLE fileHandle = ::CreateFile(szFileName, access, shareMode, NULL,
312 disposition, FILE_ATTRIBUTE_NORMAL, 0);
313 if (fileHandle == INVALID_HANDLE_VALUE)
314 fd = -1;
315 else
316 fd = (int) fileHandle;
317#else
49d5d881 318 int flags = O_BINARY;
c801d85f 319
92980e90
RR
320 switch ( mode )
321 {
49d5d881
VZ
322 case read:
323 flags |= O_RDONLY;
324 break;
c801d85f 325
f6bcfd97
BP
326 case write_append:
327 if ( wxFile::Exists(szFileName) )
328 {
329 flags |= O_WRONLY | O_APPEND;
330 break;
331 }
332 //else: fall through as write_append is the same as write if the
333 // file doesn't exist
334
49d5d881
VZ
335 case write:
336 flags |= O_WRONLY | O_CREAT | O_TRUNC;
337 break;
61b02744 338
68164137
RL
339 case write_excl:
340 flags |= O_WRONLY | O_CREAT | O_EXCL;
341 break;
342
49d5d881
VZ
343 case read_write:
344 flags |= O_RDWR;
345 break;
346 }
c801d85f 347
cc8cc54f
VZ
348#ifdef __WINDOWS__
349 // only read/write bits for "all" are supported by this function under
350 // Windows, and VC++ 8 returns EINVAL if any other bits are used in
351 // accessMode, so clear them as they have at best no effect anyhow
352 accessMode &= wxS_IRUSR | wxS_IWUSR;
353#endif // __WINDOWS__
354
92980e90 355 int fd = wxOpen( szFileName, flags ACCESS(accessMode));
1c193821 356#endif
92980e90
RR
357 if ( fd == -1 )
358 {
49d5d881
VZ
359 wxLogSysError(_("can't open file '%s'"), szFileName);
360 return FALSE;
361 }
362 else {
363 Attach(fd);
364 return TRUE;
365 }
c801d85f
KB
366}
367
368// close
61b02744 369bool wxFile::Close()
c801d85f 370{
49d5d881 371 if ( IsOpened() ) {
1c193821
JS
372#ifdef __WXWINCE__
373 if (!CloseHandle((HANDLE) m_fd))
374#else
375 if ( close(m_fd) == -1 )
376#endif
377 {
49d5d881
VZ
378 wxLogSysError(_("can't close file descriptor %d"), m_fd);
379 m_fd = fd_invalid;
380 return FALSE;
381 }
382 else
383 m_fd = fd_invalid;
61b02744 384 }
61b02744 385
49d5d881 386 return TRUE;
c801d85f
KB
387}
388
389// ----------------------------------------------------------------------------
390// read/write
391// ----------------------------------------------------------------------------
392
393// read
394off_t wxFile::Read(void *pBuf, off_t nCount)
395{
49d5d881 396 wxCHECK( (pBuf != NULL) && IsOpened(), 0 );
c801d85f 397
1c193821
JS
398#ifdef __WXWINCE__
399 DWORD bytesRead = 0;
400 int iRc = 0;
401 if (ReadFile((HANDLE) m_fd, pBuf, (DWORD) nCount, & bytesRead, NULL))
402 iRc = bytesRead;
403 else
404 iRc = -1;
405#elif defined(__MWERKS__)
49d5d881 406 int iRc = ::read(m_fd, (char*) pBuf, nCount);
469e1e5c 407#else
49d5d881 408 int iRc = ::read(m_fd, pBuf, nCount);
469e1e5c 409#endif
49d5d881
VZ
410 if ( iRc == -1 ) {
411 wxLogSysError(_("can't read from file descriptor %d"), m_fd);
412 return wxInvalidOffset;
413 }
414 else
415 return (size_t)iRc;
c801d85f
KB
416}
417
418// write
c86f1403 419size_t wxFile::Write(const void *pBuf, size_t nCount)
c801d85f 420{
49d5d881 421 wxCHECK( (pBuf != NULL) && IsOpened(), 0 );
c801d85f 422
1c193821 423#ifdef __WXWINCE__
87b6002d 424 DWORD bytesWritten = 0;
1c193821 425 int iRc = 0;
87b6002d
VZ
426 if (WriteFile((HANDLE) m_fd, pBuf, (DWORD) nCount, & bytesWritten, NULL))
427 iRc = bytesWritten;
1c193821
JS
428 else
429 iRc = -1;
430#elif defined(__MWERKS__)
5b781a67
SC
431#if __MSL__ >= 0x6000
432 int iRc = ::write(m_fd, (void*) pBuf, nCount);
433#else
49d5d881 434 int iRc = ::write(m_fd, (const char*) pBuf, nCount);
5b781a67 435#endif
469e1e5c 436#else
49d5d881 437 int iRc = ::write(m_fd, pBuf, nCount);
469e1e5c 438#endif
49d5d881
VZ
439 if ( iRc == -1 ) {
440 wxLogSysError(_("can't write to file descriptor %d"), m_fd);
441 m_error = TRUE;
442 return 0;
443 }
444 else
445 return iRc;
c801d85f
KB
446}
447
448// flush
449bool wxFile::Flush()
450{
49d5d881 451 if ( IsOpened() ) {
1c193821
JS
452#ifdef __WXWINCE__
453 // Do nothing
454#elif defined(__VISUALC__) || wxHAVE_FSYNC
f6bcfd97 455 if ( wxFsync(m_fd) == -1 )
09914df7
VZ
456 {
457 wxLogSysError(_("can't flush file descriptor %d"), m_fd);
458 return FALSE;
459 }
49d5d881 460#else // no fsync
09914df7 461 // just do nothing
49d5d881
VZ
462#endif // fsync
463 }
c801d85f 464
49d5d881 465 return TRUE;
c801d85f
KB
466}
467
468// ----------------------------------------------------------------------------
469// seek
470// ----------------------------------------------------------------------------
471
472// seek
79c3e0e1 473off_t wxFile::Seek(off_t ofs, wxSeekMode mode)
c801d85f 474{
49d5d881
VZ
475 wxASSERT( IsOpened() );
476
1c193821
JS
477#ifdef __WXWINCE__
478 int origin;
479 switch ( mode ) {
480 default:
481 wxFAIL_MSG(_("unknown seek origin"));
482
483 case wxFromStart:
484 origin = FILE_BEGIN;
485 break;
486
487 case wxFromCurrent:
488 origin = FILE_CURRENT;
489 break;
490
491 case wxFromEnd:
492 origin = FILE_END;
493 break;
494 }
495
496 DWORD res = SetFilePointer((HANDLE) m_fd, ofs, 0, origin) ;
497 if (res == 0xFFFFFFFF && GetLastError() != NO_ERROR)
498 {
499 wxLogSysError(_("can't seek on file descriptor %d"), m_fd);
500 return wxInvalidOffset;
501 }
502 else
503 return (off_t)res;
504#else
a1b82138 505 int origin;
49d5d881 506 switch ( mode ) {
a1b82138
VZ
507 default:
508 wxFAIL_MSG(_("unknown seek origin"));
509
49d5d881 510 case wxFromStart:
a1b82138 511 origin = SEEK_SET;
49d5d881
VZ
512 break;
513
514 case wxFromCurrent:
a1b82138 515 origin = SEEK_CUR;
49d5d881
VZ
516 break;
517
518 case wxFromEnd:
a1b82138 519 origin = SEEK_END;
49d5d881 520 break;
49d5d881
VZ
521 }
522
a1b82138 523 int iRc = lseek(m_fd, ofs, origin);
49d5d881
VZ
524 if ( iRc == -1 ) {
525 wxLogSysError(_("can't seek on file descriptor %d"), m_fd);
526 return wxInvalidOffset;
527 }
528 else
529 return (off_t)iRc;
1c193821 530#endif
c801d85f
KB
531}
532
533// get current off_t
534off_t wxFile::Tell() const
535{
49d5d881
VZ
536 wxASSERT( IsOpened() );
537
1c193821
JS
538#ifdef __WXWINCE__
539 DWORD res = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_CURRENT) ;
540 if (res == 0xFFFFFFFF && GetLastError() != NO_ERROR)
541 {
542 wxLogSysError(_("can't get seek position on file descriptor %d"), m_fd);
543 return wxInvalidOffset;
544 }
545 else
546 return (off_t)res;
547#else
f6bcfd97 548 int iRc = wxTell(m_fd);
49d5d881
VZ
549 if ( iRc == -1 ) {
550 wxLogSysError(_("can't get seek position on file descriptor %d"), m_fd);
551 return wxInvalidOffset;
552 }
553 else
554 return (off_t)iRc;
1c193821 555#endif
c801d85f
KB
556}
557
558// get current file length
559off_t wxFile::Length() const
560{
49d5d881 561 wxASSERT( IsOpened() );
c801d85f 562
1c193821
JS
563#ifdef __WXWINCE__
564 DWORD off0 = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_CURRENT);
565 DWORD off1 = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_END);
566 off_t len = off1;
567
568 // Restore position
569 SetFilePointer((HANDLE) m_fd, off0, 0, FILE_BEGIN);
570 return len;
571#else
49d5d881 572#ifdef __VISUALC__
c801d85f 573 int iRc = _filelength(m_fd);
49d5d881 574#else // !VC++
f6bcfd97 575 int iRc = wxTell(m_fd);
c801d85f 576 if ( iRc != -1 ) {
49d5d881
VZ
577 // @ have to use const_cast :-(
578 int iLen = ((wxFile *)this)->SeekEnd();
579 if ( iLen != -1 ) {
580 // restore old position
581 if ( ((wxFile *)this)->Seek(iRc) == -1 ) {
582 // error
583 iLen = -1;
584 }
c801d85f 585 }
c801d85f 586
49d5d881
VZ
587 iRc = iLen;
588 }
589#endif // VC++
590
591 if ( iRc == -1 ) {
592 wxLogSysError(_("can't find length of file on file descriptor %d"), m_fd);
593 return wxInvalidOffset;
c801d85f 594 }
49d5d881
VZ
595 else
596 return (off_t)iRc;
1c193821 597#endif
c801d85f
KB
598}
599
600// is end of file reached?
601bool wxFile::Eof() const
602{
49d5d881 603 wxASSERT( IsOpened() );
c801d85f 604
1c193821
JS
605#ifdef __WXWINCE__
606 DWORD off0 = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_CURRENT);
607 DWORD off1 = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_END);
608 if (off0 == off1)
609 return TRUE;
610 else
611 {
612 SetFilePointer((HANDLE) m_fd, off0, 0, FILE_BEGIN);
613 return FALSE;
614 }
615#else
49d5d881 616 int iRc;
61b02744 617
d3b4d710 618#if defined(__DOS__) || defined(__UNIX__) || defined(__GNUWIN32__) || defined( __MWERKS__ ) || defined(__SALFORDC__)
61b02744
VZ
619 // @@ this doesn't work, of course, on unseekable file descriptors
620 off_t ofsCur = Tell(),
49d5d881 621 ofsMax = Length();
1678ad78 622 if ( ofsCur == wxInvalidOffset || ofsMax == wxInvalidOffset )
49d5d881 623 iRc = -1;
61b02744 624 else
49d5d881
VZ
625 iRc = ofsCur == ofsMax;
626#else // Windows and "native" compiler
61b02744 627 iRc = eof(m_fd);
49d5d881 628#endif // Windows/Unix
c801d85f 629
49d5d881
VZ
630 switch ( iRc ) {
631 case 1:
632 break;
c801d85f 633
49d5d881
VZ
634 case 0:
635 return FALSE;
c801d85f 636
49d5d881 637 case -1:
8e3f1261 638 wxLogSysError(_("can't determine if the end of file is reached on descriptor %d"), m_fd);
49d5d881 639 break;
c801d85f 640
49d5d881
VZ
641 default:
642 wxFAIL_MSG(_("invalid eof() return value."));
643 }
c801d85f 644
49d5d881 645 return TRUE;
1c193821 646#endif
c801d85f
KB
647}
648
649// ============================================================================
650// implementation of wxTempFile
651// ============================================================================
652
653// ----------------------------------------------------------------------------
654// construction
655// ----------------------------------------------------------------------------
44b62d54 656
c801d85f
KB
657wxTempFile::wxTempFile(const wxString& strName)
658{
49d5d881 659 Open(strName);
c801d85f
KB
660}
661
662bool wxTempFile::Open(const wxString& strName)
663{
44b62d54
VZ
664 // we must have an absolute filename because otherwise CreateTempFileName()
665 // would create the temp file in $TMP (i.e. the system standard location
666 // for the temp files) which might be on another volume/drive/mount and
667 // wxRename()ing it later to m_strName from Commit() would then fail
668 //
669 // with the absolute filename, the temp file is created in the same
670 // directory as this one which ensures that wxRename() may work later
671 wxFileName fn(strName);
672 if ( !fn.IsAbsolute() )
673 {
674 fn.Normalize(wxPATH_NORM_ABSOLUTE);
675 }
676
677 m_strName = fn.GetFullPath();
246037e2 678
44b62d54 679 m_strTemp = wxFileName::CreateTempFileName(m_strName, &m_file);
ade35f11
VZ
680
681 if ( m_strTemp.empty() )
682 {
683 // CreateTempFileName() failed
684 return FALSE;
685 }
49d5d881 686
49d5d881 687#ifdef __UNIX__
ade35f11
VZ
688 // the temp file should have the same permissions as the original one
689 mode_t mode;
ca11abde 690
f6bcfd97 691 wxStructStat st;
ca11abde 692 if ( stat( (const char*) m_strName.fn_str(), &st) == 0 )
49d5d881 693 {
ade35f11 694 mode = st.st_mode;
49d5d881
VZ
695 }
696 else
697 {
ade35f11 698 // file probably didn't exist, just give it the default mode _using_
68164137 699 // user's umask (new files creation should respect umask)
ade35f11
VZ
700 mode_t mask = umask(0777);
701 mode = 0666 & ~mask;
702 umask(mask);
49d5d881 703 }
49d5d881 704
ca11abde 705 if ( chmod( (const char*) m_strTemp.fn_str(), mode) == -1 )
fe99e285 706 {
5a3912f2 707#ifndef __OS2__
ade35f11 708 wxLogSysError(_("Failed to set temporary file permissions"));
5a3912f2 709#endif
fe99e285 710 }
49d5d881 711#endif // Unix
246037e2 712
ade35f11 713 return TRUE;
c801d85f
KB
714}
715
716// ----------------------------------------------------------------------------
717// destruction
718// ----------------------------------------------------------------------------
719
720wxTempFile::~wxTempFile()
721{
49d5d881
VZ
722 if ( IsOpened() )
723 Discard();
c801d85f
KB
724}
725
726bool wxTempFile::Commit()
727{
49d5d881 728 m_file.Close();
c801d85f 729
f6bcfd97 730 if ( wxFile::Exists(m_strName) && wxRemove(m_strName) != 0 ) {
49d5d881
VZ
731 wxLogSysError(_("can't remove file '%s'"), m_strName.c_str());
732 return FALSE;
733 }
c801d85f 734
f35746ce 735 if ( !wxRenameFile(m_strTemp, m_strName) ) {
49d5d881
VZ
736 wxLogSysError(_("can't commit changes to file '%s'"), m_strName.c_str());
737 return FALSE;
738 }
c801d85f 739
49d5d881 740 return TRUE;
c801d85f
KB
741}
742
743void wxTempFile::Discard()
744{
49d5d881 745 m_file.Close();
f6bcfd97 746 if ( wxRemove(m_strTemp) != 0 )
49d5d881 747 wxLogSysError(_("can't remove temporary file '%s'"), m_strTemp.c_str());
c801d85f 748}
ce4169a4 749
ade35f11 750#endif // wxUSE_FILE
cc985fac 751