I rather prefer using VBIsam over BDB for Indexed files as the 'data' file is a plain text file.
I have a need to be able to access the 'same' indexed file in program A and then whilst that
file is still open - have program A call program B which also reads the 'same' indexed file.
Since VBIsam presently is unable to 'share' indexed files I thought I would try using 'EXTERNAL.
Having the indexed file described as EXTERNAL 'should' enable it to be used at the same
time in both the calling & called programs.
I wrote 3 programs - A creates an indexed file - reads a record - displays it then calls program B.
B opens the file shared - reads a record - then calls program C. C reads a record displays it then ends.
Program B displays correctly because program A closes the file - but program C crashes with:
libcob: TSTPRG6C.cbl:26: error: file already open (status = 41)
for file FILA ('TSTPRG6' => C:\TEST\TSTPRG6) on OPEN
libcob: TSTPRG6C.cbl:26: warning: implicit CLOSE of FILA ('TSTPRG6')
I've attached the 3 simple programs if anyone's interested in what I'm doing wrong.
I'd really like to get EXTERNAL files working because VBIsam can't share files at present.
Then again - I note with interest the Programming guide says this:
2.2.8.1. File Sharing
GnuCOBOL controls concurrent-file access at the highest level through the concept of file shar-
ing, enforced when a program attempts to open a file. This is accomplished via a UNIX
operating-system routine called "fcntl()". That module is not currently supported by Win-
dows and is not present in the MinGW Unix-emulation package. GnuCOBOL builds created
using a MinGW environment will be incapable of supporting file-sharing controls — files will
always be shared in such environments.
Perhaps this is not actually the case..
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@vcoen Can you please adjust that part of the PG? GnuCOBOL uses whatever is available to create and release locks and if "nothing" is available then there are still:
the OS taking care of file locks and sharing
for ORGANIZATION IS INDEXED - the indexed handler (which in the BDB case is only active if DB_HOME is set to the same directory for all COBOL processes that want to use the same indexed files); possibly only rudimentary but then at the DB level for the new SQL handlers in trunk
One may could say that the control is possibly not as fine-graned in Win32/DOS (not only MinGW) in general, but even there they are not "always shared".
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Where I supplied the 'almost' identical 3 programs showing that using open I-o sharing all FILE
didn't appear to work.
I'm using VBIsam 2.0.1 which I believe is the same version that Arnold uses for the 'official' releases - although I have tried 2.1.1 with similar 'no worky' results.
I don't know what your definition of 'sharing' is - but mine is that a file is opened shared in one program and another program opening the same file - also shared - can read it.
That is NOT the case in the original 3 programs - nor the 3 that I attached at the top.
The 3 at the top I 'attempted' to use EXTERNAL in addition to sharing all.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've amended the 3 programs and reduced them to 2.
The first creates an indexed file - closes that file - then reopens it shared all.
It then reads a record and passes the key to the second program.
The second program opens the same file shared all - AND CRASHES AT THIS POINT.
It's supposed to read the passed key - then read the next record and pass that key back.
It crashes with : libcob: TSTPRG6B.cbl:26: error: file sharing conflict (status = 61) for file FILA ('TSTPRG6' => C:\TEST\TSTPRG6) on OPEN
That's pretty specific that file sharing doesn't work - isn't it.
Hey David.
I use a common I-O routine per dataset.
If your file access is limited to a single .EXE this technique works for me.
The common I-O routine services COBOL I-O from programs within the current run unit.
In your example, program "A", "B", and "C" would have access to the dataset.
You must replace all COBOL I-O in your application with calls to the common I-O module.
Example:
MOVE 'OPOT' TO ZRETPID-FUNC
CALL ZRETPID USING
ZRETPID-FUNC
ZPROCESS-ID
ZRETPID-STATUS
MOVE 'ISRT' TO ZRETPID-FUNC
CALL ZRETPID USING
ZRETPID-FUNC
ZPROCESS-ID
ZRETPID-STATUS
MOVE 'CLOSE' TO ZRETPID-FUNC
CALL ZRETPID USING
ZRETPID-FUNC
ZPROCESS-ID
ZRETPID-STATUS.
Here is a snippet of a common I-O routine.
It has logic in it for VSAM / ISAM support. For instance START, READ NEXT...
LINKAGESECTION.01PARM-FUNCPICX(08).01LTRIGGER-DATA.05LTPID-9PIC9(08).01LINK-FILE-STATUSPICX(02).PROCEDUREDIVISIONUSINGPARM-FUNCLTRIGGER-DATALINK-FILE-STATUS.A-000-MAINLINE.IFFIRST-TIME='1'MOVE'GNUDATA'TOREADV-KEYMOVELENGTHOFREADV-KEYTOREADV-KEY-LENCALLZREADENVUSINGREADV-KEYREADV-KEY-LENREADV-VALUEREADV-VALUE-LENIFRETURN-CODENOT=0MOVE'ZRETPID: "GNUDATA" SETTING NOT FOUND'TOZMSG1CALLZMSGBOX1USINGZMSG1STOPRUNEND-IFMOVESPACESTOTRIGGER-DSNSTRINGREADV-VALUE(1:READV-VALUE-LEN)DELIMITEDBYSIZE'\' DELIMITED BY SIZE 'EXEPID.DAT' DELIMITED BY SIZE INTO TRIGGER-DSN MOVE '0' TO FIRST-TIME END-IF IF TRIGGER-OPEN = '1' MOVE LTRIGGER-DATA TO TRIGGER-DATA END-IF PERFORM B-000-EVALUATE THRU B-000-EXIT. IF TEST-FILE-STATUS = '00' IF PARM-FUNC (1:2) NOT = 'OP' AND PARM-FUNC (1:4) NOT = 'CLOS' MOVE TRIGGER-DATA TO LTRIGGER-DATA END-IF END-IF. MOVE TEST-FILE-STATUS TO LINK-FILE-STATUS. GOBACK. A-000-EXIT. EXIT. B-000-EVALUATE. EVALUATE PARM-FUNC WHEN 'CLOS' MOVE 'CLOS' TO LOCAL-FUNC PERFORM B-001-SERVICE-IO THRU B-001-EXIT WHEN 'OPEN' MOVE 'OPIO' TO LOCAL-FUNC PERFORM B-001-SERVICE-IO THRU B-001-EXIT WHEN 'BROWSE' MOVE 'OPEN' TO LOCAL-FUNC PERFORM B-001-SERVICE-IO THRU B-001-EXIT WHEN OTHER MOVE PARM-FUNC TO LOCAL-FUNC PERFORM B-001-SERVICE-IO THRU B-001-EXIT END-EVALUATE. B-000-EXIT. EXIT. B-001-SERVICE-IO. MOVE '0' TO IO-OK. MOVE '1' TO FIRST-CALL. MOVE '00' TO TEST-FILE-STATUS EVALUATE LOCAL-FUNC WHEN 'UPDT' PERFORM B-070-REWRITE THRU B-070-EXIT UNTIL IO-OK NOT = '0' WHEN 'REPL' PERFORM B-070-REWRITE THRU B-070-EXIT UNTIL IO-OK NOT = '0' WHEN 'CLOS' MOVE 'C' TO FILE-STATUS PERFORM B-030-CLOSE THRU B-030-EXIT WHEN 'CLOSE' MOVE 'C' TO FILE-STATUS PERFORM B-030-CLOSE THRU B-030-EXIT WHEN 'DLET' PERFORM B-050-DLET THRU B-050-EXIT UNTIL IO-OK NOT = '0' WHEN 'GET' PERFORM B-010-GU THRU B-010-EXIT UNTIL IO-OK NOT = '0' WHEN 'GN' PERFORM B-020-GN THRU B-020-EXIT UNTIL IO-OK NOT = '0' WHEN 'GU' PERFORM B-010-GU THRU B-010-EXIT UNTIL IO-OK NOT = '0' WHEN 'ISRT' PERFORM B-060-ISRT THRU B-060-EXIT UNTIL IO-OK NOT = '0' WHEN 'OPEN' IF TRIGGER-OPEN = '1' MOVE '0' TO TRIGGER-OPEN CLOSE TRIGGER-FILE END-IF PERFORM B-005-OPEN THRU B-005-EXIT WHEN 'OPIO' IF TRIGGER-OPEN = '1' MOVE '0' TO TRIGGER-OPEN CLOSE TRIGGER-FILE END-IF PERFORM B-005-OPEN THRU B-005-EXIT WHEN 'OPOT' IF TRIGGER-OPEN = '1' MOVE '0' TO TRIGGER-OPEN CLOSE TRIGGER-FILE END-IF PERFORM B-005-OPEN THRU B-005-EXIT WHEN 'PREV' PERFORM B-090-GET-PREV THRU B-090-EXIT UNTIL IO-OK NOT = '0' WHEN 'STN<' PERFORM B-040-START-KEY THRU B-040-EXIT UNTIL IO-OK NOT = '0' WHEN 'STN>' PERFORM B-045-START-KEY THRU B-045-EXIT UNTIL IO-OK NOT = '0' WHEN 'SKILL' MOVE '0' TO TRIGGER-OPEN CALL 'CBL_DELETE_FILE' USING TRIGGER-DSN END-EVALUATE. B-001-EXIT. EXIT. B-005-OPEN. IF LOCAL-FUNC = 'OPIO' MOVE '1' TO TRIGGER-OPEN OPEN I-O TRIGGER-FILE MOVE 'B' TO FILE-STATUS MOVE TRIGGER-STATUS TO TEST-FILE-STATUS IF TEST-FILE-STATUS NOT = '00' AND NOT = '35' MOVE 'ZRETPID:OPENI-OFAILED' TO ZMSG1 MOVE TEST-FILE-STATUS TO ZMSG1 (25:2) MOVE TRIGGER-DSN TO ZMSG1 (28:50) CALL ZMSGBOX1 USING ZMSG1 STOP RUN END-IF GO TO B-005-EXIT END-IF. IF LOCAL-FUNC = 'OPOT' MOVE '1' TO TRIGGER-OPEN OPEN OUTPUT TRIGGER-FILE MOVE 'O' TO FILE-STATUS MOVE TRIGGER-STATUS TO TEST-FILE-STATUS IF TEST-FILE-STATUS NOT = '00' MOVE 'ZRETPID:OPENOUTFAILED' TO ZMSG1 MOVE TEST-FILE-STATUS TO ZMSG1 (25:2) MOVE TRIGGER-DSN TO ZMSG1 (28:50) CALL ZMSGBOX1 USING ZMSG1 STOP RUN END-IF GO TO B-005-EXIT END-IF. IF LOCAL-FUNC NOT = 'OPIO' AND NOT = 'OPOT' MOVE '1' TO TRIGGER-OPEN MOVE 'I' TO FILE-STATUS OPEN INPUT TRIGGER-FILE MOVE TRIGGER-STATUS TO TEST-FILE-STATUS IF TEST-FILE-STATUS NOT = '00' MOVE 'ZRETPID:OPENINFAILED' TO ZMSG1 MOVE TEST-FILE-STATUS TO ZMSG1 (25:2) MOVE TRIGGER-DSN TO ZMSG1 (28:50) CALL ZMSGBOX1 USING ZMSG1 STOP RUN END-IF GO TO B-005-EXIT END-IF. B-005-EXIT. EXIT. B-010-GU. MOVE '0' TO EOD-IO. PERFORM B-011-READ THRU B-011-EXIT UNTIL EOD-IO NOT = '0'. IF TEST-FILE-STATUS = '00' MOVE '1' TO IO-OK END-IF. B-010-EXIT. EXIT.
I use this technique extensively.
It isn't quite "sharing" - in some aspects it is better.
A caveat when you locate a postion with START it is advisible to store the READ NEXT value to isolate the file position from one .DLL to another. Reposition on subsequent calls if necessary.
I presume you could generalize the common I-O routine by using EXTFH.
Ralph
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks Ralph, I'll have a good look through it & see if I can make use of it - the actual set of programs have a maximum of 12 indexed files in them and there are 7 subroutines that would use up to 6 files at any one time - so it may become a bit unweildy, compared to just having 'file sharing' work as described - I'm surprised no-one has come across this before as ISAM files was a big thing back in the good old days.
I'm converting from another language - that using files in a shared manner just works.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It gets real easy.
Second nature to me at this point.
Once you create a common I-O routine for the first time, cloning it is a simple matter for the next data set.
Using it is simple as well.
Let me know if you want a fulling working caller and common I-O example set.
I even use it as a poor man's inter-process communication facility.
Ralph
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm thinking of maybe just closing each file before I call the called program - hopefully that won't take up too much time and whilst not actually 'sharing' the file - will allow the called program to do its thing.
I may still take you up on that offer.
David
Last edit: Simon Sobisch 2020-06-16
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Rechecked: the issue is not related to VB-ISAM at all, instead it is related to the issue that GnuCOBOL 3.x doesn't actually support the SHARING clause.
It looks like trunk won't do the correct thing here, too - but that's an actual easy fix there. I have to see when I find time to work on this :-(
I may be able to manually merge the SHARING part from trunk (2016 changes, only did not got in so far as they were intermixed with other changes) and then fix this case (+merge the fix back).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
No. I've lost the track on this and likely won't do much in the next days on this- but it would help if you could create a bug-report for this with the minimal information needed to show the issue - as discussion board entries are much less likely to loose track of.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I rather prefer using VBIsam over BDB for Indexed files as the 'data' file is a plain text file.
I have a need to be able to access the 'same' indexed file in program A and then whilst that
file is still open - have program A call program B which also reads the 'same' indexed file.
Since VBIsam presently is unable to 'share' indexed files I thought I would try using 'EXTERNAL.
Having the indexed file described as EXTERNAL 'should' enable it to be used at the same
time in both the calling & called programs.
I wrote 3 programs - A creates an indexed file - reads a record - displays it then calls program B.
B opens the file shared - reads a record - then calls program C. C reads a record displays it then ends.
Program B displays correctly because program A closes the file - but program C crashes with:
libcob: TSTPRG6C.cbl:26: error: file already open (status = 41)
for file FILA ('TSTPRG6' => C:\TEST\TSTPRG6) on OPEN
libcob: TSTPRG6C.cbl:26: warning: implicit CLOSE of FILA ('TSTPRG6')
I've attached the 3 simple programs if anyone's interested in what I'm doing wrong.
I'd really like to get EXTERNAL files working because VBIsam can't share files at present.
Then again - I note with interest the Programming guide says this:
2.2.8.1. File Sharing
GnuCOBOL controls concurrent-file access at the highest level through the concept of file shar-
ing, enforced when a program attempts to open a file. This is accomplished via a UNIX
operating-system routine called "fcntl()". That module is not currently supported by Win-
dows and is not present in the MinGW Unix-emulation package. GnuCOBOL builds created
using a MinGW environment will be incapable of supporting file-sharing controls — files will
always be shared in such environments.
Perhaps this is not actually the case..
@vcoen Can you please adjust that part of the PG? GnuCOBOL uses whatever is available to create and release locks and if "nothing" is available then there are still:
ORGANIZATION IS INDEXED- the indexed handler (which in the BDB case is only active ifDB_HOMEis set to the same directory for all COBOL processes that want to use the same indexed files); possibly only rudimentary but then at the DB level for the new SQL handlers in trunkOne may could say that the control is possibly not as fine-graned in Win32/DOS (not only MinGW) in general, but even there they are not "always shared".
This is too indefinite i.e., if and but.
When you get an actual precise process for users I can change it but at the moment it looks like it is a heavy may be for, - well any thing.
It is some times flacky under Linux (use of DB_HOME etc some times does not work with and without.
So I will keep it as it is for the moment.
Concerning BDB you may want to use
db_dumpto get a plain textfile (which would obviosuly not work well if you have binary fields in there).It definitely is. What exact version do you use? Please provide a sample program to reproduce it.
To the
EXTERNALissue - anEXTERNALfile shares the open and record positions, therefore the error message is completely correct.I refer to a discussion earlier this year.
https://sourceforge.net/p/open-cobol/discussion/cobol/thread/630d1a2d/#918e/e6c5/5edf/be52/378f
Where I supplied the 'almost' identical 3 programs showing that using open I-o sharing all FILE
didn't appear to work.
I'm using VBIsam 2.0.1 which I believe is the same version that Arnold uses for the 'official' releases - although I have tried 2.1.1 with similar 'no worky' results.
I don't know what your definition of 'sharing' is - but mine is that a file is opened shared in one program and another program opening the same file - also shared - can read it.
That is NOT the case in the original 3 programs - nor the 3 that I attached at the top.
The 3 at the top I 'attempted' to use EXTERNAL in addition to sharing all.
I've amended the 3 programs and reduced them to 2.
The first creates an indexed file - closes that file - then reopens it shared all.
It then reads a record and passes the key to the second program.
The second program opens the same file shared all - AND CRASHES AT THIS POINT.
It's supposed to read the passed key - then read the next record and pass that key back.
It crashes with : libcob: TSTPRG6B.cbl:26: error: file sharing conflict (status = 61) for file FILA ('TSTPRG6' => C:\TEST\TSTPRG6) on OPEN
That's pretty specific that file sharing doesn't work - isn't it.
Yes. I'm at least investigating this now...
Hey David.
I use a common I-O routine per dataset.
If your file access is limited to a single .EXE this technique works for me.
The common I-O routine services COBOL I-O from programs within the current run unit.
In your example, program "A", "B", and "C" would have access to the dataset.
You must replace all COBOL I-O in your application with calls to the common I-O module.
Example:
Here is a snippet of a common I-O routine.
It has logic in it for VSAM / ISAM support. For instance START, READ NEXT...
I use this technique extensively.
It isn't quite "sharing" - in some aspects it is better.
A caveat when you locate a postion with START it is advisible to store the READ NEXT value to isolate the file position from one .DLL to another. Reposition on subsequent calls if necessary.
I presume you could generalize the common I-O routine by using EXTFH.
Ralph
Thanks Ralph, I'll have a good look through it & see if I can make use of it - the actual set of programs have a maximum of 12 indexed files in them and there are 7 subroutines that would use up to 6 files at any one time - so it may become a bit unweildy, compared to just having 'file sharing' work as described - I'm surprised no-one has come across this before as ISAM files was a big thing back in the good old days.
I'm converting from another language - that using files in a shared manner just works.
It gets real easy.
Second nature to me at this point.
Once you create a common I-O routine for the first time, cloning it is a simple matter for the next data set.
Using it is simple as well.
Let me know if you want a fulling working caller and common I-O example set.
I even use it as a poor man's inter-process communication facility.
Ralph
Thanks Ralph,
I'm thinking of maybe just closing each file before I call the called program - hopefully that won't take up too much time and whilst not actually 'sharing' the file - will allow the called program to do its thing.
I may still take you up on that offer.
David
Last edit: Simon Sobisch 2020-06-16
Rechecked: the issue is not related to VB-ISAM at all, instead it is related to the issue that GnuCOBOL 3.x doesn't actually support the SHARING clause.
It looks like trunk won't do the correct thing here, too - but that's an actual easy fix there. I have to see when I find time to work on this :-(
I may be able to manually merge the SHARING part from trunk (2016 changes, only did not got in so far as they were intermixed with other changes) and then fix this case (+merge the fix back).
Strange that the identical 2 latest programs work fine under BDB where they fail under VBI.
Identical.!!!
@sf-mensch - Is there any resolve to this - 18 months later ???
No. I've lost the track on this and likely won't do much in the next days on this- but it would help if you could create a bug-report for this with the minimal information needed to show the issue - as discussion board entries are much less likely to loose track of.