diff --git a/.github/workflows/build_nightly.yml b/.github/workflows/build_nightly.yml index cd48c7435..9ee69c078 100644 --- a/.github/workflows/build_nightly.yml +++ b/.github/workflows/build_nightly.yml @@ -872,22 +872,10 @@ jobs: run: | cd tests\testsuite.src - rem Skip test as it sometimes works and sometimes not... - rem sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' used_binaries.at - - rem The following 13 fail (identical to MSYS2) + rem The following 4 fail (identical to MSYS2) sed -i '/AT_SETUP(\[Test dump feature (4)\])/a AT_SKIP_IF(\[true\])' run_misc.at - sed -i '/AT_SETUP(\[OUTPUT on INDEXED file to missing directory\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[INDEXED undeclared keys\])/a AT_SKIP_IF(\[true\])' run_file.at sed -i '/AT_SETUP(\[PIPE I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at sed -i '/AT_SETUP(\[STDOUT STDERR I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[LINE SEQUENTIAL one Record\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[INDEXED COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[SEQUENTIAL\/RELATIVE COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[LINE SEQUENTIAL COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[OPEN OUTPUT COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[MF io status (indexed)\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[Test MF Status (sequential)\])/a AT_SKIP_IF(\[true\])' run_file.at sed -i '/AT_SETUP(\[LINE SEQUENTIAL\])/a AT_SKIP_IF(\[true\])' run_file.at - name: Run testsuite diff --git a/.github/workflows/ibm.yml b/.github/workflows/ibm.yml index 1c26ef818..d606258c6 100644 --- a/.github/workflows/ibm.yml +++ b/.github/workflows/ibm.yml @@ -10,7 +10,7 @@ on: jobs: build: runs-on: ${{ matrix.os }} - timeout-minutes: 15 # usually around 6-10 minutes + timeout-minutes: 20 # usually around 6-10 minutes strategy: fail-fast: false matrix: diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index 8e8f54cdf..dbca566cf 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -165,34 +165,13 @@ jobs: # Depends on target-specific memory layout sed -i '/AT_SETUP(\[runtime check: write to internal storage (1)\])/a AT_SKIP_IF(\[true\])' run_misc.at - # The following 22 fail in Release Mode - sed -i '/AT_SETUP(\[Large BINARY, COMP-X\])/a AT_SKIP_IF(\[true\])' run_misc.at + # The following 4 fail in Release Mode sed -i '/AT_SETUP(\[Test dump feature (4)\])/a AT_SKIP_IF(\[true\])' run_misc.at - sed -i '/AT_SETUP(\[C-API (3)\])/a AT_SKIP_IF(\[true\])' run_misc.at - sed -i '/AT_SETUP(\[C API Test JUST\])/a AT_SKIP_IF(\[true\])' run_misc.at - sed -i '/AT_SETUP(\[Test COBOL-C interface\])/a AT_SKIP_IF(\[true\])' run_misc.at - sed -i '/AT_SETUP(\[Test COBOL-C interface (2)\])/a AT_SKIP_IF(\[true\])' run_misc.at - sed -i '/AT_SETUP(\[OUTPUT on INDEXED file to missing directory\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[INDEXED file SUPPRESS WHEN ALL + KEYCHECK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[INDEXED undeclared keys\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[EXTFH: using ISAM callback\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[trace feature\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[trace feature with indexed EXTFH\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[trace feature with subroutine\])/a AT_SKIP_IF(\[true\])' run_file.at sed -i '/AT_SETUP(\[PIPE I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at sed -i '/AT_SETUP(\[STDOUT STDERR I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[INDEXED COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[SEQUENTIAL\/RELATIVE COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[LINE SEQUENTIAL COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[OPEN OUTPUT COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[MF io status (indexed)\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[Test MF Status (sequential)\])/a AT_SKIP_IF(\[true\])' run_file.at sed -i '/AT_SETUP(\[LINE SEQUENTIAL\])/a AT_SKIP_IF(\[true\])' run_file.at - # The following 4 fail in Debug Mode - sed -i '/AT_SETUP(\[C-API (field based)\])/a AT_SKIP_IF(\[true\])' run_misc.at - sed -i '/AT_SETUP(\[SEQUENTIAL basic I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[LINE SEQUENTIAL one Record\])/a AT_SKIP_IF(\[true\])' run_file.at + # The following 1 fail in Debug Mode sed -i '/AT_SETUP(\[System routine CBL_GC_HOSTED\])/a AT_SKIP_IF(\[true\])' run_extensions.at - name: Build testsuite diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml index 11a403c42..d48b29b66 100644 --- a/.github/workflows/windows-msys2.yml +++ b/.github/workflows/windows-msys2.yml @@ -150,7 +150,7 @@ jobs: # command it provides, to workaround a diff bug under the MSYS2 CI ; # this no longer seems necessary today # PATH="$PATH:/c/Program Files/Git/usr/bin" - ../configure $CFGOPT CFLAGS=-std=c17 + ../configure $CFGOPT CFLAGS=-std=gnu17 - name: Upload config.log if: ${{ !cancelled() }} @@ -190,23 +190,10 @@ jobs: run: | cd tests/testsuite.src - # Skip test as it sometimes works and sometimes not... - # sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' used_binaries.at - - # The following 13 fail (identical to MSYS1) - # Note LINE SEQUENTIAL one Record works with the clang64 environment + # The following 4 fail (identical to MSYS1) sed -i '/AT_SETUP(\[Test dump feature (4)\])/a AT_SKIP_IF(\[true\])' run_misc.at - sed -i '/AT_SETUP(\[OUTPUT on INDEXED file to missing directory\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[INDEXED undeclared keys\])/a AT_SKIP_IF(\[true\])' run_file.at sed -i '/AT_SETUP(\[PIPE I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at sed -i '/AT_SETUP(\[STDOUT STDERR I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[LINE SEQUENTIAL one Record\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[INDEXED COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[SEQUENTIAL\/RELATIVE COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[LINE SEQUENTIAL COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[OPEN OUTPUT COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[MF io status (indexed)\])/a AT_SKIP_IF(\[true\])' run_file.at - sed -i '/AT_SETUP(\[Test MF Status (sequential)\])/a AT_SKIP_IF(\[true\])' run_file.at sed -i '/AT_SETUP(\[LINE SEQUENTIAL\])/a AT_SKIP_IF(\[true\])' run_file.at - name: Run testsuite diff --git a/TODO b/TODO index dbdf1a446..7d2d6b9ae 100644 --- a/TODO +++ b/TODO @@ -234,6 +234,8 @@ https://sourceforge.net/p/gnucobol/code/HEAD/tree/external-doc/guide/ - Check the TODO about cb_default_byte in codegen.c:output_initialize +- Check the TODO about having a single dialect option to change io stats (also for other dialects) in run_file.at:Test MF Status (sequential) + - Make status an enum instead of an int in fileio.c:cob_file_save_status as per TODO - Move the IO status codes from common.h to fileio.h as per TODO diff --git a/build_windows/vs2010/cobc.vcxproj b/build_windows/vs2010/cobc.vcxproj index 3cbbb6e4c..848f80a0a 100644 --- a/build_windows/vs2010/cobc.vcxproj +++ b/build_windows/vs2010/cobc.vcxproj @@ -30,23 +30,27 @@ true + false Application + true Application true + false Windows7.1SDK Application + true Windows7.1SDK diff --git a/build_windows/vs2010/cobcrun.vcxproj b/build_windows/vs2010/cobcrun.vcxproj index 8e3852a65..6c01f236d 100644 --- a/build_windows/vs2010/cobcrun.vcxproj +++ b/build_windows/vs2010/cobcrun.vcxproj @@ -30,23 +30,27 @@ true + false Application + true Application true + false Windows7.1SDK Application + true Windows7.1SDK @@ -211,4 +215,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2010/libcob.vcxproj b/build_windows/vs2010/libcob.vcxproj index bf659c744..4740935f2 100644 --- a/build_windows/vs2010/libcob.vcxproj +++ b/build_windows/vs2010/libcob.vcxproj @@ -28,17 +28,21 @@ DynamicLibrary true + false DynamicLibrary + true DynamicLibrary true + false Windows7.1SDK DynamicLibrary + true Windows7.1SDK diff --git a/build_windows/vs2010/libsupport.vcxproj b/build_windows/vs2010/libsupport.vcxproj index 88d1f7fd8..5cb2a53e1 100644 --- a/build_windows/vs2010/libsupport.vcxproj +++ b/build_windows/vs2010/libsupport.vcxproj @@ -30,23 +30,27 @@ true + false StaticLibrary + true StaticLibrary true + false Windows7.1SDK StaticLibrary + true Windows7.1SDK @@ -197,4 +201,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2012/cobc.vcxproj b/build_windows/vs2012/cobc.vcxproj index c81fa2163..a7024d4bf 100644 --- a/build_windows/vs2012/cobc.vcxproj +++ b/build_windows/vs2012/cobc.vcxproj @@ -27,6 +27,7 @@ Application + false $(DefaultPlatformToolset) @@ -34,12 +35,14 @@ Application + true $(DefaultPlatformToolset) Application + false $(DefaultPlatformToolset) @@ -47,6 +50,7 @@ Application + true $(DefaultPlatformToolset) diff --git a/build_windows/vs2012/cobcrun.vcxproj b/build_windows/vs2012/cobcrun.vcxproj index 159e54490..bad6154ea 100644 --- a/build_windows/vs2012/cobcrun.vcxproj +++ b/build_windows/vs2012/cobcrun.vcxproj @@ -27,6 +27,7 @@ Application + false $(DefaultPlatformToolset) @@ -34,12 +35,14 @@ Application + true $(DefaultPlatformToolset) Application + false $(DefaultPlatformToolset) @@ -47,6 +50,7 @@ Application + true $(DefaultPlatformToolset) @@ -215,4 +219,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2012/libcob.vcxproj b/build_windows/vs2012/libcob.vcxproj index 9acdcc07f..b7093b6a6 100644 --- a/build_windows/vs2012/libcob.vcxproj +++ b/build_windows/vs2012/libcob.vcxproj @@ -27,20 +27,24 @@ DynamicLibrary + false $(DefaultPlatformToolset) true DynamicLibrary + true $(DefaultPlatformToolset) DynamicLibrary + false $(DefaultPlatformToolset) true DynamicLibrary + true $(DefaultPlatformToolset) diff --git a/build_windows/vs2012/libsupport.vcxproj b/build_windows/vs2012/libsupport.vcxproj index e152acba0..3c2ec55bb 100644 --- a/build_windows/vs2012/libsupport.vcxproj +++ b/build_windows/vs2012/libsupport.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -199,4 +203,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2013/cobc.vcxproj b/build_windows/vs2013/cobc.vcxproj index d3dc279e7..92bdaf0e0 100644 --- a/build_windows/vs2013/cobc.vcxproj +++ b/build_windows/vs2013/cobc.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) diff --git a/build_windows/vs2013/cobcrun.vcxproj b/build_windows/vs2013/cobcrun.vcxproj index dc77a4253..2a73e0233 100644 --- a/build_windows/vs2013/cobcrun.vcxproj +++ b/build_windows/vs2013/cobcrun.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -218,4 +222,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2013/libcob.vcxproj b/build_windows/vs2013/libcob.vcxproj index 50557d1f9..b964d2c13 100644 --- a/build_windows/vs2013/libcob.vcxproj +++ b/build_windows/vs2013/libcob.vcxproj @@ -28,19 +28,23 @@ DynamicLibrary true + false $(DefaultPlatformToolset) DynamicLibrary + true $(DefaultPlatformToolset) DynamicLibrary true + false $(DefaultPlatformToolset) DynamicLibrary + true $(DefaultPlatformToolset) diff --git a/build_windows/vs2013/libsupport.vcxproj b/build_windows/vs2013/libsupport.vcxproj index 87a28db68..e8376cf5e 100644 --- a/build_windows/vs2013/libsupport.vcxproj +++ b/build_windows/vs2013/libsupport.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -203,4 +207,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2015/cobc.vcxproj b/build_windows/vs2015/cobc.vcxproj index 6925f9fb3..053a2709f 100644 --- a/build_windows/vs2015/cobc.vcxproj +++ b/build_windows/vs2015/cobc.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) diff --git a/build_windows/vs2015/cobcrun.vcxproj b/build_windows/vs2015/cobcrun.vcxproj index dde7b36a8..c4533c287 100644 --- a/build_windows/vs2015/cobcrun.vcxproj +++ b/build_windows/vs2015/cobcrun.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -216,4 +220,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2015/libsupport.vcxproj b/build_windows/vs2015/libsupport.vcxproj index f729813d1..78a8d4992 100644 --- a/build_windows/vs2015/libsupport.vcxproj +++ b/build_windows/vs2015/libsupport.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -201,4 +205,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2017/cobc.vcxproj b/build_windows/vs2017/cobc.vcxproj index af3131a60..4947999db 100644 --- a/build_windows/vs2017/cobc.vcxproj +++ b/build_windows/vs2017/cobc.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) diff --git a/build_windows/vs2017/cobcrun.vcxproj b/build_windows/vs2017/cobcrun.vcxproj index 9b7dad5e0..e64af341e 100644 --- a/build_windows/vs2017/cobcrun.vcxproj +++ b/build_windows/vs2017/cobcrun.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -218,4 +222,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2017/libsupport.vcxproj b/build_windows/vs2017/libsupport.vcxproj index c3f8188dd..0b7ee8994 100644 --- a/build_windows/vs2017/libsupport.vcxproj +++ b/build_windows/vs2017/libsupport.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -205,4 +209,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2019/cobc.vcxproj b/build_windows/vs2019/cobc.vcxproj index 6eb1ab255..e1248842b 100644 --- a/build_windows/vs2019/cobc.vcxproj +++ b/build_windows/vs2019/cobc.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) diff --git a/build_windows/vs2019/cobcrun.vcxproj b/build_windows/vs2019/cobcrun.vcxproj index 9b7dad5e0..e64af341e 100644 --- a/build_windows/vs2019/cobcrun.vcxproj +++ b/build_windows/vs2019/cobcrun.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) Application + true $(DefaultPlatformToolset) @@ -218,4 +222,4 @@ - \ No newline at end of file + diff --git a/build_windows/vs2019/libsupport.vcxproj b/build_windows/vs2019/libsupport.vcxproj index c47f9e74c..01830ca2a 100644 --- a/build_windows/vs2019/libsupport.vcxproj +++ b/build_windows/vs2019/libsupport.vcxproj @@ -30,12 +30,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -43,12 +45,14 @@ true + false $(DefaultPlatformToolset) StaticLibrary + true $(DefaultPlatformToolset) @@ -205,4 +209,4 @@ - \ No newline at end of file + diff --git a/libcob/ChangeLog b/libcob/ChangeLog index aed29a146..4f8d06c6b 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,18 @@ +2026-08-14 David Declerck + + * fileio.c (isdirvalid): implement Windows counterpart + * fileio.c (cob_open_qbl): fix flags and permission for Windows + * fileio.c (cob_file_sync, cob_file_unlock): call fdcobsync + only if file is open in mode other than COB_OPEN_INPUT + and fflush only is last operation was a write + * fileio.c (pathcmp) [_WIN32]: new function to compare paths + while ignoring slash differences + * fileio.c (cob_get_filename_print) [_WIN32]: use pathcmp + instead of strcmp to compare paths + * fbdb.c (ix_bdb_open): call ix_bdb_close to cleanup on + * cobcapi.c (cob_get_buff): protect call to cob_free + 2025-07-28 Simon Sobisch * common.h, fileio.c: new externalized typedef EXTFH_FUNC used in diff --git a/libcob/Makefile.am b/libcob/Makefile.am index b0fb053b9..0e6bb8e8b 100644 --- a/libcob/Makefile.am +++ b/libcob/Makefile.am @@ -50,7 +50,7 @@ INDEXED_LD_FLAGS = -version-info 1:0:0 if COB_MAKE_CISAM_LIB lib_ci = libcobci.la libcobci_la_SOURCES = libcobci.c fsqlxfd.c # includes fisam.c -libcobci_la_LIBADD = libcob.la $(CISAM_LIBS) +libcobci_la_LIBADD = libcob.la $(CISAM_LIBS) $(LIBCOB_LIBS) libcobci_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS) libcobci_la_CFLAGS = $(AM_CFLAGS) $(CISAM_CFLAGS) else @@ -60,7 +60,7 @@ endif if COB_MAKE_DISAM_LIB lib_di = libcobdi.la libcobdi_la_SOURCES = libcobdi.c fsqlxfd.c # includes fisam.c -libcobdi_la_LIBADD = libcob.la $(DISAM_LIBS) +libcobdi_la_LIBADD = libcob.la $(DISAM_LIBS) $(LIBCOB_LIBS) libcobdi_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS) libcobdi_la_CFLAGS = $(AM_CFLAGS) $(DISAM_CFLAGS) else @@ -70,7 +70,7 @@ endif if COB_MAKE_VBISAM_LIB lib_vb = libcobvb.la libcobvb_la_SOURCES = libcobvb.c fsqlxfd.c # includes fisam.c -libcobvb_la_LIBADD = libcob.la $(VBISAM_LIBS) +libcobvb_la_LIBADD = libcob.la $(VBISAM_LIBS) $(LIBCOB_LIBS) libcobvb_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS) libcobvb_la_CFLAGS = $(AM_CFLAGS) $(VBISAM_CFLAGS) else @@ -80,7 +80,7 @@ endif if COB_MAKE_VISAM_LIB lib_vc = libcobvc.la libcobvc_la_SOURCES = libcobvc.c fsqlxfd.c # includes fisam.c -libcobvc_la_LIBADD = libcob.la $(VISAM_LIBS) +libcobvc_la_LIBADD = libcob.la $(VISAM_LIBS) $(LIBCOB_LIBS) libcobvc_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS) libcobvc_la_CFLAGS = $(AM_CFLAGS) $(VISAM_CFLAGS) else @@ -89,7 +89,7 @@ endif if COB_MAKE_ODBC_LIB lib_od = libcobod.la -libcobod_la_LIBADD = libcob.la $(ODBC_LIBS) +libcobod_la_LIBADD = libcob.la $(ODBC_LIBS) $(LIBCOB_LIBS) libcobod_la_SOURCES = fodbc.c fsqlxfd.c libcobod_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS) libcobod_la_CFLAGS = $(AM_CFLAGS) $(ODBC_CFLAGS) @@ -99,7 +99,7 @@ endif if COB_MAKE_OCI_LIB lib_oc = libcoboc.la -libcoboc_la_LIBADD = libcob.la $(OCI_LIBS) +libcoboc_la_LIBADD = libcob.la $(OCI_LIBS) $(LIBCOB_LIBS) libcoboc_la_SOURCES = foci.c fsqlxfd.c libcoboc_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS) libcoboc_la_CFLAGS = $(AM_CFLAGS) $(OCI_CFLAGS) @@ -109,7 +109,7 @@ endif if COB_MAKE_BDB_LIB lib_db = libcobdb.la -libcobdb_la_LIBADD = libcob.la $(BDB_LIBS) +libcobdb_la_LIBADD = libcob.la $(BDB_LIBS) $(LIBCOB_LIBS) libcobdb_la_SOURCES = fbdb.c fsqlxfd.c libcobdb_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS) libcobdb_la_CFLAGS = $(AM_CFLAGS) $(BDB_CFLAGS) @@ -119,7 +119,7 @@ endif if COB_MAKE_LMDB_LIB lib_lm = libcoblm.la -libcoblm_la_LIBADD = libcob.la $(LMDB_LIBS) +libcoblm_la_LIBADD = libcob.la $(LMDB_LIBS) $(LIBCOB_LIBS) libcoblm_la_SOURCES = flmdb.c fsqlxfd.c libcoblm_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS) libcoblm_la_CFLAGS = $(AM_CFLAGS) $(LMDB_CFLAGS) diff --git a/libcob/cobcapi.c b/libcob/cobcapi.c index 56181f8aa..372ee6ff2 100644 --- a/libcob/cobcapi.c +++ b/libcob/cobcapi.c @@ -73,7 +73,9 @@ cob_get_buff (const size_t buffsize) { if (buffsize > capi_lastsize) { capi_lastsize = buffsize; - cob_free (capi_buffer); + if (capi_buffer) { + cob_free (capi_buffer); + } capi_buffer = cob_fast_malloc (buffsize); } return capi_buffer; diff --git a/libcob/fbdb.c b/libcob/fbdb.c index bbb2b4c85..c38d2570c 100644 --- a/libcob/fbdb.c +++ b/libcob/fbdb.c @@ -1527,6 +1527,7 @@ ix_bdb_open (cob_file_api *a, cob_file *f, char *filename, const enum cob_open_m if (p->data.data != NULL && p->data.size > 0 && p->data.size > f->record_max) { + ix_bdb_close (a, f, 0); return COB_STATUS_39_CONFLICT_ATTRIBUTE; } } else { diff --git a/libcob/fileio.c b/libcob/fileio.c index 870f6398b..8a9d3cec9 100644 --- a/libcob/fileio.c +++ b/libcob/fileio.c @@ -399,12 +399,20 @@ void cob_seqra_init_fileio (cob_file_api *); /* Local functions */ +static COB_INLINE COB_A_INLINE int +isslash (char c) +{ + return +#ifdef _WIN32 + c == '\\' || +#endif + c == '/'; +} + static int isdirvalid (char *filename) { -#ifndef _WIN32 struct stat st; -#endif char tmp[COB_NORMAL_BUFF]; int ln = strlen (filename); @@ -419,12 +427,19 @@ isdirvalid (char *filename) strcpy (tmp, filename); while (--ln > 0) { -#ifndef _WIN32 - /* TODO: This code needs to be tested on Windows and adjusted as needed */ - /* For now it is effectively disabled on Windows */ - if (tmp[ln] == SLASH_CHAR) { + if (isslash(tmp[ln])) { + while (ln > 1 && isslash(tmp[ln-1])) { --ln; } tmp[ln] = 0; errno = 0; +#ifdef _WIN32 + /* Under Windows, a slash is required after a drive letter, else stat fails */ + if (ln == 2 && tmp[1] == ':' + && ((tmp[0] >= 'A' && tmp[0] <= 'Z') + || (tmp[0] >= 'a' && tmp[0] <= 'z'))) { + tmp[ln] = '\\'; + tmp[ln + 1] = 0; + } +#endif if (stat(tmp, &st) == -1) { errno = ENOENT; return 0; @@ -434,7 +449,6 @@ isdirvalid (char *filename) return 0; } } -#endif } errno = 0; return 1; @@ -1095,12 +1109,12 @@ cob_open_qbl (char *filename, int makeit, int append) { int fd, mode; errno = 0; - mode = O_RDWR; + mode = O_RDWR | O_BINARY; if (append) mode |= O_APPEND; if (makeit) mode |= O_CREAT; - fd = open (filename, mode, 0666); + fd = open (filename, mode, COB_FILE_MODE); if (errno) { cob_runtime_warning (_("Error opening %s; %s"), filename, strerror(errno)); @@ -1912,8 +1926,13 @@ cob_file_sync (cob_file *f) fileio_funcs[get_io_ptr (f)]->iosync (&file_api, f); return; } - if (f->organization != COB_ORG_SORT) { - if (f->file) { + if (f->organization != COB_ORG_SORT && f->open_mode != COB_OPEN_INPUT) { + if (f->file + && (f->last_operation == COB_LAST_WRITE + || f->last_operation == COB_LAST_REWRITE + || f->last_operation == COB_LAST_DELETE + || f->last_operation == COB_LAST_COMMIT + || f->last_operation == COB_LAST_ROLLBACK)) { fflush ((FILE *)f->file); } if (f->fd >= 0) { @@ -6485,7 +6504,7 @@ cob_file_unlock (cob_file *f) return; } if (f->organization != COB_ORG_INDEXED) { - if (f->fd >= 0) { + if (f->fd >= 0 && f->open_mode != COB_OPEN_INPUT) { fdcobsync (f->fd); } #ifdef HAVE_FCNTL @@ -9821,6 +9840,53 @@ cob_file_return (cob_file *f) } } +#ifdef _WIN32 + +static int +get_drive_letter(const char **s) +{ + const char *p = *s; + if (p[0] == '/' + && ((p[1] >= 'A' && p[1] <= 'Z') + || (p[1] >= 'a' && p[1] <= 'z')) + && p[2] == '/') { + *s += 3; + return p[1]; + } else + if (((p[0] >= 'A' && p[0] <= 'Z') + || (p[0] >= 'a' && p[0] <= 'z')) + && p[1] == ':' + && (p[2] == '\\' || p[2] == '/')) { + *s += 3; + return p[0]; + } + return 0; +} + +static int +pathcmp (const char *s1, const char *s2) +{ + int c1, c2; + c1 = get_drive_letter(&s1); + c2 = get_drive_letter(&s2); + if (c1 != c2) { + return c1 - c2; + } + do { + c1 = (unsigned char)*s1++; + c2 = (unsigned char)*s2++; + if (c1 == '\\') c1 = '/'; + if (c2 == '\\') c2 = '/'; + } while (c1 && c1 == c2); + return c1 - c2; +} + +#else + +#define pathcmp strcmp + +#endif + char * cob_get_filename_print (cob_file* file, const int show_resolved_name) { @@ -9846,7 +9912,7 @@ cob_get_filename_print (cob_file* file, const int show_resolved_name) offset += len; if (show_resolved_name - && strcmp (file_open_env, file_open_name)) { + && pathcmp (file_open_env, file_open_name)) { /* environment name is set; format: "%s ('%s' => %s)" */ len = 5; memcpy (runtime_buffer + offset, "' => ", len); diff --git a/tests/testsuite.src/run_file.at b/tests/testsuite.src/run_file.at index 1a0114c78..c1977b6b5 100644 --- a/tests/testsuite.src/run_file.at +++ b/tests/testsuite.src/run_file.at @@ -18477,8 +18477,8 @@ AT_DATA([cmod.c], [[ #include #include -#include #include +#include #ifndef TRUE #define TRUE 1 @@ -26634,7 +26634,8 @@ AT_DATA([prog.cob], [ MOVE "./junky/chkdatax" TO DATAFILE. MOVE "invalid directory" TO LIST-TEST PERFORM LISTFILE. - MOVE "/tmp" TO DATAFILE. + ACCEPT DATAFILE FROM ENVIRONMENT "TMP". + IF DATAFILE = SPACES MOVE "/tmp" TO DATAFILE. MOVE "tmp directory" TO LIST-TEST PERFORM LISTFILE. STOP RUN RETURNING 0. @@ -26708,7 +26709,7 @@ AT_DATA([prog.cob], [ DATA-CUST-NUM (SUB). ]) -# TODO: have a single dialect option to change io stats (also for ohter dialects) +# TODO: have a single dialect option to change io stats (also for other dialects) AT_CHECK([$COMPILE -std=mf prog.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog], [0], @@ -26880,7 +26881,8 @@ AT_DATA([prog.cob], [ MOVE "./junky/chkdatax" TO DATAFILE. MOVE "invalid directory" TO LIST-TEST PERFORM LISTFILE. - MOVE "/tmp" TO DATAFILE. + ACCEPT DATAFILE FROM ENVIRONMENT "TMP". + IF DATAFILE = SPACES MOVE "/tmp" TO DATAFILE. MOVE "tmp directory" TO LIST-TEST PERFORM LISTFILE. STOP RUN RETURNING 0. @@ -29833,3 +29835,75 @@ AT_CHECK([$COMPILE -fdefault-file-colseq=EBCDIC prog.cob]) AT_CHECK([$COBCRUN_DIRECT ./prog]) AT_CLEANUP + + +AT_SETUP([Check for potential COB_SYNC bugs]) +AT_KEYWORDS([runfile INPUT READ UNLOCK COB_SYNC]) + +# Under Windows, fdcobsync is an alias of _commit, which calls the +# FlushFileBuffers function, which can not be called on a file opened +# exclusively for input. Therefore, we should ensure the READ and +# UNLOCK operation do not call fdcobsync. + +AT_DATA([prog1.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog1. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT file1 ASSIGN DISK ORGANIZATION SEQUENTIAL. + DATA DIVISION. + FILE SECTION. + FD file1. + 01 file1-rec PIC X. + PROCEDURE DIVISION. + OPEN OUTPUT file1. + WRITE file1-rec. + CLOSE file1. + OPEN INPUT file1. + READ file1. + UNLOCK file1. + CLOSE file1. + GOBACK. +]) + +AT_CHECK([$COMPILE prog1.cob], [0], [], []) +AT_CHECK([COB_SYNC=Y $COBCRUN_DIRECT ./prog1], [0], [], []) + +# Per C standard, calling fflush is UB on files opened for input or after a +# read operation on a file opened for update/append. While harmless under +# most C runtime implementations, this causes problems under MSVCRT (used +# by older MSVC and by MSYS2's MINGW32/64 environments). Typically, a fflush +# after read might mess up the EOF indicator, resulting in incomplete +# file read. Therefore, we should not call fflush on files opened for +# INPUT, or after a READ operation on files opened for I-O. + +AT_DATA([prog2.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT file2 ASSIGN DISK ORGANIZATION LINE SEQUENTIAL. + DATA DIVISION. + FILE SECTION. + FD file2. + 01 file2-rec PIC X. + PROCEDURE DIVISION. + OPEN OUTPUT file2. + MOVE "X" TO file2-rec. + WRITE file2-rec. + MOVE "Y" TO file2-rec. + WRITE file2-rec. + CLOSE file2. + OPEN I-O file2. + READ file2. + READ file2. + CLOSE file2. + GOBACK. +]) + +AT_CHECK([$COMPILE prog2.cob], [0], [], []) +AT_CHECK([COB_SYNC=Y $COBCRUN_DIRECT ./prog2], [0], [], []) + +AT_CLEANUP diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index ba481c31b..092d75705 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -3701,22 +3701,28 @@ AT_DATA([prog.cob], [ AT_DATA([cmod.c], [[ #include -int dump (unsigned char *data) +#include + +COB_EXT_EXPORT int +dump (unsigned char *data) { int i; for (i = 0; i < 4; i++) printf ("%02X", data[i]); puts (" "); + fflush(stdout); return 0; } -int dumpln (unsigned char *data, int len) +COB_EXT_EXPORT int +dumpln (unsigned char *data, int len) { int i; printf ("%2d: ",len); for (i = 0; i < 32 && i < len; i++) printf ("%02X", data[i]); puts (":"); + fflush(stdout); return 0; } ]]) @@ -11322,7 +11328,7 @@ AT_DATA([cmod.c], [[ #include static int doWatch = 1; -int +COB_EXT_EXPORT int CSYMDMP () { int nargs,sts; @@ -11392,6 +11398,7 @@ CSYMDMP () sts = cob_get_field_value (modname, fld, sizeof(buf), buf); printf(" %30s is %s%s. Was changed\n",fld,sts?"Error: ":"",buf); } + fflush(stdout); return 0; } ]]) @@ -11501,7 +11508,7 @@ getType(int type, int byvalue) return wrk; } -int +COB_EXT_EXPORT int CAPI(void *p1, ...) { int k,nargs,type,digits,scale,size,sign,byvalue,isright; @@ -14204,17 +14211,18 @@ AT_DATA([prog.cob], [ AT_DATA([cmod.c], [[ #include -#include +#include extern int CSUB4(); extern int CSUB5(); extern int SUB6(); extern int CSUB7(float f); extern int CSUB8(float *f); -int +COB_EXT_EXPORT int COBCSUB(int y, unsigned char x[15]) { float flt1; printf("C routine passed: Y is %d; X is '%.15s'\n",y,x); + fflush(stdout); CSUB4(y, x); CSUB4(y+1, "A C-String is being passed"); CSUB5(y+2, "A much longer C-String is being passed"); @@ -14354,9 +14362,11 @@ int main() return 0; } -void one_parameter(void *dummy) +COB_EXT_EXPORT void +one_parameter(void *dummy) { printf("Now in one_parameter\n"); + fflush(stdout); routine2((void *)(0x3),(void *)(0x4)); } ]])