How to check whether a file is open already in COBOL? - file

I am trying to find out a way to check whether a file is already opened in COBOL, so that I can open it if it is closed or close it if it is opened.
Thnx.

Check the FILE STATUS and act accordingly.
Try the following:
Add a FILE-STATUS under the FILE-CONTROL, for example:
FILE-CONTROL.
SELECT MYFILE ASSIGN MYDD
ORGANIZATION SEQUENTIAL
ACCESS SEQUENTIAL
FILE STATUS MYFILE-STATUS.
Declare a FILE STATUS variable in WORKING-STORAGE
as a PIC X(2) value, for example:
01 MYFILE-STATUS PIC X(2).
88 MYFILE-ALREADY-OPEN VALUE '41'.
Then in the PROCEDURE DIVISIONissue an OPEN for your
file. Immediately following that, test the value of FILE STATUS
as in:
OPEN MYFILE....
IF MYFILE-ALRADY-OPEN
CLOSE MYFILE...
END-IF
IF MYFILE-STATUS <> '00'
perform some sort of general error routine
END-IF
Values of FILE STATUS where the first character is not a '9', are
COBOL standard values so testing for '41' to detect an already open file
should work on all COBOL implementations. Beware when the first character is a '9',
these are vendor specific file status codes. Check out the following link for
a good introduction to using COBOL FILE STATUS: http://www.simotime.com/vsmfsk01.htm

Your compiler may also provide a external API, such as CBL_CHECK_FILE_EXIST which can be found on Micro Focus COBOL, AcuCOBOL and Fujutsu COBOL.
For example, on Micro Focus COBOL:
copy "cblproto.cpy".
program-id. MYMAIN.
working-storage section.
01 .
05 file-details cblt-fileexist-buf.
procedure division.
call 'CBL_CHECK_FILE_EXIST' using 'mymain.cbl '
file-details
if return-code not = 0
display "File mymain.cbl does not exist (or error)"
else
display "File mymain.cbl size is " cblt-fe-filesize
of file-details
end-if
end program MYMAIN.

Related

COBOL - File Status 37 when opening sequential dataset with relative & dynamic options

I'm trying to open a sequential dataset.
I get the file status 37, for which IBM says:
An OPEN statement was attempted on a file that would not support the
open mode specified in the OPEN statement. Possible violations are:
The EXTEND or OUTPUT phrase was specified but the file would not support write operations.
The I-O phrase was specified but the file would not support the input and output operations permitted.
The INPUT phrase was specified but the file would not support read operations.
I suspect the third, because the relevant bits of my program are :
*----------------------
INPUT-OUTPUT SECTION.
*----------------------
FILE-CONTROL.
* input file 1
SELECT INPUT-1-FILE
ASSIGN TO EXAMPLE
ORGANIZATION IS RELATIVE
ACCESS MODE IS DYNAMIC
RELATIVE KEY IS INPUT-1-ACCESS-KEY
FILE STATUS IS INPUT-1-FS
.
****************
DATA DIVISION.
****************
*--------------
FILE SECTION.
*--------------
* fichier 1
FD INPUT-1-FILE
.
01 INPUT-1-LINE.
05 filler PIC X(300).
*-------------------------
WORKING-STORAGE SECTION.
*-------------------------
77 INPUT-1-ACCESS-KEY PIC 9(3) comp value 1.
01 INPUT-1-FS PIC 99 value 00.
*********************
PROCEDURE DIVISION.
*********************
OPEN INPUT INPUT-1-FILE
DISPLAY INPUT-1-FS
And the DD card in my JCL looks like :
EXAMPLE DD DISP=SHR,DSN=MY.DATASET.NAME
We're using COBOL v5, so I checked IBM's relevant docs, but I can't find any reason that my file is not openable in input mode.
Here are my dataset's characteristics:
And the result of a VSAM listcat:
In your program, ORGANIZATION IS RELATIVE means the input file must be a relative record data set (RRDS) VSAM file, which can be defined using the IDCAMS DEFINE command. What could be happening is that if the file you open is a sequential file, you get a file status of 37. More information about IDCAMS DEFINE is mentioned in IBM Redbook "VSAM Demystified" section 1.5.3, 'Relative record data set'.
You can make the input file a VSAM file with something like the following:
//[YOURID] JOB ,
// MSGCLASS=S,REGION=0M,COND=(9,LT),NOTIFY=&SYSUID,TIME=(1,1)
//*********************************************************************
//* Create a VSAM
//*********************************************************************
//S1IDCAMS EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DELETE ([YOURID].P00695.VSAMRRDS) CLUSTER PURGE
DEFINE CLUSTER (NAME([YOURID].P00695.VSAMRRDS) -
NUMBERED -
RECORDSIZE(80 80) -
BUFFERSPACE(2048) -
SHAREOPTIONS(4 3) -
VOLUMES(SYS162)) -
DATA (NAME([YOURID].P00695.VSAMRRDS.DATA) -
TRACK(1,1) -
CISZ (1024))
/*
//S2REPRO EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//VSAM DD DISP=SHR,DSN=[YOURID].P00695.VSAMRRDS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
REPRO OUTFILE(VSAM) INFILE(INREC)
/*
//INREC DD *
XXXXXXX060ALISONALISONALISONALISONALISONALISONALISONALISONAL ISONALIS
XXXXXXX060ALISONALISONALISONALISONALISONALISONALISONALISONAL ISONALIS
/*
In the IBM docs linked in the question (page 126: FILE-CONTROL paragraph) it is said that the relative access mode is only available for VSAM files :
Problem: the input file is currently not a VSAM file.
Solution: make the input file a VSAM file.
This worked:
DD card in the JCL when creating the input file:
//FOO DD DISP=(NEW,CATLG,DELETE),
// SPACE=(TRK,(1000,1000),RLSE),
// LRECL=300,
// RECORG=RR,
// DSN=MY.DATASET.NAME
The RECORG parameter makes the dataset an RRDS. The lines don't have an easily defined key, so I couldn't use a KSDS and I need the random access, so no ESDS either.
DD card for reading the dataset:
//BAR DD DISP=SHR,DSN=MY.DATASET.NAME
And then in the COBOL program (in FILE-CONTROL):
SELECT INPUT-FILE
ASSIGN TO BAR
ORGANIZATION IS RELATIVE
ACCESS MODE IS DYNAMIC
RELATIVE KEY IS INPUT-FILE-KEY
FILE STATUS IS INPUT-FILE-STATUS
.
If you want to open a sequential dataset for read, you need to open it for Input (done!), have it in the JCL with DISP=SHR (you could try with OLD, but don't need it), and have ACCESS IS SEQUENTIAL.
ACCESS IS RELATIVE as noted by other users is for VSAM only, and your IDCAMS output shows that this is not a VSAM file. If it's just a sequential dataset, you don't need a key either.

How to know from within a Fortran code if a file is opened by any program (Windows 7)

I have a Fortran code that updates in real time the content of a text file by adding some new real time measuraments at the very bottom of it. This text file is used (reading only) both by a fluid dynamics code (that continuously runs in real time) and by another executable built from matlab code (that performs plotting). I want to add a line in the Fortran code that says: update the text file ONLY IF it is not opened by any other program. I tried using INQUIRE:
do
INQUIRE(FILE = filename,OPENED = ISopen)
if (.not.ISopen) then
ADD NEW MEASUREMENTS HERE
exit
endif
endif
enddo
and before running this fortran program I opened the file with textpad. However, the variable ISopen is false. So I guess maybe INQUIRE only works for testing if file is opened within the fortran program itself. In fact if I add at the beginning of the above snippet of code:
OPEN (33,FILE = filename)
then ISopen is true. I then created an executable from a fortran code containing only:
OPEN (33,FILE = filename)
pause
CLOSE(33)
and I run it and let it in a paused status. I then run the first code I posted above and ISopen is still false. Any idea how to test if a file is open by any other program from within Fortran? My operative system is windows 7.
thanks
At the end I solved in this way. I could not find a way to know if the file is opened, and even if there was a way it could still happen that some other program opens it right between the time I check if its open and then I modify it. Therefore, I just create a temporary copy of the file to modify, I modify this temporary copy and then I move the file back by overwriting the original one. The latter operation is performed only if the file is not locked (i.e. no other program opened the file to read the data), so I keep trying to copy it until it succeeds. I tested in many situations and it works. The code is:
USE IFPORT
IMPLICIT NONE
character*256 :: DOScall
logical :: keepTRYING
integer :: resul
DOScall = 'copy D:\myfile.txt D:\myfile_TMP.txt' !create temporary copy
resul = SYSTEM(DOScall)
open(15,file ='D:\myfile_TMP.txt',form = 'formatted')
!.... perform here some writing operations on myfile_TMP........
close(15)
do
resul = SYSTEM('move D:\myfile_TMP.txt D:\myfile.txt')
if (resul==0) then
exit
else
pause(10)
endif
enddo
Note that works perfectly fine for multiple programs performing reading and one program writing in the file (as in my case where I have 2 programs reading and only one writing). If multiple programs write the same file I guess some other parallel techniques have to be used.
I do not think it is possible to check if a file is opened by an external process. Some programming languages allow you to check if the file is locked or not, and that is still far from telling you if the file is opened or not, both program must acquire and release system lock for it to really work. To my knowledge, the standard fortran does not have that feature directly, but you can use the semaphore from C with the interoperability stuff.
Most user application (editors mostly) however, before updating a file, usually check if the content on the disk has changed since they capture a copy, and alert the user. They also do that if they lost and acquire the focus. If you restrict your goal to updating only if the content has not changed since you opened it, you can do the same or simply open-add and close any time you want to add a new entry. A good editor will notify the user on the other side that the content had been change by another process.
An alternative is to simulate a lock yourself and buffer the data in fortran. By buffering I mean, collect some new data (let say 100, 1000 or whatever number that is convenient) and send them to the file at once. For each update, you open, update and close the file.
Your lock can be made of two simple files (emptys one for example), one created by the reader (matlab) and the other created by writer (fortran program). Let name them reading.ongoing for the reader and writing.ongoing for the writer.
On the fortran side, you do the following anytime you have collected enough data to write:
check for the existence of reading.ongoing (using inquire function), proceed only if it does not exist
create writing.ongoing
check for the existence of reading.ongoing again, if it exists, delete writing.ongoing and go back to step 1. If it does not exist, proceed forward.
open, write the data and close the data file
delete writing.ongoing
On matlab side, do similar thing, inverting the role of reading.ongoing and writing.ongoing.
In an exceptional race condition you could be blocked because they are all trying at the same time. In that case, you could modify the step 1. of matlab to force it to wait for few millisecond before proceeding. This will get you on the road as long as none of the program get killed between step 1 and 5.
You can also use semaphore with the interoperability stuff in fortran. See the following post for example. You can also similar think on the side of matlab, I do not have any example. That will lower your headhache and let the system manage the lock for you.

open extend in COBOL not working

I'm trying to write a subprogram in COBOL to make a logfile called from my main program. I don't want the logfile is cleared every time I call the subprogram so I use 'open extend'. The problem is because of an unknown reason it won't work, the program does nothing. When i change 'open extend' into 'open output' it works but I don't want the file is overwritten every time.
IDENTIFICATION DIVISION.
PROGRAM-ID. LOGGER.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT LOGFILE ASSIGN TO "LOGFILE.txt"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD LOGFILE.
copy "FDLOGGER.cpy".
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 LOGFILEBOODSCHAP PIC X(150) value spaces.
Procedure division USING LOGFILEBOODSCHAP.
pgm.
open EXTEND LOGFILE
Move Current-time to TIJD
Move Current-date to DATUM
Move LOGFILEBOODSCHAP to BOODSCHAP
write logrecord
close LOGFILE
exit program
.
Well, it's a guess, as you have not provided much, but if "LOGFILE.txt" does not exist, you will need OPTIONAL on your SELECT.
Suggest you put FILE STATUS checking in your code.
I know your question is very old here. But I was still having the same problem today and after a few hours I discover that GnuCOBOL 2.0 with OpenCobolIDE 4.7.6 that I am using generates error 35 when trying to use OPEN EXTEND. I solved it in a not very elegant way, but it works perfectly. I am sharing the solution I found.
IDENTIFICATION DIVISION.
PROGRAM-ID. CREATFIL.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION ALL INTRINSIC.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FD-VIRTUAL ASSIGN TO "CADFILE.TXT"
ORGANIZATION IS LINE SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS WS-GET-ERROR.
DATA DIVISION.
FILE SECTION.
FD FD-VIRTUAL.
01 FS-BOOK.
05 NOME PIC X(40).
WORKING-STORAGE SECTION.
77 WS-GET-ERROR PIC XX.
LOCAL-STORAGE SECTION.
01 TB-VIRTUAL.
05 TB-BOOK.
10 LS-NOME PIC X(40).
77 LS-ENTER PIC X.
77 WS-RESP PIC A VALUE "Y".
PROCEDURE DIVISION.
OPEN EXTEND FD-VIRTUAL.
IF WS-GET-ERROR = "35"
OPEN OUTPUT FD-VIRTUAL
END-IF
IF WS-GET-ERROR = "00"
PERFORM UNTIL UPPER-CASE(WS-RESP) NOT = "Y"
DISPLAY X"0D"
DISPLAY "Name: " WITH NO ADVANCING
ACCEPT LS-NOME
WRITE FS-BOOK FROM TB-BOOK
DISPLAY "More record (Y) for YES " WITH NO ADVANCING
DISPLAY "- any key for NOT: "
WITH NO ADVANCING
ACCEPT WS-RESP
IF UPPER-CASE(WS-RESP) NOT = "Y"
EXIT PERFORM
END-IF
END-PERFORM
END-IF.
CLOSE FD-VIRTUAL.
DISPLAY X"0D".
DISPLAY "Press <ENTER> to finish... " WITH NO ADVANCING.
ACCEPT LS-ENTER.
STOP RUN.
END PROGRAM CREATFIL.
Observe the instruction
OPEN EXTEND FD-VIRTUAL.
IF WS-GET-ERROR = "35"
OPEN OUTPUT FD-VIRTUAL
END-IF

Linux ANSI C simultaneous access to files and locking

I am writing Linux ANSI C cgi-bin server program with simultaneous access to files.
Is it possible to distinguish between file existence and file locking?
I can't find the answer with Google.
I'd like to write a program which tries to open file for a few seconds if fd<0
(thinking that the file is locked for a while).
But if the file does not exist it's fd also <0. So the program will waste time waiting.
Suppose a few threads try to append to the same file with no locking.
One tries to add "AAAA", another - "BBBB".
Can the result file be like "AABBAABB"?
Or it will always be like AAAABBBB or BBBBAAAA?
Or the result is unpredictable?
Am assuming IEEE Std 1003.1-2001 might defer to the ISO C standard...
In case the fopen fails i.e. fd < 0 then the system sets some error codes...
you can check those error codes. In case of file non-existent, the returned error would be
ENOENT
A component of filename does not name an existing file or filename is an empty string.
For more reference visit:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html
For point 2: I have been doing logging of certain data in my system by more than 100 processes writing to single file simultaneously but have never seen a merger of records(file is always opened in append mode). i.e. its always like AAAABBBB

AS 400- Sequential File not getting written. No error in the status. COBOL 400

I'm declaring a sequential file :
SELECT F-MYFILE ASSIGN DATABASE-MYFILE
ORGANIZATION SEQUENTIAL
ACCESS SEQUENTIAL
STATUS WW-STS-MYFILE.
In my COBOL program I am opening it as:
OPEN extend F-MYFILE
IF WW-STS-MYFILE NOT="00"
GO TO FINISH
END-IF
INITIALIZE MYFILE
MOVE "abcd" TO CONTENT OF MYFILE
WRITE MYFILE.
While I am writing the record the file is not showing any error in the status WW-STS-MYFILE, its '00'.
But still the record is not getting written.
Could you please tell the possible reason for the same.
Thanks
I'm not that familiar with AS/400 as I'm a z/OS developer, but the rule of thumb I've followed is that you read a file, but you write a record. if MYFILE is the filename and not a record layout for that file, then you are trying to write a file instead of a record for that file.
Does your program CLOSE the file? Is the file under commitment control? If you're using commitment control, and you haven't done a COMMIT or a CLOSE, the record(s) will be rolled back automatically when the program ends.
If you try to view the file while the program is still running, before it CLOSEs the file, it may be a file buffering issue.

Resources