Add COB_SET_RUNTIME_STDOUT_FILE and COB_SET_RUNTIME_STDERR_FILE runtime options to enable redirection of stdout/stderr output#296
Conversation
- Defaults back to regular stdout and stderr, if the runtime configurations are not set Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
|
@GitMensch Here is the promised PR for stdout/stderr redirection. I opened it in draft for now to clarify a small issue in I also feel like implementing the redirection in some places seemed unnecessary to me, with the thought that they were meant for direct usage over the command line, rather than a C module interacting with GnuCOBOL. I would appreciate if you could check in general where it makes sense, or whether there are still places missing, where we need to the redirection. As always, always glad and available for further questions and discussions. Thanks for the support! |
|
I can confirm that the failing tests in CI (should be seven in total) are related to the PR, will investigate. |
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
…f cobsetptr not initialized Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
|
All tests should be fixed now, the issue was |
|
Not sure what is going on with Windows CI tests, and the vbisam one, but I believe it is unrelated? |
GitMensch
left a comment
There was a problem hiding this comment.
Please also add those two as "normal" runtime settings COB_STDOUT_FILE and COB_STDERR_FILE with the common file handling (like + opening the file as append), this allows users to both set the filename within a COBOL thread via SET ENVIRONMENT as well as easily having one per PID (which would be your example).
Not sure, but... would it be reasonable to redirect stdin the same way?
| bdb_env->set_errfile (bdb_env, cobsetptr->cob_stderr); | ||
| #if (DB_VERSION_MAJOR > 4) || ((DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR > 2)) | ||
| bdb_env->set_msgfile (bdb_env, stderr); | ||
| bdb_env->set_msgfile (bdb_env, cobsetptr->cob_stderr); |
There was a problem hiding this comment.
Should this be re-set if the current thread changes the file* ?
There was a problem hiding this comment.
How would I trigger the refresh/re-set in cob_set_runtime_option in that case, by simply adding a non-static getter for bdb_env?
There was a problem hiding this comment.
the right way would be to do the same as in screenio - see cob_settings_screenio and its callers... but at least add one exported function into fileio.c that you can call when this specific runtime setting changed
There was a problem hiding this comment.
Done, let me know if it is missing something.
There was a problem hiding this comment.
the only question here is shouldn't the code be moved to the setting function (and that function either be called in the caller or inside this function)?
There was a problem hiding this comment.
That makes sense, I guess I was trying to be as uninvasive as possible, hence redundant stuff.
There was a problem hiding this comment.
I have moved the unused (probably deprecated) part of the ifdef to settings as well. My gut feeling was telling me they should stay together.
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
For stdin, I don't have a clue whether it would be useful, so you can decide. I think it wouldn't be too much of an effort. For adding them as normal runtime settings, how does "SET ENVIRONMENT" work right now for IO files? I thought GnuCOBOL already implements changing the stdout/stderr via |
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
|
If stdin is not a big effort, then please add it the same way, covering all internally used streams. We may even use it later for other tests. For the |
GitMensch
left a comment
There was a problem hiding this comment.
there seems to be one missing element used when calling libcob from cobc, but only on Win32 - I guess that's the place where the binary mode is set (unix_lf), as that will only happen this way on win32
That and the stderr_f assignment inlined should fix CI; adding stdin redirection + reassignment for BDB would then finalize the changes.
If you feel that you can't get the part done soon that works on those changes and are likely more often used by "normal" users (three matching runtime settings to assign the streams to a filename) then we can get this in with a follow-up PR or work by someone else.
- Defaults back to regular stdin, if the runtime configurations are not set Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Apart from TODOs I have commented on, some stylings and docs, all parts should be there now. I have changed the test slightly to make it Windows compatible, let's see if CI passes. |
| { | ||
| if (ambig_fallback) | ||
| { | ||
| /* TODO: Decide how to do stdout/stderr redirection here |
There was a problem hiding this comment.
What do you think about here? Solve it similarly by adding an exported init function?
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
- introduces following runtime configurations: COB_STDIN_FILENAME, COB_STDOUT_FILENAME, COB_STDERR_FILENAME Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
|
Remaining failing CI tests should be hopefully unrelated. |
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
|
Updated docs/changelogs, will mark the PR non-draft, once all the todos are cleared. The one extra failed CI with Ubuntu+MSYS1 should actually pass (i.e. I haven't touched anything other than docs)? Instead, it got broken pipe in SIGPIPE test for some reason. |
GitMensch
left a comment
There was a problem hiding this comment.
ci failures unrelated, most important adjustment is the handling of the setting of the runtime option - the current version won't work if those come from SET ENVIRONMENT (explicit setting in the COBOL main instead of runtime config file / environment)
| bdb_env->set_errfile (bdb_env, cobsetptr->cob_stderr); | ||
| #if (DB_VERSION_MAJOR > 4) || ((DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR > 2)) | ||
| bdb_env->set_msgfile (bdb_env, stderr); | ||
| bdb_env->set_msgfile (bdb_env, cobsetptr->cob_stderr); |
There was a problem hiding this comment.
the only question here is shouldn't the code be moved to the setting function (and that function either be called in the caller or inside this function)?
| if (cobsetptr->cob_stdin_filename) { | ||
| if (!cobsetptr->cob_unix_lf) { | ||
| cobsetptr->cob_stdin = | ||
| fopen (cobsetptr->cob_stdin_filename, "r"); | ||
| } else { | ||
| cobsetptr->cob_stdin = | ||
| fopen (cobsetptr->cob_stdin_filename, "rb"); | ||
| } | ||
| if (!cobsetptr->cob_stdin) { | ||
| cobsetptr->cob_stdin_filename = NULL; | ||
| cobsetptr->cob_stdin = stdin; | ||
| } | ||
| } | ||
|
|
||
| if (cobsetptr->cob_stdout_filename) { | ||
| cobsetptr->cob_stdout = | ||
| cob_open_logfile (cobsetptr->cob_stdout_filename); | ||
| if (!cobsetptr->cob_stdout) { | ||
| cobsetptr->cob_stdout_filename = NULL; | ||
| cobsetptr->cob_stdout = stdout; | ||
| } | ||
| } | ||
|
|
||
| if (cobsetptr->cob_stderr_filename) { | ||
| cobsetptr->cob_stderr = | ||
| cob_open_logfile (cobsetptr->cob_stderr_filename); | ||
| if (!cobsetptr->cob_stderr) { | ||
| cobsetptr->cob_stderr_filename = NULL; | ||
| cobsetptr->cob_stderr = stderr; | ||
| } | ||
| } |
There was a problem hiding this comment.
that part needs to be moved (maybe to termio.c?) and called when one of those runtime settings are changed - and in that case close the old pointer, before opening it again (if the pointer changed and the content differs)
There was a problem hiding this comment.
Moved it, see comment at the bottom.
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Makes sense, I will take a look. |
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## gitside-gnucobol-3.x #296 +/- ##
=======================================================
Coverage ? 67.44%
=======================================================
Files ? 34
Lines ? 61604
Branches ? 16045
=======================================================
Hits ? 41547
Misses ? 14103
Partials ? 5954 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
Signed-off-by: Oguzcan Kirmemis <oguzcan.kirmemis@gmail.com>
|
I think SET ENVIRONMENT should work now, added a test for it. It is kind of messy how I do it in cobsetptr, i.e. having There is also the Otherwise, from my side all that is missing is what we should with |
This PR adds runtime options
COB_SET_RUNTIME_STDOUT_FILEandCOB_SET_RUNTIME_STDERR_FILEwhich allows control over the location where the stdout/stderr output is written.Motivation
For modules written in C that interact with libcob, it is currently difficult to change the location of stdout/stderr output without disturbing the stdout/stderr of the whole process (i.e., other threads). This is especially useful for thread applications, where it is desired that each thread gets its own stdout/stderr without disturbing the one another.
With these options, the main program can easily redirect the output of the COBOL program (including the messages from the runtime itself) and decide what to do with it. For that reason, the main program is also responsible for managing the lifetime of the passed stdout/stderr files, should they be used.
Implementation
COB_SET_RUNTIME_STDOUT_FILEandCOB_SET_RUNTIME_STDERR_FILEoptions tocob_runtime_option_switchincommon.h.cob_settingsincoblocal.hto store the location of configuredstdout/stderr. By default, they are initialized to stdout/stderr of the process.cob_set_runtime_optionandcob_get_runtime_optionincommon.c../libcob, so that they behave accordingly.doc/gnucobol.texi.