]> git.saurik.com Git - wxWidgets.git/blame - src/common/file.cpp
Make radiobutton tab behaviour the same on MSW
[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
a62848fd 205 return true;
1c193821 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 218 m_fd = fd_invalid;
a62848fd 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 230 // Dominic Mazzoni [dmazzoni+@cs.cmu.edu] reports that open is still broken on the mac, so we replace
a2b77260 231 // int fd = open( szFileName , O_CREAT | (bOverwrite ? O_TRUNC : O_EXCL), access);
92980e90 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 252 wxLogSysError(_("can't create file '%s'"), szFileName);
a62848fd 253 return false;
49d5d881 254 }
92980e90
RR
255 else
256 {
49d5d881 257 Attach(fd);
a62848fd 258 return true;
49d5d881 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
1c193821
JS
270 switch ( mode )
271 {
272 case read:
273 access = GENERIC_READ;
274 shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
275 disposition = OPEN_EXISTING;
276 break;
277
278 case write_append:
279 if ( wxFile::Exists(szFileName) )
280 {
281 access = GENERIC_READ|GENERIC_WRITE;
282 shareMode = FILE_SHARE_READ;
283 disposition = 0;
284 break;
285 }
286 //else: fall through as write_append is the same as write if the
287 // file doesn't exist
288
289 case write:
290 access = GENERIC_WRITE;
291 shareMode = 0;
292 disposition = TRUNCATE_EXISTING;
293 break;
294
295 case write_excl:
296 access = GENERIC_WRITE;
297 shareMode = 0;
298 disposition = TRUNCATE_EXISTING;
299 break;
300
301 case read_write:
302 access = GENERIC_READ|GENERIC_WRITE;
303 shareMode = 0;
304 disposition = 0;
305 break;
306 }
307
308 int fd = 0;
309 HANDLE fileHandle = ::CreateFile(szFileName, access, shareMode, NULL,
310 disposition, FILE_ATTRIBUTE_NORMAL, 0);
311 if (fileHandle == INVALID_HANDLE_VALUE)
312 fd = -1;
313 else
314 fd = (int) fileHandle;
315#else
49d5d881 316 int flags = O_BINARY;
c801d85f 317
92980e90
RR
318 switch ( mode )
319 {
49d5d881
VZ
320 case read:
321 flags |= O_RDONLY;
322 break;
c801d85f 323
f6bcfd97
BP
324 case write_append:
325 if ( wxFile::Exists(szFileName) )
326 {
327 flags |= O_WRONLY | O_APPEND;
328 break;
329 }
330 //else: fall through as write_append is the same as write if the
331 // file doesn't exist
332
49d5d881
VZ
333 case write:
334 flags |= O_WRONLY | O_CREAT | O_TRUNC;
335 break;
61b02744 336
68164137
RL
337 case write_excl:
338 flags |= O_WRONLY | O_CREAT | O_EXCL;
339 break;
340
49d5d881
VZ
341 case read_write:
342 flags |= O_RDWR;
343 break;
344 }
c801d85f 345
cc8cc54f
VZ
346#ifdef __WINDOWS__
347 // only read/write bits for "all" are supported by this function under
348 // Windows, and VC++ 8 returns EINVAL if any other bits are used in
349 // accessMode, so clear them as they have at best no effect anyhow
350 accessMode &= wxS_IRUSR | wxS_IWUSR;
351#endif // __WINDOWS__
352
92980e90 353 int fd = wxOpen( szFileName, flags ACCESS(accessMode));
1c193821 354#endif
92980e90
RR
355 if ( fd == -1 )
356 {
49d5d881 357 wxLogSysError(_("can't open file '%s'"), szFileName);
a62848fd 358 return false;
49d5d881
VZ
359 }
360 else {
361 Attach(fd);
a62848fd 362 return true;
49d5d881 363 }
c801d85f
KB
364}
365
366// close
61b02744 367bool wxFile::Close()
c801d85f 368{
49d5d881 369 if ( IsOpened() ) {
1c193821
JS
370#ifdef __WXWINCE__
371 if (!CloseHandle((HANDLE) m_fd))
372#else
373 if ( close(m_fd) == -1 )
374#endif
375 {
49d5d881
VZ
376 wxLogSysError(_("can't close file descriptor %d"), m_fd);
377 m_fd = fd_invalid;
a62848fd 378 return false;
49d5d881
VZ
379 }
380 else
381 m_fd = fd_invalid;
61b02744 382 }
61b02744 383
a62848fd 384 return true;
c801d85f
KB
385}
386
387// ----------------------------------------------------------------------------
388// read/write
389// ----------------------------------------------------------------------------
390
391// read
392off_t wxFile::Read(void *pBuf, off_t nCount)
393{
49d5d881 394 wxCHECK( (pBuf != NULL) && IsOpened(), 0 );
c801d85f 395
1c193821
JS
396#ifdef __WXWINCE__
397 DWORD bytesRead = 0;
398 int iRc = 0;
399 if (ReadFile((HANDLE) m_fd, pBuf, (DWORD) nCount, & bytesRead, NULL))
400 iRc = bytesRead;
401 else
402 iRc = -1;
403#elif defined(__MWERKS__)
49d5d881 404 int iRc = ::read(m_fd, (char*) pBuf, nCount);
469e1e5c 405#else
49d5d881 406 int iRc = ::read(m_fd, pBuf, nCount);
469e1e5c 407#endif
49d5d881
VZ
408 if ( iRc == -1 ) {
409 wxLogSysError(_("can't read from file descriptor %d"), m_fd);
410 return wxInvalidOffset;
411 }
412 else
413 return (size_t)iRc;
c801d85f
KB
414}
415
416// write
c86f1403 417size_t wxFile::Write(const void *pBuf, size_t nCount)
c801d85f 418{
49d5d881 419 wxCHECK( (pBuf != NULL) && IsOpened(), 0 );
c801d85f 420
1c193821 421#ifdef __WXWINCE__
87b6002d 422 DWORD bytesWritten = 0;
1c193821 423 int iRc = 0;
87b6002d
VZ
424 if (WriteFile((HANDLE) m_fd, pBuf, (DWORD) nCount, & bytesWritten, NULL))
425 iRc = bytesWritten;
1c193821
JS
426 else
427 iRc = -1;
428#elif defined(__MWERKS__)
5b781a67
SC
429#if __MSL__ >= 0x6000
430 int iRc = ::write(m_fd, (void*) pBuf, nCount);
431#else
49d5d881 432 int iRc = ::write(m_fd, (const char*) pBuf, nCount);
5b781a67 433#endif
469e1e5c 434#else
49d5d881 435 int iRc = ::write(m_fd, pBuf, nCount);
469e1e5c 436#endif
49d5d881
VZ
437 if ( iRc == -1 ) {
438 wxLogSysError(_("can't write to file descriptor %d"), m_fd);
a62848fd 439 m_error = true;
49d5d881
VZ
440 return 0;
441 }
442 else
443 return iRc;
c801d85f
KB
444}
445
446// flush
447bool wxFile::Flush()
448{
49d5d881 449 if ( IsOpened() ) {
1c193821
JS
450#ifdef __WXWINCE__
451 // Do nothing
452#elif defined(__VISUALC__) || wxHAVE_FSYNC
f6bcfd97 453 if ( wxFsync(m_fd) == -1 )
09914df7
VZ
454 {
455 wxLogSysError(_("can't flush file descriptor %d"), m_fd);
a62848fd 456 return false;
09914df7 457 }
49d5d881 458#else // no fsync
09914df7 459 // just do nothing
49d5d881
VZ
460#endif // fsync
461 }
c801d85f 462
a62848fd 463 return true;
c801d85f
KB
464}
465
466// ----------------------------------------------------------------------------
467// seek
468// ----------------------------------------------------------------------------
469
470// seek
79c3e0e1 471off_t wxFile::Seek(off_t ofs, wxSeekMode mode)
c801d85f 472{
49d5d881
VZ
473 wxASSERT( IsOpened() );
474
1c193821
JS
475#ifdef __WXWINCE__
476 int origin;
477 switch ( mode ) {
478 default:
479 wxFAIL_MSG(_("unknown seek origin"));
480
481 case wxFromStart:
482 origin = FILE_BEGIN;
483 break;
484
485 case wxFromCurrent:
486 origin = FILE_CURRENT;
487 break;
488
489 case wxFromEnd:
490 origin = FILE_END;
491 break;
492 }
493
494 DWORD res = SetFilePointer((HANDLE) m_fd, ofs, 0, origin) ;
495 if (res == 0xFFFFFFFF && GetLastError() != NO_ERROR)
496 {
497 wxLogSysError(_("can't seek on file descriptor %d"), m_fd);
498 return wxInvalidOffset;
499 }
500 else
501 return (off_t)res;
502#else
a1b82138 503 int origin;
49d5d881 504 switch ( mode ) {
a1b82138
VZ
505 default:
506 wxFAIL_MSG(_("unknown seek origin"));
507
49d5d881 508 case wxFromStart:
a1b82138 509 origin = SEEK_SET;
49d5d881
VZ
510 break;
511
512 case wxFromCurrent:
a1b82138 513 origin = SEEK_CUR;
49d5d881
VZ
514 break;
515
516 case wxFromEnd:
a1b82138 517 origin = SEEK_END;
49d5d881 518 break;
49d5d881
VZ
519 }
520
a1b82138 521 int iRc = lseek(m_fd, ofs, origin);
49d5d881
VZ
522 if ( iRc == -1 ) {
523 wxLogSysError(_("can't seek on file descriptor %d"), m_fd);
524 return wxInvalidOffset;
525 }
526 else
527 return (off_t)iRc;
1c193821 528#endif
c801d85f
KB
529}
530
531// get current off_t
532off_t wxFile::Tell() const
533{
49d5d881
VZ
534 wxASSERT( IsOpened() );
535
1c193821
JS
536#ifdef __WXWINCE__
537 DWORD res = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_CURRENT) ;
538 if (res == 0xFFFFFFFF && GetLastError() != NO_ERROR)
539 {
540 wxLogSysError(_("can't get seek position on file descriptor %d"), m_fd);
541 return wxInvalidOffset;
542 }
543 else
544 return (off_t)res;
545#else
f6bcfd97 546 int iRc = wxTell(m_fd);
49d5d881
VZ
547 if ( iRc == -1 ) {
548 wxLogSysError(_("can't get seek position on file descriptor %d"), m_fd);
549 return wxInvalidOffset;
550 }
551 else
552 return (off_t)iRc;
1c193821 553#endif
c801d85f
KB
554}
555
556// get current file length
557off_t wxFile::Length() const
558{
49d5d881 559 wxASSERT( IsOpened() );
c801d85f 560
1c193821
JS
561#ifdef __WXWINCE__
562 DWORD off0 = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_CURRENT);
563 DWORD off1 = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_END);
564 off_t len = off1;
565
566 // Restore position
567 SetFilePointer((HANDLE) m_fd, off0, 0, FILE_BEGIN);
568 return len;
569#else
49d5d881 570#ifdef __VISUALC__
c801d85f 571 int iRc = _filelength(m_fd);
49d5d881 572#else // !VC++
f6bcfd97 573 int iRc = wxTell(m_fd);
c801d85f 574 if ( iRc != -1 ) {
49d5d881
VZ
575 // @ have to use const_cast :-(
576 int iLen = ((wxFile *)this)->SeekEnd();
577 if ( iLen != -1 ) {
578 // restore old position
579 if ( ((wxFile *)this)->Seek(iRc) == -1 ) {
580 // error
581 iLen = -1;
582 }
c801d85f 583 }
c801d85f 584
49d5d881
VZ
585 iRc = iLen;
586 }
587#endif // VC++
588
589 if ( iRc == -1 ) {
590 wxLogSysError(_("can't find length of file on file descriptor %d"), m_fd);
591 return wxInvalidOffset;
c801d85f 592 }
49d5d881
VZ
593 else
594 return (off_t)iRc;
1c193821 595#endif
c801d85f
KB
596}
597
598// is end of file reached?
599bool wxFile::Eof() const
600{
49d5d881 601 wxASSERT( IsOpened() );
c801d85f 602
1c193821
JS
603#ifdef __WXWINCE__
604 DWORD off0 = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_CURRENT);
605 DWORD off1 = SetFilePointer((HANDLE) m_fd, 0, 0, FILE_END);
606 if (off0 == off1)
a62848fd 607 return true;
1c193821
JS
608 else
609 {
610 SetFilePointer((HANDLE) m_fd, off0, 0, FILE_BEGIN);
a62848fd 611 return false;
1c193821
JS
612 }
613#else
49d5d881 614 int iRc;
61b02744 615
d3b4d710 616#if defined(__DOS__) || defined(__UNIX__) || defined(__GNUWIN32__) || defined( __MWERKS__ ) || defined(__SALFORDC__)
61b02744
VZ
617 // @@ this doesn't work, of course, on unseekable file descriptors
618 off_t ofsCur = Tell(),
49d5d881 619 ofsMax = Length();
1678ad78 620 if ( ofsCur == wxInvalidOffset || ofsMax == wxInvalidOffset )
49d5d881 621 iRc = -1;
61b02744 622 else
49d5d881
VZ
623 iRc = ofsCur == ofsMax;
624#else // Windows and "native" compiler
61b02744 625 iRc = eof(m_fd);
49d5d881 626#endif // Windows/Unix
c801d85f 627
49d5d881
VZ
628 switch ( iRc ) {
629 case 1:
630 break;
c801d85f 631
49d5d881 632 case 0:
a62848fd 633 return false;
c801d85f 634
49d5d881 635 case -1:
8e3f1261 636 wxLogSysError(_("can't determine if the end of file is reached on descriptor %d"), m_fd);
49d5d881 637 break;
c801d85f 638
49d5d881
VZ
639 default:
640 wxFAIL_MSG(_("invalid eof() return value."));
641 }
c801d85f 642
a62848fd 643 return true;
1c193821 644#endif
c801d85f
KB
645}
646
647// ============================================================================
648// implementation of wxTempFile
649// ============================================================================
650
651// ----------------------------------------------------------------------------
652// construction
653// ----------------------------------------------------------------------------
44b62d54 654
c801d85f
KB
655wxTempFile::wxTempFile(const wxString& strName)
656{
49d5d881 657 Open(strName);
c801d85f
KB
658}
659
660bool wxTempFile::Open(const wxString& strName)
661{
44b62d54
VZ
662 // we must have an absolute filename because otherwise CreateTempFileName()
663 // would create the temp file in $TMP (i.e. the system standard location
664 // for the temp files) which might be on another volume/drive/mount and
665 // wxRename()ing it later to m_strName from Commit() would then fail
666 //
667 // with the absolute filename, the temp file is created in the same
668 // directory as this one which ensures that wxRename() may work later
669 wxFileName fn(strName);
670 if ( !fn.IsAbsolute() )
671 {
672 fn.Normalize(wxPATH_NORM_ABSOLUTE);
673 }
674
675 m_strName = fn.GetFullPath();
246037e2 676
44b62d54 677 m_strTemp = wxFileName::CreateTempFileName(m_strName, &m_file);
ade35f11
VZ
678
679 if ( m_strTemp.empty() )
680 {
681 // CreateTempFileName() failed
a62848fd 682 return false;
ade35f11 683 }
49d5d881 684
49d5d881 685#ifdef __UNIX__
ade35f11
VZ
686 // the temp file should have the same permissions as the original one
687 mode_t mode;
a62848fd 688
f6bcfd97 689 wxStructStat st;
ca11abde 690 if ( stat( (const char*) m_strName.fn_str(), &st) == 0 )
49d5d881 691 {
ade35f11 692 mode = st.st_mode;
49d5d881
VZ
693 }
694 else
695 {
ade35f11 696 // file probably didn't exist, just give it the default mode _using_
68164137 697 // user's umask (new files creation should respect umask)
ade35f11
VZ
698 mode_t mask = umask(0777);
699 mode = 0666 & ~mask;
700 umask(mask);
49d5d881 701 }
49d5d881 702
ca11abde 703 if ( chmod( (const char*) m_strTemp.fn_str(), mode) == -1 )
fe99e285 704 {
5a3912f2 705#ifndef __OS2__
ade35f11 706 wxLogSysError(_("Failed to set temporary file permissions"));
5a3912f2 707#endif
fe99e285 708 }
49d5d881 709#endif // Unix
246037e2 710
a62848fd 711 return true;
c801d85f
KB
712}
713
714// ----------------------------------------------------------------------------
715// destruction
716// ----------------------------------------------------------------------------
717
718wxTempFile::~wxTempFile()
719{
49d5d881
VZ
720 if ( IsOpened() )
721 Discard();
c801d85f
KB
722}
723
724bool wxTempFile::Commit()
725{
49d5d881 726 m_file.Close();
c801d85f 727
f6bcfd97 728 if ( wxFile::Exists(m_strName) && wxRemove(m_strName) != 0 ) {
49d5d881 729 wxLogSysError(_("can't remove file '%s'"), m_strName.c_str());
a62848fd 730 return false;
49d5d881 731 }
c801d85f 732
f35746ce 733 if ( !wxRenameFile(m_strTemp, m_strName) ) {
49d5d881 734 wxLogSysError(_("can't commit changes to file '%s'"), m_strName.c_str());
a62848fd 735 return false;
49d5d881 736 }
c801d85f 737
a62848fd 738 return true;
c801d85f
KB
739}
740
741void wxTempFile::Discard()
742{
49d5d881 743 m_file.Close();
f6bcfd97 744 if ( wxRemove(m_strTemp) != 0 )
49d5d881 745 wxLogSysError(_("can't remove temporary file '%s'"), m_strTemp.c_str());
c801d85f 746}
ce4169a4 747
ade35f11 748#endif // wxUSE_FILE
cc985fac 749