@@ -291,7 +291,7 @@ static int file_statw(file_t* file);
291
291
* @param dir_path (nullable) directory path to prepend to printable path
292
292
* @param print_path printable path, which encoding shall be detected
293
293
* @param init_flags bit flags, helping to detect the encoding
294
- * @return encoding on success, -1 on fail with error code stored in errno
294
+ * @return encoding on success, -1 on failure with error code stored in errno
295
295
*/
296
296
static int detect_path_encoding (file_t * file , wchar_t * dir_path , const char * print_path , unsigned init_flags )
297
297
{
@@ -354,7 +354,7 @@ static int detect_path_encoding(file_t* file, wchar_t* dir_path, const char* pri
354
354
* @param prepend_dir the directory to prepend to the print_path, to construct the file path, can be NULL
355
355
* @param print_path the printable representation of the file path
356
356
* @param init_flags initialization flags
357
- * @return 0 on success, -1 on fail with error code stored in errno
357
+ * @return 0 on success, -1 on failure with error code stored in errno
358
358
*/
359
359
int file_init_by_print_path (file_t * file , file_t * prepend_dir , const char * print_path , unsigned init_flags )
360
360
{
@@ -617,7 +617,7 @@ void file_swap(file_t* first, file_t* second)
617
617
* @param str the string to insert into/append to the source file path
618
618
* @param operation the operation determinating how to modify the file path, can be one of the values
619
619
* FModifyAppendSuffix, FModifyInsertBeforeExtension, FModifyRemoveExtension, FModifyGetParentDir
620
- * @return allocated and modified file path on success, NULL on fail
620
+ * @return allocated and modified file path on success, NULL on failure
621
621
*/
622
622
static char * get_modified_path (const char * path , const char * str , int operation )
623
623
{
@@ -654,7 +654,7 @@ static char* get_modified_path(const char* path, const char* str, int operation)
654
654
* @param str the string to insert into/append to the source file path
655
655
* @param operation the operation determinating how to modify the file path, can be one of the values
656
656
* FModifyAppendSuffix, FModifyInsertBeforeExtension, FModifyRemoveExtension, FModifyGetParentDir
657
- * @return allocated and modified file path on success, NULL on fail
657
+ * @return allocated and modified file path on success, NULL on failure
658
658
*/
659
659
static tpath_t get_modified_tpath (ctpath_t path , const char * str , int operation )
660
660
{
@@ -694,7 +694,7 @@ static tpath_t get_modified_tpath(ctpath_t path, const char* str, int operation)
694
694
* @param str the string to insert into/append to the source file path
695
695
* @param operation the operation to do on src file, can be one of the values
696
696
* FModifyAppendSuffix, FModifyInsertBeforeExtension, FModifyRemoveExtension, FModifyGetParentDir
697
- * @return 0 on success, -1 on fail with error code stored in errno
697
+ * @return 0 on success, -1 on failure with error code stored in errno
698
698
*/
699
699
int file_modify_path (file_t * dst , file_t * src , const char * str , int operation )
700
700
{
@@ -729,7 +729,7 @@ int file_modify_path(file_t* dst, file_t* src, const char* str, int operation)
729
729
* Retrieve file information (type, size, mtime) into file_t fields.
730
730
*
731
731
* @param file the file information
732
- * @return 0 on success, -1 on fail with error code stored in errno
732
+ * @return 0 on success, -1 on failure with error code stored in errno
733
733
*/
734
734
static int file_statw (file_t * file )
735
735
{
@@ -777,7 +777,7 @@ static int file_statw(file_t* file)
777
777
*
778
778
* @param file the file information
779
779
* @param fstat_flags bitmask consisting of FileStatModes bits
780
- * @return 0 on success, -1 on fail with error code stored in errno
780
+ * @return 0 on success, -1 on failure with error code stored in errno
781
781
*/
782
782
int file_stat (file_t * file , int fstat_flags )
783
783
{
@@ -822,11 +822,65 @@ int file_stat(file_t* file, int fstat_flags)
822
822
}
823
823
824
824
/**
825
- * Open the file and return its decriptor .
825
+ * Open the file and return POSIX file descriptor .
826
826
*
827
- * @param file the file information, including the path
828
- * @param fopen_flags bitmask consisting of FileFOpenModes bits
829
- * @return file descriptor on success, NULL on fail with error code stored in errno
827
+ * On Windows, the file is always opened in binary mode (`_O_BINARY`)
828
+ * and with `_SH_DENYNO` (shared read/write access).
829
+ * In read-only mode (`FOpenRead`), the file is opened with a hint for sequential access:
830
+ * - Windows: Uses `_O_SEQUENTIAL`.
831
+ * - POSIX: Uses `posix_fadvise(POSIX_FADV_SEQUENTIAL)` if available.
832
+ *
833
+ * @param file file information, including the path (must not be NULL)
834
+ * @param open_flags bitmask of `FOpenRead`, `FOpenWrite`
835
+ * @return POSIX file descriptor on success, -1 on failure with error code stored in errno
836
+ */
837
+ int file_open (file_t * file , int open_flags )
838
+ {
839
+ const int possible_oflags [4 ] = {
840
+ #if defined(_WIN32 )
841
+ 0 , _O_RDONLY | _O_BINARY | _O_SEQUENTIAL ,
842
+ _O_WRONLY | _O_BINARY , _O_RDWR | _O_BINARY
843
+ #else
844
+ # if !defined(O_BINARY )
845
+ # define O_BINARY 0
846
+ # endif
847
+ 0 , O_RDONLY | O_BINARY , O_WRONLY | O_BINARY , O_RDWR | O_BINARY
848
+ #endif
849
+ };
850
+ const int oflags = possible_oflags [open_flags & FOpenRW ];
851
+ int fd ;
852
+ assert ((open_flags & FOpenRW ) != 0 );
853
+ if (!file -> real_path ) {
854
+ errno = EINVAL ;
855
+ return -1 ;
856
+ }
857
+ #ifdef _WIN32
858
+ {
859
+ fd = _wsopen (file -> real_path , oflags , _SH_DENYNO , 0 );
860
+ if (fd < 0 && errno == EINVAL )
861
+ errno = ENOENT ;
862
+ return fd ;
863
+ }
864
+ #else
865
+ fd = open (file -> real_path , oflags , 0 );
866
+ # if _POSIX_C_SOURCE >= 200112L && defined(POSIX_FADV_SEQUENTIAL )
867
+ if (fd >= 0 )
868
+ posix_fadvise (fd , 0 , 0 , POSIX_FADV_SEQUENTIAL );
869
+ # endif /* _POSIX_C_SOURCE >= 200112L && defined(POSIX_FADV_SEQUENTIAL) */
870
+ return fd ;
871
+ #endif
872
+ }
873
+
874
+ /**
875
+ * Open the file and return a standard C file stream pointer.
876
+ *
877
+ * On Windows, the file is opened with shared access (`_SH_DENYNO`)
878
+ * In read-only mode (`FOpenRead`), a hint for sequential access is applied.
879
+ *
880
+ * @param file the file information, including the path (must not be NULL)
881
+ * @param fopen_flags bitmask of `FOpenRead`, `FOpenWrite`, and optionally `FOpenBin`.
882
+ * Must include at least one of `FOpenRead` or `FOpenWrite`.
883
+ * @return valid `FILE*` stream on success, NULL on failure with error code stored in errno
830
884
*/
831
885
FILE * file_fopen (file_t * file , int fopen_flags )
832
886
{
@@ -868,7 +922,7 @@ FILE* file_fopen(file_t* file, int fopen_flags)
868
922
*
869
923
* @param from the source file
870
924
* @param to the destination path
871
- * @return 0 on success, -1 on fail with error code stored in errno
925
+ * @return 0 on success, -1 on failure with error code stored in errno
872
926
*/
873
927
int file_rename (const file_t * from , const file_t * to )
874
928
{
@@ -889,7 +943,7 @@ int file_rename(const file_t* from, const file_t* to)
889
943
* Rename a given file to *.bak, if it exists.
890
944
*
891
945
* @param file the file to move
892
- * @return 0 on success, -1 on fail with error code stored in errno
946
+ * @return 0 on success, -1 on failure with error code stored in errno
893
947
*/
894
948
int file_move_to_bak (file_t * file )
895
949
{
@@ -962,7 +1016,7 @@ int file_is_readable(file_t* file)
962
1016
*
963
1017
* @param list the file_list_t structure to initialize
964
1018
* @param file the file to open
965
- * @return 0 on success, -1 on fail with error code stored in errno
1019
+ * @return 0 on success, -1 on failure with error code stored in errno
966
1020
*/
967
1021
int file_list_open (file_list_t * list , file_t * file )
968
1022
{
@@ -1040,7 +1094,7 @@ struct WIN_DIR_t
1040
1094
* Open directory iterator for reading the directory content.
1041
1095
*
1042
1096
* @param dir_path directory path
1043
- * @return pointer to directory stream, NULL on fail with error code stored in errno
1097
+ * @return pointer to directory stream, NULL on failure with error code stored in errno
1044
1098
*/
1045
1099
WIN_DIR * win_opendir (const char * dir_path )
1046
1100
{
0 commit comments