Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
525b5a1
First draft
florianschmidt1994 Jan 8, 2025
076ec90
Add documentation
florianschmidt1994 Jan 8, 2025
e79955a
Change default COB_LOAD_GLOBAL to false
florianschmidt1994 Jan 8, 2025
e5a827d
Move option in config_tbl to similar options
florianschmidt1994 Jan 8, 2025
874d5c3
Remove wrong NULL check
florianschmidt1994 Jan 8, 2025
a058ffa
Address review comments
florianschmidt1994 Jan 8, 2025
9ecb459
Add entry to ChangeLog
florianschmidt1994 Jan 8, 2025
e8c88d1
refactor and introduce a cob_dlopen function
florianschmidt1994 Jan 8, 2025
8ee4d57
Restructure according to PR comments
florianschmidt1994 Jan 9, 2025
75de7e1
:Remove unnecessary whitespace changes
florianschmidt1994 Jan 9, 2025
8e3f3a5
Address PR comment
florianschmidt1994 Jan 9, 2025
d2009c2
Move changelog entries to respective folders
florianschmidt1994 Jan 9, 2025
76cbb27
Improve handling of lt_dladvise
florianschmidt1994 Jan 9, 2025
7123abb
Resolve symbol overwrite issue
florianschmidt1994 Jan 9, 2025
df48d36
Add entry to NEWS
florianschmidt1994 Jan 9, 2025
a953f65
Add simple testcase
florianschmidt1994 Jan 9, 2025
3d921d0
Merge test-cases
florianschmidt1994 Jan 13, 2025
3383567
Fix issue with upper / lower case call
florianschmidt1994 Feb 11, 2025
f2a9e9a
Fix another case issue
florianschmidt1994 Feb 11, 2025
bcf1da6
Remove C++ style comment
florianschmidt1994 Feb 11, 2025
f9533aa
Update ChangeLog
GitMensch Feb 11, 2025
5db3270
Address some PR comments
florianschmidt1994 Jul 8, 2025
210200c
Fix syntax issue in misc checks
florianschmidt1994 Jul 9, 2025
337ebc1
test: add testcase for using COB_LOAD_GLOBAL=false to allow multithre…
florianschmidt1994 Aug 14, 2025
fa8e0bc
refactor: remove seemly unnecessary COB_LIBRARY_PATH
florianschmidt1994 Aug 14, 2025
2b57d37
Add some print statements for ci build debugging
florianschmidt1994 Aug 14, 2025
433ebff
Hardcode COB_LIBRARY_PATH for CI debugging
florianschmidt1994 Aug 14, 2025
41f2159
Try lowercase module name in cob_resolve for CI
florianschmidt1994 Aug 14, 2025
0c89be2
chore: make test case C89 compatible
florianschmidt1994 Aug 19, 2025
f4348b7
chore: skip test for MSYS1
florianschmidt1994 Aug 19, 2025
223b5f9
ci: skip test on darwin
florianschmidt1994 Aug 19, 2025
9256417
ci: print $OSTYPE for debugging
florianschmidt1994 Aug 19, 2025
70288a9
fix: match ostype also against darwin24 etc.
florianschmidt1994 Aug 19, 2025
99abcee
fix: remove debugging CI statement
florianschmidt1994 Aug 19, 2025
397dbd7
ci: force sched_yield in test and decrease number of threads
florianschmidt1994 Aug 19, 2025
65602c8
fix: use $COBC to compile test binary
florianschmidt1994 Aug 27, 2025
2cab53a
ci: try again to ignore msys
florianschmidt1994 Sep 17, 2025
19c8648
fix: Add HAVE_DLMOPEN and HAVE_PTHREAD_H to skip COB_LOAD_GLOBAL dlmo…
oguzcankirmemis Nov 9, 2025
5abc321
Revert "fix: Add HAVE_DLMOPEN and HAVE_PTHREAD_H to skip COB_LOAD_GLO…
florianschmidt1994 Nov 17, 2025
49a99a8
fix: skip tests on compilation failure using exit code 77
florianschmidt1994 Nov 17, 2025
c2b16d8
Update run_misc.at
GitMensch Dec 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ NEWS - user visible changes -*- outline -*-
$b for executable basename, $d for date in YYYYMMDD format, $t for time
in HHMMSS format (before, only $$ was available for pid)

** introduction of the COB_LOAD_GLOBAL boolean flag, which determines whether
the symbols of dynamically loaded shared libraries are made available
globally to other shared objects or remain confined locally. Previously,
this behavior depended on the underlying platform, where the default was
often "global." The default behavior is now explicitly set to "local".

* New build features

** configure now uses pkg-config/ncurses-config to search for ncurses and
Expand Down
4 changes: 4 additions & 0 deletions config/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

* gcos-strict.conf: set init-justify to no after testing on GCOS

2024-12-16 Simon Sobisch <[email protected]>

* config/runtime.cfg: add COB_LOAD_GLOBAL

2024-08-17 Ammar Almoris <[email protected]>

FR #474: add runtime configuration to hide cursor for extended screenio
Expand Down
13 changes: 13 additions & 0 deletions config/runtime.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,19 @@
# Default: false
# Example: PHYSICAL_CANCEL TRUE

# Environment name: COB_LOAD_GLOBAL
# Parameter name: load_global
# Purpose: tell the system loader to provide symbols in CALLed
# programs globally, allowing symbols to be found for linked
# libraries later
# Type: boolean
# Note: COBOL CALLs will always find symbols in already CALLed or
# pre-loaded modules; this setting is mostly an advise to the
# system, not all systems are capable of loading libraries
# global/local
# Default: false
# Example: load_global true

#
## File I/O
#
Expand Down
11 changes: 11 additions & 0 deletions libcob/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,17 @@
* common.h, common.c: handle [__xlc__] identical to [__IBMC__]
* common.c [!SIGPIPE]: fix warning about unused jump

2025-01-08 Florian Schmidt <[email protected]>

* call.c (cob_dlopen): new function used instead of partially re-defining
lt_dlopen; changed default to not load symbols to the global namespace
any more but locally (was always the case for _WIN32)
* common.c, coblocal.h (cob_settings): added boolean COB_LOAD_GLOBAL
to toggle into which namespace the symbols of CALLed programs should be
made available
* call.c (cob_dlopen, add_to_preload, cache_preload, cob_exit_call):
handle COB_LOAD_GLOBAL (load_global)

2024-12-31 Simon Sobisch <[email protected]>

* common.c [WITH_EXTENDED_SCREENIO]: adjusted curses includes/defines
Expand Down
98 changes: 80 additions & 18 deletions libcob/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,6 @@ FILE *fmemopen (void *buf, size_t size, const char *mode);
#include <windows.h>
#include <io.h> /* for access */

static HMODULE
lt_dlopen (const char *x)
{
if (x == NULL) {
return GetModuleHandle (NULL);
}
return LoadLibrary(x);
}

static void *
lt_dlsym (HMODULE hmod, const char *p)
{
Expand Down Expand Up @@ -106,7 +97,6 @@ lt_dlerror (void)
/* note: only defined in configure when HAVE_DLFCN_H is true and dlopen can be linked */
#include <dlfcn.h>

#define lt_dlopen(x) dlopen(x, RTLD_LAZY | RTLD_GLOBAL)
#define lt_dlsym(x,y) dlsym(x, y)
#define lt_dlclose(x) dlclose(x)
#define lt_dlerror() dlerror()
Expand Down Expand Up @@ -171,6 +161,10 @@ static char *call_filename_buff;
static lt_dlhandle mainhandle;
#endif

#if !defined(_WIN32) && !defined(USE_LIBDL)
static lt_dladvise advise = NULL;
#endif

static size_t call_lastsize;
static size_t resolve_size = 0;
static unsigned int cob_jmp_primed;
Expand Down Expand Up @@ -289,6 +283,42 @@ static int last_entry_is_working_directory (const char *buff, const char *pstr)
return 0;
}

static void* cob_dlopen(const char* filename) {
#if defined (_WIN32)
if (filename == NULL) {
return GetModuleHandle (NULL);
}
return LoadLibrary(filename);
#elif defined(USE_LIBDL)
const int flags = cobsetptr->cob_load_global
? RTLD_LAZY | RTLD_GLOBAL
: RTLD_LAZY | RTLD_LOCAL;

return dlopen(filename, flags);
#else
if (advise != NULL) {
int error;
static int last_cob_load_global = -1;

if (cobsetptr->cob_load_global != last_cob_load_global) {
last_cob_load_global = cobsetptr->cob_load_global

if (cobsetptr->cob_load_global) {
error = lt_dladvise_global (&advise);
} else {
error = lt_dladvise_local (&advise);
}

if (error) {
cob_runtime_warning ("set link loader hint failed; %s", lt_dlerror());
}
}
}

return lt_dlopenadvise (filename, advise);
#endif
}

/* resolves the actual library path used from
* COB_LIBRARY_PATH runtime setting
* "." as current working direktory [if not included already: prefixed]
Expand Down Expand Up @@ -555,9 +585,20 @@ add_to_preload (const char *path, lt_dlhandle libhandle, struct struct_handle *l
base_preload_ptr = preptr;
}
#else
COB_UNUSED (last_elem);
preptr->next = base_preload_ptr;
base_preload_ptr = preptr;
/* Use the same logic as above in case the cob_load_global is set to local */
if (!cobsetptr->cob_load_global) {
if (last_elem) {
last_elem->next = preptr;
} else {
preptr->next = NULL;
base_preload_ptr = preptr;
}
} else {
COB_UNUSED (last_elem);
preptr->next = base_preload_ptr;
base_preload_ptr = preptr;
}

#endif

if (!cobsetptr->cob_preload_str) {
Expand Down Expand Up @@ -590,6 +631,9 @@ cache_preload (const char *path)
/* Save last element of preload list */
if (!preptr->next) last_elem = preptr;
#endif
if(!cobsetptr->cob_load_global) {
if (!preptr->next) last_elem = preptr;
}
}

/* Check for duplicate in already loaded programs;
Expand Down Expand Up @@ -619,7 +663,7 @@ cache_preload (const char *path)
return 0;
}

libhandle = lt_dlopen (path);
libhandle = cob_dlopen (path);
if (!libhandle) {
cob_runtime_warning (
_("preloading from existing path '%s' failed; %s"), path, lt_dlerror());
Expand Down Expand Up @@ -865,7 +909,7 @@ cob_resolve_internal (const char *name, const char *dirent,
for (p = call_filename_buff; *p; ++p) {
*p = (cob_u8_t)toupper(*p);
}
handle = lt_dlopen (call_filename_buff);
handle = cob_dlopen (call_filename_buff);
if (handle != NULL) {
/* Candidate for future calls */
cache_dynload (call_filename_buff, handle);
Expand Down Expand Up @@ -908,7 +952,7 @@ cob_resolve_internal (const char *name, const char *dirent,
return NULL;
}
lt_dlerror (); /* clear last error conditions */
handle = lt_dlopen (call_filename_buff);
handle = cob_dlopen (call_filename_buff);
if (handle != NULL) {
/* Candidate for future calls */
cache_dynload (call_filename_buff, handle);
Expand Down Expand Up @@ -941,7 +985,7 @@ cob_resolve_internal (const char *name, const char *dirent,
call_filename_buff[COB_NORMAL_MAX] = 0;
if (access (call_filename_buff, R_OK) == 0) {
lt_dlerror (); /* clear last error conditions */
handle = lt_dlopen (call_filename_buff);
handle = cob_dlopen (call_filename_buff);
if (handle != NULL) {
/* Candidate for future calls */
cache_dynload (call_filename_buff, handle);
Expand Down Expand Up @@ -1701,6 +1745,15 @@ cob_exit_call (void)
#endif
#endif

#if !defined(_WIN32) && !defined(USE_LIBDL)
if (advise != NULL) {
if (lt_dladvise_destroy (&advise)) {
/* not translated as highly unlikely */
cob_runtime_warning (
"destroying link loader advise failed; %s", lt_dlerror ());
}
}
#endif
}

/* try to load specified module from all entries in COB_LIBRARY_PATH
Expand Down Expand Up @@ -1788,12 +1841,21 @@ cob_init_call (cob_global *lptr, cob_settings* sptr, const int check_mainhandle)

lt_dlinit ();

#if !defined(_WIN32) && !defined(USE_LIBDL)
int error = lt_dladvise_init(&advise);
if (error) {
/* not translated as highly unlikely */
cob_runtime_warning (
"init link loader advise failed; %s", lt_dlerror());
}
#endif

#ifndef COB_BORKED_DLOPEN
/* only set main handle if not started by cobcrun as this
saves a check for exported functions in every CALL
*/
if (check_mainhandle) {
mainhandle = lt_dlopen (NULL);
mainhandle = cob_dlopen (NULL);
} else {
mainhandle = NULL;
}
Expand Down
1 change: 1 addition & 0 deletions libcob/coblocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ typedef struct __cob_settings {

/* call.c */
int cob_physical_cancel; /* 0 "= "logical only" (default), 1 "also unload", -1 "never unload" */
unsigned int cob_load_global; /* hint for dynamic linker to make symbols available 0=global, 1=local */
unsigned int name_convert;
char *cob_preload_str;
char *cob_library_path;
Expand Down
3 changes: 3 additions & 0 deletions libcob/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,9 @@ static struct config_tbl gc_conf[] = {
{"LOGICAL_CANCELS", "logical_cancels", NULL, NULL, GRP_HIDE, ENV_BOOL | ENV_NOT, SETPOS (cob_physical_cancel)},
{"COB_LIBRARY_PATH", "library_path", NULL, NULL, GRP_CALL, ENV_PATH, SETPOS (cob_library_path)}, /* default value set in cob_init_call() */
{"COB_PRE_LOAD", "pre_load", NULL, NULL, GRP_CALL, ENV_STR, SETPOS (cob_preload_str)},
#ifndef _WIN32
{"COB_LOAD_GLOBAL", "load_global", "0", NULL, GRP_CALL, ENV_BOOL, SETPOS(cob_load_global)},
#endif
{"COB_BELL", "bell", "0", beepopts, GRP_SCREEN, ENV_UINT | ENV_ENUMVAL, SETPOS (cob_beep_value)},
{"COB_DEBUG_LOG", "debug_log", NULL, NULL, GRP_HIDE, ENV_FILE, SETPOS (cob_debug_log)},
{"COB_DISABLE_WARNINGS", "disable_warnings", "0", NULL, GRP_MISC, ENV_BOOL | ENV_NOT, SETPOS (cob_display_warn)},
Expand Down
Loading
Loading