ReactOS 0.4.16-dev-1019-g2c2cdfd
open.cpp File Reference
#include <corecrt_internal_lowio.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
Include dependency graph for open.cpp:

Go to the source code of this file.

Classes

struct  anonymous_namespace{open.cpp}::file_options
 

Namespaces

namespace  anonymous_namespace{open.cpp}
 

Macros

#define UTF16LE_BOM   0xFEFF
 
#define UTF16BE_BOM   0xFFFE
 
#define BOM_MASK   0xFFFF
 
#define UTF8_BOM   0xBFBBEF
 
#define UTF16_BOMLEN   2
 
#define UTF8_BOMLEN   3
 

Functions

template<typename Character >
static int __cdecl common_open (_In_z_ Character const *const path, int const oflag, int const pmode) throw ()
 
int _open (char const *const path, int const oflag,...)
 
int _wopen (wchar_t const *const path, int const oflag,...)
 
template<typename Character >
static errno_t __cdecl common_sopen_dispatch (_In_z_ Character const *const path, int const oflag, int const shflag, int const pmode, int *const pfh, int const secure) throw ()
 
errno_t __cdecl _sopen_dispatch (char const *const path, int const oflag, int const shflag, int const pmode, int *const pfh, int const secure)
 
errno_t __cdecl _wsopen_dispatch (wchar_t const *const path, int const oflag, int const shflag, int const pmode, int *const pfh, int const secure)
 
static HANDLE __cdecl create_file (PCWSTR const path, SECURITY_ATTRIBUTES *const security_attributes, file_options const options) throw ()
 
static DWORD decode_access_flags (int const oflag) throw ()
 
static DWORD decode_open_create_flags (int const oflag) throw ()
 
static DWORD decode_sharing_flags (int const shflag, int const access) throw ()
 
static bool is_text_mode (int const oflag) throw ()
 
static file_options decode_options (int const oflag, int const shflag, int const pmode) throw ()
 
static errno_t truncate_ctrl_z_if_present (int const fh) throw ()
 
static errno_t configure_text_mode (int const fh, file_options const options, int oflag, __crt_lowio_text_mode &text_mode) throw ()
 
errno_t __cdecl _wsopen_nolock (int *const punlock_flag, int *const pfh, wchar_t const *const path, int const oflag, int const shflag, int const pmode, int const secure)
 
errno_t __cdecl _sopen_nolock (int *const punlock_flag, int *const pfh, char const *const path, int const oflag, int const shflag, int const pmode, int const secure)
 
int __cdecl _sopen (char const *const path, int const oflag, int const shflag,...)
 
int __cdecl _wsopen (wchar_t const *const path, int const oflag, int const shflag,...)
 
errno_t __cdecl _sopen_s (int *const pfh, char const *const path, int const oflag, int const shflag, int const pmode)
 
errno_t __cdecl _wsopen_s (int *const pfh, wchar_t const *const path, int const oflag, int const shflag, int const pmode)
 

Variables

DWORD const anonymous_namespace{open.cpp}::GENERIC_READ_WRITE = (GENERIC_READ | GENERIC_WRITE)
 

Macro Definition Documentation

◆ BOM_MASK

#define BOM_MASK   0xFFFF

Definition at line 78 of file open.cpp.

◆ UTF16_BOMLEN

#define UTF16_BOMLEN   2

Definition at line 80 of file open.cpp.

◆ UTF16BE_BOM

#define UTF16BE_BOM   0xFFFE

Definition at line 77 of file open.cpp.

◆ UTF16LE_BOM

#define UTF16LE_BOM   0xFEFF

Definition at line 76 of file open.cpp.

◆ UTF8_BOM

#define UTF8_BOM   0xBFBBEF

Definition at line 79 of file open.cpp.

◆ UTF8_BOMLEN

#define UTF8_BOMLEN   3

Definition at line 81 of file open.cpp.

Function Documentation

◆ _open()

int _open ( char const *const  path,
int const  oflag,
  ... 
)

Definition at line 124 of file open.cpp.

125{
127 va_start(arglist, oflag);
128 int const pmode = va_arg(arglist, int);
130
131 return common_open(path, oflag, pmode);
132}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
static int __cdecl common_open(_In_z_ Character const *const path, int const oflag, int const pmode)
Definition: open.cpp:84
va_lists_t arglist[FMT_ARGMAX+1]
Definition: format.c:284

Referenced by _creat(), compat_open(), install_from_unix_file(), main(), rd_open_file(), rw(), test__popen(), test__sopen_s(), test_chsize(), test_file_write_read(), test_get_osfhandle(), test_ioinfo_flags(), test_setmode(), and tmpfile().

◆ _sopen()

int __cdecl _sopen ( char const *const  path,
int const  oflag,
int const  shflag,
  ... 
)

Definition at line 859 of file open.cpp.

860{
861 va_list ap;
862 va_start(ap, shflag);
863 int const pmode = va_arg(ap, int);
864 va_end(ap);
865
866 // The last argument is 0 so thta the pmode is not validated in open_s:
867 int fh = -1;
868 errno_t const result = _sopen_dispatch(path, oflag, shflag, pmode, &fh, FALSE);
869 return result ? -1 : fh;
870}
#define FALSE
Definition: types.h:117
GLuint64EXT * result
Definition: glext.h:11304
errno_t __cdecl _sopen_dispatch(char const *const path, int const oflag, int const shflag, int const pmode, int *const pfh, int const secure)
Definition: open.cpp:196
int errno_t
Definition: corecrt.h:615
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36

Referenced by _open(), and test_get_osfhandle().

◆ _sopen_dispatch()

errno_t __cdecl _sopen_dispatch ( char const *const  path,
int const  oflag,
int const  shflag,
int const  pmode,
int *const  pfh,
int const  secure 
)

Definition at line 196 of file open.cpp.

204{
205 return common_sopen_dispatch(path, oflag, shflag, pmode, pfh, secure);
206}
static int secure
Definition: server.c:138
static errno_t __cdecl common_sopen_dispatch(_In_z_ Character const *const path, int const oflag, int const shflag, int const pmode, int *const pfh, int const secure)
Definition: open.cpp:147

Referenced by _sopen(), _sopen_s(), and test__sopen_dispatch().

◆ _sopen_nolock()

errno_t __cdecl _sopen_nolock ( int *const  punlock_flag,
int *const  pfh,
char const *const  path,
int const  oflag,
int const  shflag,
int const  pmode,
int const  secure 
)

Definition at line 835 of file open.cpp.

844{
845 // At this point we know path is not null already
847
849
850 if (cvt != 0) {
851 return -1;
852 }
853
854 return _wsopen_nolock(punlock_flag, pfh, wide_path.data(), oflag, shflag, pmode, secure);
855}
errno_t __acrt_mbs_to_wcs_cp(char const *const null_terminated_input_string, __crt_win32_buffer< wchar_t, ResizePolicy > &win32_buffer, unsigned int const code_page)
unsigned int __acrt_get_utf8_acp_compatibility_codepage()
static char * cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag)
Definition: fcvtbuf.c:45
errno_t __cdecl _wsopen_nolock(int *const punlock_flag, int *const pfh, wchar_t const *const path, int const oflag, int const shflag, int const pmode, int const secure)
Definition: open.cpp:655

◆ _sopen_s()

errno_t __cdecl _sopen_s ( int *const  pfh,
char const *const  path,
int const  oflag,
int const  shflag,
int const  pmode 
)

Definition at line 887 of file open.cpp.

894{
895 // The last argument is 1 so that pmode is validated in open_s:
896 return _sopen_dispatch(path, oflag, shflag, pmode, pfh, TRUE);
897}
#define TRUE
Definition: types.h:120

◆ _wopen()

int _wopen ( wchar_t const *const  path,
int const  oflag,
  ... 
)

Definition at line 134 of file open.cpp.

135{
137 va_start(arglist, oflag);
138 int const pmode = va_arg(arglist, int);
140
141 return common_open(path, oflag, pmode);
142}

Referenced by compat_open(), and gz_open().

◆ _wsopen()

int __cdecl _wsopen ( wchar_t const *const  path,
int const  oflag,
int const  shflag,
  ... 
)

Definition at line 872 of file open.cpp.

873{
874 va_list ap;
875 va_start(ap, shflag);
876 int const pmode = va_arg(ap, int);
877 va_end(ap);
878
879 // The last argument is 0 so thta the pmode is not validated in open_s:
880 int fh = -1;
881 errno_t const result = _wsopen_dispatch(path, oflag, shflag, pmode, &fh, FALSE);
882 return result ? -1 : fh;
883}
errno_t __cdecl _wsopen_dispatch(wchar_t const *const path, int const oflag, int const shflag, int const pmode, int *const pfh, int const secure)
Definition: open.cpp:208

◆ _wsopen_dispatch()

errno_t __cdecl _wsopen_dispatch ( wchar_t const *const  path,
int const  oflag,
int const  shflag,
int const  pmode,
int *const  pfh,
int const  secure 
)

Definition at line 208 of file open.cpp.

216{
217 return common_sopen_dispatch(path, oflag, shflag, pmode, pfh, secure);
218}

Referenced by _wsopen(), and _wsopen_s().

◆ _wsopen_nolock()

errno_t __cdecl _wsopen_nolock ( int *const  punlock_flag,
int *const  pfh,
wchar_t const *const  path,
int const  oflag,
int const  shflag,
int const  pmode,
int const  secure 
)

Definition at line 655 of file open.cpp.

664{
666
667 // First, do the initial parse of the options. The only thing that can fail
668 // here is the parsing of the share options, in which case -1 is returned
669 // and errno is set.
670 file_options options = decode_options(oflag, shflag, pmode);
671 if (options.share == static_cast<DWORD>(-1))
672 {
673 _doserrno = 0;
674 *pfh = -1;
675 return errno;
676 }
677
678 // Allocate the CRT file handle. Note that if a handle is allocated, it is
679 // locked when it is returned by the allocation function. It is our caller's
680 // responsibility to unlock the file handle (we do not unlock it before
681 // returning).
682 *pfh = _alloc_osfhnd();
683 if (*pfh == -1)
684 {
685 _doserrno = 0;
686 *pfh = -1;
687 errno = EMFILE;
688 return errno;
689 }
690
691 // Beyond this point, do not change *pfh, even if an error occurs. Our
692 // caller requires the handle in order to release its lock.
693 *punlock_flag = 1;
694
695
696
697 SECURITY_ATTRIBUTES security_attributes;
698 security_attributes.nLength = sizeof(security_attributes);
699 security_attributes.lpSecurityDescriptor = nullptr;
700 security_attributes.bInheritHandle = (oflag & _O_NOINHERIT) == 0;
701
702
703 // Try to open or create the file:
704 HANDLE os_handle = create_file(path, &security_attributes, options);
705 if (os_handle == INVALID_HANDLE_VALUE)
706 {
707 if ((options.access & GENERIC_READ_WRITE) == GENERIC_READ_WRITE && (oflag & _O_WRONLY))
708 {
709 // The call may have failed because we may be trying to open
710 // something for reading that does not allow reading (e.g. a pipe or
711 // a device). So, we try again with just GENERIC_WRITE. If this
712 // succeeds, we will have to assume the default encoding because we
713 // will have no way to read the BOM.
714 options.access &= ~GENERIC_READ;
715
716 os_handle = create_file(path, &security_attributes, options);
717 }
718 }
719
720 if (os_handle == INVALID_HANDLE_VALUE)
721 {
722 // We failed to open the file. We need to free the CRT file handle, but
723 // we do not release the lock--our caller releases the lock.
724 _osfile(*pfh) &= ~FOPEN;
726 return errno;
727 }
728
729 // Find out what type of file this is (e.g., file, device, pipe, etc.)
730 DWORD const file_type = GetFileType(os_handle);
731
733 {
734 DWORD const last_error = GetLastError();
736
737 _osfile(*pfh) &= ~FOPEN;
738 CloseHandle(os_handle);
739
740 // If GetFileType returns FILE_TYPE_UNKNOWN but doesn't fail, the file
741 // type really is unknown. This function is not designed to handle
742 // unknown types of files, so we must return an error.
744 errno = EACCES;
745
746 return errno;
747 }
748
750 {
751 options.crt_flags |= FDEV;
752 }
753 else if (file_type == FILE_TYPE_PIPE)
754 {
755 options.crt_flags |= FPIPE;
756 }
757
758 // The file is open and valid. Set the OS handle:
759 __acrt_lowio_set_os_handle(*pfh, reinterpret_cast<intptr_t>(os_handle));
760
761
762 // Mark the handle as open, and store the flags we gathered so far:
763 options.crt_flags |= FOPEN;
764 _osfile(*pfh) = options.crt_flags;
765
766
767 // The text mode is set to ANSI by default. If we find a BOM, then we will
768 // reset this to the appropriate type (this check happens below).
770
771
772 // If the text mode file is opened for writing and allows reading, remove
773 // any trailing Ctrl+Z character, if present, to ensure appending works:
774 if (oflag & _O_RDWR)
775 {
777 if (result != 0)
778 {
779 _close_nolock(*pfh);
780 return result;
781 }
782 }
783
784 // Configure the text mode:
786 errno_t const text_mode_result = configure_text_mode(*pfh, options, oflag, text_mode);
787 if (text_mode_result != 0)
788 {
789 _close_nolock(*pfh);
790 return text_mode_result;
791 }
792
793 _textmode(*pfh) = text_mode;
794 _tm_unicode(*pfh) = (oflag & _O_WTEXT) != 0;
795
796
797 // Set FAPPEND flag if appropriate. Don't do this for devices or pipes:
798 if ((options.crt_flags & (FDEV | FPIPE)) == 0 && (oflag & _O_APPEND))
799 _osfile(*pfh) |= FAPPEND;
800
801
802 // Finally, if we were asked only to open the file with write access but we
803 // opened it with read and write access in order to read the BOM, close the
804 // file and re-open it with only write access:
805 if ((options.access & GENERIC_READ_WRITE) == GENERIC_READ_WRITE && (oflag & _O_WRONLY))
806 {
807 CloseHandle(os_handle);
808 options.access &= ~GENERIC_READ;
809 os_handle = create_file(path, &security_attributes, options);
810
811 if (os_handle == INVALID_HANDLE_VALUE)
812 {
813 // Note that we can't use the normal close function here because the
814 // file isn't really open anymore. We need only release the file
815 // handle by unsetting the FOPEN flag:
817 _osfile(*pfh) &= ~FOPEN;
818 _free_osfhnd(*pfh);
819 return errno;
820 }
821 else
822 {
823 // We were able to open the file successfully, set the file
824 // handle in the _ioinfo structure, then we are done. All
825 // the options.crt_flags should have been set properly already.
826 _osfhnd(*pfh) = reinterpret_cast<intptr_t>(os_handle);
827 }
828 }
829
830 return 0; // Success!
831}
#define EACCES
Definition: acclib.h:85
void __cdecl __acrt_errno_map_os_error(unsigned long)
Definition: errno.cpp:91
#define _osfhnd(i)
int __cdecl _alloc_osfhnd(void)
Definition: osfinfo.cpp:116
__crt_lowio_text_mode
int __cdecl __acrt_lowio_set_os_handle(int, intptr_t)
Definition: osfinfo.cpp:195
_Check_return_opt_ int __cdecl _close_nolock(_In_ int _FileHandle)
int __cdecl _free_osfhnd(int)
Definition: osfinfo.cpp:227
#define ERROR_SUCCESS
Definition: deptool.c:10
#define _O_RDWR
Definition: cabinet.h:39
#define _O_NOINHERIT
Definition: cabinet.h:45
#define _O_APPEND
Definition: cabinet.h:41
#define _O_WRONLY
Definition: cabinet.h:38
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
DWORD WINAPI GetFileType(HANDLE hFile)
Definition: fileinfo.c:269
#define EMFILE
Definition: errno.h:30
unsigned long DWORD
Definition: ntddk_ex.h:95
#define FOPEN
#define _O_WTEXT
Definition: fcntl.h:20
#define _doserrno
Definition: stdlib.h:131
#define create_file(name, size)
Definition: asmcache.c:813
DWORD const GENERIC_READ_WRITE
Definition: open.cpp:56
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
static errno_t truncate_ctrl_z_if_present(int const fh)
Definition: open.cpp:398
static errno_t configure_text_mode(int const fh, file_options const options, int oflag, __crt_lowio_text_mode &text_mode)
Definition: open.cpp:441
static file_options decode_options(int const oflag, int const shflag, int const pmode)
Definition: open.cpp:337
#define errno
Definition: errno.h:18
#define _osfile(i)
Definition: internal.h:72
#define _tm_unicode(i)
Definition: internal.h:75
#define _textmode(i)
Definition: internal.h:74
FD_TYPE file_type(FDSC **curr, char *fixed)
Definition: file.c:221
LPVOID lpSecurityDescriptor
Definition: compat.h:193
int intptr_t
Definition: vcruntime.h:134
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FILE_TYPE_UNKNOWN
Definition: winbase.h:284
#define FILE_TYPE_CHAR
Definition: winbase.h:286
#define FILE_TYPE_PIPE
Definition: winbase.h:287

Referenced by _sopen_nolock().

◆ _wsopen_s()

errno_t __cdecl _wsopen_s ( int *const  pfh,
wchar_t const *const  path,
int const  oflag,
int const  shflag,
int const  pmode 
)

Definition at line 899 of file open.cpp.

906{
907 // The last argument is 1 so that pmode is validated in open_s:
908 return _wsopen_dispatch(path, oflag, shflag, pmode, pfh, TRUE);
909}

◆ common_open()

template<typename Character >
static int __cdecl common_open ( _In_z_ Character const *const  path,
int const  oflag,
int const  pmode 
)
throw (
)
static

Definition at line 84 of file open.cpp.

89{
90 typedef __crt_char_traits<Character> traits;
91
92 _VALIDATE_RETURN(path != nullptr, EINVAL, -1);
93
94 int fh = -1;
95 int unlock_flag = 0;
97 __try
98 {
99 error_code = traits::tsopen_nolock(&unlock_flag, &fh, path, oflag, _SH_DENYNO, pmode, 0);
100 }
102 {
103 if (unlock_flag)
104 {
105 if (error_code)
106 {
107 _osfile(fh) &= ~FOPEN;
108 }
109
111 }
112 }
114
115 if (error_code != 0)
116 {
118 return -1;
119 }
120
121 return fh;
122}
#define EINVAL
Definition: acclib.h:90
void __cdecl __acrt_lowio_unlock_fh(_In_ int _FileHandle)
#define _VALIDATE_RETURN(expr, errorcode, retexpr)
#define _SH_DENYNO
Definition: share.h:17
#define __try
Definition: pseh2_64.h:188
#define __endtry
Definition: pseh2_64.h:191
#define __finally
Definition: pseh2_64.h:190
static int error_code[8]
Definition: odbccp32.c:61

Referenced by _open(), and _wopen().

◆ common_sopen_dispatch()

template<typename Character >
static errno_t __cdecl common_sopen_dispatch ( _In_z_ Character const *const  path,
int const  oflag,
int const  shflag,
int const  pmode,
int *const  pfh,
int const  secure 
)
throw (
)
static

Definition at line 147 of file open.cpp.

155{
156 typedef __crt_char_traits<Character> traits;
157
158 _VALIDATE_RETURN_ERRCODE(pfh != nullptr, EINVAL);
159 *pfh = -1;
160
162
163 if(secure)
164 {
165 _VALIDATE_RETURN_ERRCODE((pmode & (~(_S_IREAD | _S_IWRITE))) == 0, EINVAL);
166 }
167
168
169 int unlock_flag = 0;
171 __try
172 {
173 error_code = traits::tsopen_nolock(&unlock_flag, pfh, path, oflag, shflag, pmode, secure);
174 }
176 {
177 if (unlock_flag)
178 {
179 if (error_code)
180 {
181 _osfile(*pfh) &= ~FOPEN;
182 }
184 }
185 }
187
188 if (error_code != 0)
189 {
190 *pfh = -1;
191 }
192
193 return error_code;
194}
#define _S_IWRITE
Definition: cabinet.h:33
#define _S_IREAD
Definition: cabinet.h:34
#define _VALIDATE_RETURN_ERRCODE(expr, errorcode)

Referenced by _sopen_dispatch(), and _wsopen_dispatch().

◆ configure_text_mode()

static errno_t configure_text_mode ( int const  fh,
file_options const  options,
int  oflag,
__crt_lowio_text_mode text_mode 
)
throw (
)
static

Definition at line 441 of file open.cpp.

447{
448 // The text mode is ANSI by default:
449 text_mode = __crt_lowio_text_mode::ansi;
450
451 // If the file is open in binary mode, it gets the default text mode:
452 if ((_osfile(fh) & FTEXT) == 0)
453 return 0;
454
455 // Set the default text mode per the oflag. The BOM may change the default,
456 // if one is present. If oflag does not specify a text mode, use the _fmode
457 // default:
458 DWORD const text_mode_mask = (_O_TEXT | _O_WTEXT | _O_U16TEXT | _O_U8TEXT);
459 if ((oflag & text_mode_mask) == 0)
460 {
461 int fmode = 0;
462 _ERRCHECK(_get_fmode(&fmode));
463
464 if ((fmode & text_mode_mask) == 0)
465 oflag |= _O_TEXT; // Default to ANSI.
466 else
467 oflag |= fmode & text_mode_mask;
468 }
469
470 // Now oflags should be set to one of the text modes:
471 _ASSERTE((oflag & text_mode_mask) != 0);
472
473 switch (oflag & text_mode_mask)
474 {
475 case _O_TEXT:
476 text_mode = __crt_lowio_text_mode::ansi;
477 break;
478
479 case _O_WTEXT:
480 case _O_WTEXT | _O_TEXT:
481 if ((oflag & (_O_WRONLY | _O_CREAT | _O_TRUNC)) == (_O_WRONLY | _O_CREAT | _O_TRUNC))
483 break;
484
485 case _O_U16TEXT:
486 case _O_U16TEXT | _O_TEXT:
488 break;
489
490 case _O_U8TEXT:
491 case _O_U8TEXT | _O_TEXT:
492 text_mode = __crt_lowio_text_mode::utf8;
493 break;
494 }
495
496
497 // If the file hasn't been opened with the UNICODE flags then we have
498 // nothing to do: the text mode is the default mode that we just set:
499 if ((oflag & (_O_WTEXT | _O_U16TEXT | _O_U8TEXT)) == 0)
500 return 0;
501
502 // If this file refers to a device, we cannot check the BOM, so we have
503 // nothing to do: the text mode is the default mode that we just set:
504 if ((options.crt_flags & FDEV) != 0)
505 return 0;
506
507
508 // Determine whether we need to check or write the BOM, by testing the
509 // access with which the file was opened and whether the file already
510 // existed or was just created:
511 int check_bom = 0;
512 int write_bom = 0;
513 switch (options.access & GENERIC_READ_WRITE)
514 {
515 case GENERIC_READ:
516 check_bom = 1;
517 break;
518
519 case GENERIC_WRITE:
521 switch (options.create)
522 {
523 // If this file was opened, we will read the BOM if the file was opened
524 // with read/write access. We will write the BOM if and only if the
525 // file is empty:
526 case OPEN_EXISTING:
527 case OPEN_ALWAYS:
528 {
529 if (_lseeki64_nolock(fh, 0, SEEK_END) != 0)
530 {
531 if (_lseeki64_nolock(fh, 0, SEEK_SET) == -1)
532 return errno;
533
534 // If we have read access, then we need to check the BOM. Note
535 // that we've taken a shortcut here: if the file is empty, then
536 // we do not set this flag because the file doesn't have a BOM
537 // to be read.
538 check_bom = (options.access & GENERIC_READ) != 0;
539 }
540 else
541 {
542 write_bom = 1;
543 break;
544 }
545 break;
546 }
547
548 // If this is a new or truncated file, then we always write the BOM:
549 case CREATE_NEW:
550 case CREATE_ALWAYS:
552 {
553 write_bom = 1;
554 break;
555 }
556 }
557 break;
558 }
559
560 if (check_bom)
561 {
562 int bom = 0;
563 int const count = _read_nolock(fh, &bom, UTF8_BOMLEN);
564
565 // Intrernal validation: This branch should never be taken if write_bom
566 // is true and count > 0:
567 if (count > 0 && write_bom == 1)
568 {
569 _ASSERTE(0 && "Internal Error");
570 write_bom = 0;
571 }
572
573 switch (count)
574 {
575 case -1:
576 return errno;
577
578 case UTF8_BOMLEN:
579 if (bom == UTF8_BOM)
580 {
581 text_mode = __crt_lowio_text_mode::utf8;
582 break;
583 }
584
585 case UTF16_BOMLEN:
586 if((bom & BOM_MASK) == UTF16BE_BOM)
587 {
588 _ASSERTE(0 && "Only UTF-16 little endian & UTF-8 is supported for reads");
589 errno = EINVAL;
590 return errno;
591 }
592
593 if((bom & BOM_MASK) == UTF16LE_BOM)
594 {
595 // We have read three bytes, so we should seek back one byte:
597 return errno;
598
600 break;
601 }
602
603 // Fall through to default case to lseek to beginning of file
604
605 default:
606 // The file has no BOM, so we seek back to the beginning:
607 if (_lseeki64_nolock(fh, 0, SEEK_SET) == -1)
608 return errno;
609
610 break;
611 }
612 }
613
614 if (write_bom)
615 {
616 // If we are creating a new file, we write a UTF-16LE or UTF8 BOM:
617 int bom_length = 0;
618 int bom = 0;
619 switch (text_mode)
620 {
622 {
623 bom = UTF16LE_BOM;
624 bom_length = UTF16_BOMLEN;
625 break;
626 }
628 {
629 bom = UTF8_BOM;
630 bom_length = UTF8_BOMLEN;
631 break;
632 }
633 }
634
635 for (int total_written = 0; bom_length > total_written; )
636 {
637 char const* const bom_begin = reinterpret_cast<char const*>(&bom);
638
639 // Note that the call to write may write less than bom_length
640 // characters but not really fail. We retry until the write fails
641 // or we have written all of the characters:
642 int const written = _write(fh, bom_begin + total_written, bom_length - total_written);
643 if (written == -1)
644 return errno;
645
646 total_written += written;
647 }
648 }
649
650 return 0; // Success!
651}
#define SEEK_END
Definition: cabinet.c:29
#define _ERRCHECK(e)
_Check_return_opt_ __int64 __cdecl _lseeki64_nolock(_In_ int _FileHandle, _In_ __int64 _Offset, _In_ int _Origin)
#define _ASSERTE(expr)
Definition: crtdbg.h:114
#define _O_TEXT
Definition: cabinet.h:50
#define _O_TRUNC
Definition: cabinet.h:47
#define _O_CREAT
Definition: cabinet.h:46
#define OPEN_EXISTING
Definition: compat.h:775
#define GENERIC_READ
Definition: compat.h:135
GLuint GLuint GLsizei count
Definition: gl.h:1545
static int check_bom(const unsigned char **source, size_t *len)
Definition: id3.c:1304
#define _O_U8TEXT
Definition: fcntl.h:22
#define _O_U16TEXT
Definition: fcntl.h:21
_CRTIMP errno_t __cdecl _get_fmode(_Out_ int *_PMode)
#define SEEK_SET
Definition: jmemansi.c:26
#define CREATE_ALWAYS
Definition: disk.h:72
#define TRUNCATE_EXISTING
Definition: disk.h:71
#define CREATE_NEW
Definition: disk.h:69
#define OPEN_ALWAYS
Definition: disk.h:70
#define GENERIC_WRITE
Definition: nt_native.h:90
#define UTF8_BOM
Definition: open.cpp:79
#define BOM_MASK
Definition: open.cpp:78
#define UTF8_BOMLEN
Definition: open.cpp:81
#define UTF16_BOMLEN
Definition: open.cpp:80
#define UTF16LE_BOM
Definition: open.cpp:76
#define UTF16BE_BOM
Definition: open.cpp:77
_CRTIMP int __cdecl _write(_In_ int _FileHandle, _In_reads_bytes_(_MaxCharCount) const void *_Buf, _In_ unsigned int _MaxCharCount)
int __cdecl _read_nolock(int const fh, void *const result_buffer, unsigned const result_buffer_size)
Definition: read.cpp:408
#define const
Definition: zconf.h:233

Referenced by _wsopen_nolock().

◆ create_file()

static HANDLE __cdecl create_file ( PCWSTR const  path,
SECURITY_ATTRIBUTES *const  security_attributes,
file_options const  options 
)
throw (
)
static

Definition at line 222 of file open.cpp.

227{
228 return CreateFileW(
229 path,
230 options.access,
231 options.share,
232 security_attributes,
233 options.create,
234 options.flags | options.attributes,
235 nullptr);
236}
#define CreateFileW
Definition: compat.h:741
uint32_t flags
Definition: btrfslib.c:116

◆ decode_access_flags()

static DWORD decode_access_flags ( int const  oflag)
throw (
)
static

Definition at line 240 of file open.cpp.

241{
242 switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR))
243 {
244 case _O_RDONLY:
245 return GENERIC_READ;
246
247 case _O_WRONLY:
248 // If the file is being opened in append mode, we give read access as
249 // well because in append (a, not a+) mode, we need to read the BOM to
250 // determine the encoding (ANSI, UTF-8, or UTF-16).
251 if ((oflag & _O_APPEND) && (oflag & (_O_WTEXT | _O_U16TEXT | _O_U8TEXT)) != 0)
253
254 return GENERIC_WRITE;
255
256 case _O_RDWR:
258 }
259
260 // This is unreachable, but the compiler can't tell.
261 _VALIDATE_RETURN(("Invalid open flag", 0), EINVAL, static_cast<DWORD>(-1));
262 return 0;
263}
#define _O_RDONLY
Definition: cabinet.h:37

Referenced by decode_options().

◆ decode_open_create_flags()

static DWORD decode_open_create_flags ( int const  oflag)
throw (
)
static

Definition at line 265 of file open.cpp.

266{
267 switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC))
268 {
269 case 0:
270 case _O_EXCL: // ignore EXCL w/o CREAT
271 return OPEN_EXISTING;
272
273 case _O_CREAT:
274 return OPEN_ALWAYS;
275
276 case _O_CREAT | _O_EXCL:
277 case _O_CREAT | _O_TRUNC | _O_EXCL:
278 return CREATE_NEW;
279
280 case _O_TRUNC:
281 case _O_TRUNC | _O_EXCL: // ignore EXCL w/o CREAT
282 return TRUNCATE_EXISTING;
283
284 case _O_CREAT | _O_TRUNC:
285 return CREATE_ALWAYS;
286 }
287
288 // This is unreachable, but the compiler can't tell.
289 _VALIDATE_RETURN(("Invalid open flag", 0), EINVAL, static_cast<DWORD>(-1));
290 return 0;
291}
#define _O_EXCL
Definition: cabinet.h:48

Referenced by decode_options().

◆ decode_options()

static file_options decode_options ( int const  oflag,
int const  shflag,
int const  pmode 
)
throw (
)
static

Definition at line 337 of file open.cpp.

338{
339 file_options result;
340 result.crt_flags = 0;
341 result.access = decode_access_flags(oflag);
342 result.create = decode_open_create_flags(oflag);
343 result.share = decode_sharing_flags(shflag, result.access);
344 result.attributes = FILE_ATTRIBUTE_NORMAL;
345 result.flags = 0;
346
347 if (oflag & _O_NOINHERIT)
348 {
349 result.crt_flags |= FNOINHERIT;
350 }
351
352 if (is_text_mode(oflag))
353 {
354 result.crt_flags |= FTEXT;
355 }
356
357 if (oflag & _O_CREAT)
358 {
359 if (((pmode & ~_umaskval) & _S_IWRITE) == 0)
360 result.attributes = FILE_ATTRIBUTE_READONLY;
361 }
362
363 if (oflag & _O_TEMPORARY)
364 {
366 result.access |= DELETE;
367 result.share |= FILE_SHARE_DELETE;
368 }
369
370 if (oflag & _O_SHORT_LIVED)
371 {
372 result.attributes |= FILE_ATTRIBUTE_TEMPORARY;
373 }
374
375 if (oflag & _O_OBTAIN_DIR)
376 {
378 }
379
380 if (oflag & _O_SEQUENTIAL)
381 {
383 }
384 else if (oflag & _O_RANDOM)
385 {
387 }
388
389 return result;
390}
int _umaskval
Definition: umask.cpp:15
#define _O_SEQUENTIAL
Definition: cabinet.h:43
#define _O_SHORT_LIVED
Definition: cabinet.h:49
#define _O_TEMPORARY
Definition: cabinet.h:44
#define _O_RANDOM
Definition: cabinet.h:42
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define _O_OBTAIN_DIR
Definition: fcntl.h:42
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
#define FILE_FLAG_RANDOM_ACCESS
Definition: disk.h:44
#define FILE_FLAG_DELETE_ON_CLOSE
Definition: disk.h:42
#define FILE_FLAG_SEQUENTIAL_SCAN
Definition: disk.h:43
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define DELETE
Definition: nt_native.h:57
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
static DWORD decode_sharing_flags(int const shflag, int const access)
Definition: open.cpp:293
static DWORD decode_access_flags(int const oflag)
Definition: open.cpp:240
static bool is_text_mode(int const oflag)
Definition: open.cpp:320
static DWORD decode_open_create_flags(int const oflag)
Definition: open.cpp:265

Referenced by _wsopen_nolock().

◆ decode_sharing_flags()

static DWORD decode_sharing_flags ( int const  shflag,
int const  access 
)
throw (
)
static

Definition at line 293 of file open.cpp.

294{
295 switch (shflag)
296 {
297 case _SH_DENYRW:
298 return 0;
299
300 case _SH_DENYWR:
301 return FILE_SHARE_READ;
302
303 case _SH_DENYRD:
304 return FILE_SHARE_WRITE;
305
306 case _SH_DENYNO:
308
309 case _SH_SECURE:
310 if (access == GENERIC_READ)
311 return FILE_SHARE_READ;
312 else
313 return 0;
314 }
315
316 _VALIDATE_RETURN(("Invalid sharing flag", 0), EINVAL, static_cast<DWORD>(-1));
317 return 0;
318}
#define _SH_DENYRW
Definition: share.h:14
#define _SH_DENYRD
Definition: share.h:16
#define _SH_SECURE
Definition: share.h:18
#define _SH_DENYWR
Definition: share.h:15
#define FILE_SHARE_READ
Definition: compat.h:136
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
#define FILE_SHARE_WRITE
Definition: nt_native.h:681

Referenced by decode_options().

◆ is_text_mode()

static bool is_text_mode ( int const  oflag)
throw (
)
static

Definition at line 320 of file open.cpp.

321{
322 if (oflag & _O_BINARY)
323 return false;
324
325 if (oflag & (_O_TEXT | _O_WTEXT | _O_U16TEXT | _O_U8TEXT))
326 return true;
327
328 // Finally, check the global default mode:
329 int fmode;
330 _ERRCHECK(_get_fmode(&fmode));
331 if (fmode != _O_BINARY)
332 return true;
333
334 return false;
335}
#define _O_BINARY
Definition: cabinet.h:51

Referenced by decode_options().

◆ truncate_ctrl_z_if_present()

static errno_t truncate_ctrl_z_if_present ( int const  fh)
throw (
)
static

Definition at line 398 of file open.cpp.

399{
400 // No truncation is possible for devices and pipes:
401 if (_osfile(fh) & (FDEV | FPIPE))
402 return 0;
403
404 // No truncation is necessary for binary files:
405 if ((_osfile(fh) & FTEXT) == 0)
406 return 0;
407
408 // Find the end of the file:
409 __int64 const last_char_position = _lseeki64_nolock(fh, -1, SEEK_END);
410
411 // If the seek failed, either the file is empty or an error occurred.
412 // (It's not an error if the file is empty.)
413 if (last_char_position == -1)
414 {
416 return 0;
417
418 return errno;
419 }
420
421 // Read the last character. If the read succeeds and the character
422 // is a Ctrl+Z, remove the character from the file by shortening:
423 wchar_t c = 0;
424 if (_read_nolock(fh, &c, 1) == 0 && c == 26)
425 {
426 if (_chsize_nolock(fh, last_char_position) == -1)
427 return errno;
428 }
429
430 // Now, rewind the file pointer back to the beginning:
431 if (_lseeki64_nolock(fh, 0, SEEK_SET) == -1)
432 return errno;
433
434 return 0;
435}
#define __int64
Definition: basetyps.h:16
_Check_return_ int __cdecl _chsize_nolock(_In_ int _FileHandle, _In_ __int64 _Size)
const GLubyte * c
Definition: glext.h:8905
#define ERROR_NEGATIVE_SEEK
Definition: winerror.h:203

Referenced by _wsopen_nolock().