Operating System - OpenVMS
1748154 Members
3585 Online
108758 Solutions
New Discussion

Re: File locked after using SYS$OPEN and SYS$CLOSE

 
SOLVED
Go to solution
Dennis Piepel
Advisor

File locked after using SYS$OPEN and SYS$CLOSE

I was trying to write a program to show a selected list of files with the file creation date and then allow the user to open and read a selected file.  I used SYS$OPEN and got the FAB and XABDAT info I needed and then did a SYS$CLOSE.  However, when I try to open one of the files, they all are currently opened and locked!

What system service call or option do I need to use to release the file lock so that I can open the file from my BASIC application program?

8 REPLIES 8
Hoff
Honored Contributor

Re: File locked after using SYS$OPEN and SYS$CLOSE

When you close an OpenVMS file using $close, the file is closed, and all locks are released.  There are no dangling locks.   For all its problems and its baroque API, RMS calls are expressly synchronous, unless you have explicitly specified otherwise.  

 

The $open and $close calls are two of the most heavily used calls in all of VMS and in most every OpenVMS application that runs on VMS.  While bugs are possible, your BASIC code is the immediate suspect.

 

It is likely that the BASIC code contains an error.  Likely around the close, of course.  Ensure that the error status values are uniformly checked, and use the debugger to take a look at the flow of the program execution.

 

If you want to pursue this here, please post the VMS version information, the BASIC version information, and the source code of a (preferably concise) reproducer. 

 

GuentherF
Trusted Contributor

Re: File locked after using SYS$OPEN and SYS$CLOSE

The file is open by a process. Use "$ SHOW DEVICE/FILE disk:" to find the process ID (PID) of the process which has this file listed.

/Guenther
Dennis Piepel
Advisor

Re: File locked after using SYS$OPEN and SYS$CLOSE

OK, I think I figured it out.
If I setup a USEROPEN function to get the FAB and XABDAT attributes then I can read the file from my BASIC program normally and still get the file attributes that I needed!
Hoff
Honored Contributor

Re: File locked after using SYS$OPEN and SYS$CLOSE

So you were opening an already-open file, probably from the same application?  (And FWIW, that lock will blocks the subsequent $open calls, and not the $close.)  To resolve that, set file sharing on the first open, and Bob's your uncle.  (This is also the general technique used to allow logs to be visible, while being written.)

Dennis Piepel
Advisor

Re: File locked after using SYS$OPEN and SYS$CLOSE

No, I did not already have the file open. 

Following is the FILE_INFO function I was trying to use.

AFTER calling that function and trying to do an OPEN command in a BASIC program is when I got the File is locked error.

 

       FUNCTION LONG FILE_INFO(        ! Get File information: &
                         STRING myFile  ! RMS file to open &
                        ,FABDEF myFab   ! Returns initialized FAB &
                        )
        OPTION TYPE=EXPLICIT

 

        %INCLUDE "SCS$LB:FILE_INFO.INC" ! COMMON variables to set

 

        %INCLUDE "$SSDEF"   %FROM %LIBRARY
        %INCLUDE "$RMSDEF"  %FROM %LIBRARY
        %INCLUDE "$FABDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET"
        %INCLUDE "$RABDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET"
        %INCLUDE "$XABDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB"
        %INCLUDE "$XABDATDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB"

        RECORD XABDAT
            VARIANT
            CASE
                XABDEF XXAB ! Shared part for COD, BLN, SPARE AND NXT
            CASE
                XABDATDEF XXABDAT ! specific part
            END VARIANT
        END RECORD XABDAT

        DECLARE XABDAT XAB_DAT

        EXTERNAL LONG FUNCTION  SYS$OPEN        &
        ,                       SYS$CONNECT     &
        ,                       SYS$CLOSE

        EXTERNAL INTEGER FUNCTION STR$ANALYZE_SDESC(STRING,WORD,LONG)

        DECLARE LONG    STATUS_L        ! return status &
        ,               XABFHC_L        ! XAB file header characteristic &

        ! Setup FAB block...
        myFab::fab$b_bid = FAB$C_BID    ! initialize FAB for open
        myFab::fab$b_bln = FAB$C_BLN
        myFab::fab$l_fop = FAB$M_UFO
        myFab::fab$b_fac = FAB$M_GET OR FAB$M_PUT
        myFab::fab$b_shr = FAB$M_UPI &
                        OR FAB$M_SHRGET &
                        OR FAB$M_SHRPUT &
                        OR FAB$M_SHRUPD &
                        OR FAB$M_SHRDEL
        myFab::fab$b_fns = STR$ANALYZE_SDESC(myFile,0%,myFab::FAB$L_FNA)

        ! Setup XAB block...
        XABFHC_L = myFab::FAB$L_XAB
        myFab::FAB$L_XAB = LOC(XAB_DAT) ! Me first, me first
        !
        XAB_DAT::XAB$B_COD = XAB$C_DAT ! Make it real
        XAB_DAT::XAB$B_BLN = XAB$C_DATLEN
        XAB_DAT::XAB$L_NXT = XABFHC_L

 

         ! Open the file...
        STATUS_L=SYS$OPEN(myFab,,)
        EXIT FUNCTION (STATUS_L) UNLESS (STATUS_L and 1%)

        ! Set CMN_FILE_INFO common block variables to return to main program...
        FILE__ORG = myFab::FAB$B_ORG
        FILE__RAT = myFab::FAB$B_RAT
        FILE__MRS = myFab::FAB$W_MRS
        FILE__ALQ = myFab::FAB$L_ALQ
        FILE__RFM = myFab::FAB$B_RFM
        !
        myFab::FAB$L_XAB = XABFHC_L
        CALL SYS$ASCTIM(0% BY VALUE, FILE__CDT, XAB_DAT::XAB$Q_CDT, 0%)

        STATUS_L=SYS$CLOSE(myFab,,)
        EXIT FUNCTION (STATUS_L) UNLESS (STATUS_L and 1%)

 

Hein van den Heuvel
Honored Contributor

Re: File locked after using SYS$OPEN and SYS$CLOSE

Right, you can hook up an XABDAT in the useropen, before the call to open and it will be filled in.

BASIC already hooks up an XABFHC and XABSUM, so if you needed those you would want to find them, not add them.

Basic uses a static FAB, FHC and SUM, but dynamic XABKEY, which are freed when done.

While an XABDAT is a 'safe' addition today, as a matter of principle you still want to keep

the XAB chain clean, no duplicates, and return as found.

To hook up that XABDAT I would put it as first XAB, and restore when done

 

XABDAT::XAB$L_NXT = FAB::FAB$L_XAB

FAB::FAB$L_XAB = LOC ( XABDAT ) 

:

stat = SYS$OPEN...

:

FAB::FAB$L_XAB = XABDAT::XAB$L_NXT

 

The original program must have failed the close. Did you check the return status?

As Hoff indicates, $CLOSE works. Period. 

As Guenther indicates, SHOW DEV/FILE can show who still has it open.

Having CMKRNL privs I prefer ANALYZE/SYSTEM ... SET PROC... SHOW PROC /CHAN, SHOW PROC/RMS=FAB

 

Finally see below for a working BASIC calling SYS$OPEN (Not close :-) example using XABDAT.

 

Cheers,

Hein

 

 1      OPTION TYPE = EXPLICIT, CONSTANT TYPE = INTEGER
 !
 !      Get_file_dates.bas       Hein van den Heuvel, Feb-2007
 !
        On error go to hell!

        EXTERNAL LONG FUNCTION  SYS$OPEN(FABDEF), LIB$GET_FOREIGN(STRING,STRING)
        EXTERNAL LONG CONSTANT  RMS$_NORMAL
       %INCLUDE "$FABDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB"
       %INCLUDE "$RABDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB"
       %INCLUDE "$XABDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB"
       %INCLUDE "$XABDATDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB"

        DECLARE STRING  FILE_NAME, TXT
        DECLARE INTEGER STAT, DATE_OFFSET, DATE_POINTER
        MAP (RMS_BLOCKS) XABDATDEF XABDAT, RABDEF RAB, FABDEF FAB, &
                         STRING DATE_TIME = 23, NAME_BUFFER = 80
        MAP (RMS_BLOCKS) XABDEF XAB ! Yuck

        STAT = LIB$GET_FOREIGN (FILE_NAME, 'File name: ')

        NAME_BUFFER = FILE_NAME         !Move into static string for LOC().
        FAB::FAB$B_BID = FAB$C_BID      !Make this a real FAB
        FAB::FAB$B_BLN = FAB$C_BLN      !Make this a real FAB
        FAB::FAB$L_FNA = LOC(NAME_BUFFER)       !Put Address of name_buf in Fab
        FAB::FAB$B_FNS = LEN(FILE_NAME) !Put Lenght of file_name in Fab
        FAB::FAB$B_FAC = FAB$M_GET      !READ access
        FAB::FAB$B_SHR = FAB$M_UPI      !No locking what so ever needed
        RAB::RAB$L_FAB = LOC(FAB)       !Put Address of Fab in Rab
        FAB::FAB$L_XAB = LOC(XAB)       !Put Address of Xab in Fab
        XAB::XAB$B_COD = XAB$C_DAT      !Make this a DAT XAB
        XAB::XAB$B_BLN = XAB$C_DATLEN   !Make this a DAT XAB

        STAT = SYS$OPEN(FAB)    !Open the file
                CALL sys$exit(STAT BY VALUE) IF STAT <> RMS$_NORMAL

 ! Like to get OFFSETs, rather than fiels for the dates. Cheat:
 ! $ pipe libr/out=sys$output:/extr=$xab*def -
 !     SYS$LIBRARY:STARLET.mlb | search sys$pipe: t_overlay

        DATA 12,"RDT",20,"CDT",28,"EDT",36,"BDT",0
        READ DATE_OFFSET
        WHILE (DATE_OFFSET)
             DATE_POINTER = LOC(XABDAT) + DATE_OFFSET
             CALL sys$asctim (0 BY VALUE, DATE_TIME, &
                 DATE_POINTER BY VALUE, 0 BY VALUE)
             READ TXT
             PRINT TXT, DATE_TIME
             READ DATE_OFFSET
       NEXT
       GOTO 2

 HELL:  PRINT ERT$(ERR) UNLESS ERR = 11
        RESUME 2
 2       END

 

 

 

 

 

 

Hein van den Heuvel
Honored Contributor

Re: File locked after using SYS$OPEN and SYS$CLOSE

Ah... your reply 'snuck' in.

 

I see you already know the 'hook me up first and clean up later method. good.


Here is the problem:   myFab::fab$l_fop = FAB$M_UFO

 

That tells RMS NOT to open the file as usual, but only to assign a channel.

 

You can not $CLOSE but must use SYS$DASSGN passing FAB$L_STV (which has the channel after open)

 

The CLOSE would have failed with status = 99684  (%x18564)

--> %RMS-F-IFI, invalid internal file identifier (IFI) value

You may want to check your error handling if that was not reported.


Also, you should drop the  OR FAB$M_PUT unless you want to make sure you do have write access.

Adding that access, will cause the revision date and number to be changed on close. 

Is that what you wanted?

 

Cheers,

 

Hein



 

 

Dennis Piepel
Advisor
Solution

Re: File locked after using SYS$OPEN and SYS$CLOSE

Thanks Hein.

You are correct.  I was getting the RMS-F-IFI error and just did not check for it.

I removed the problem line with the FAB$L_FOP and then the SYS$CLOSE worked.

I also removed the OR FAB$M_PUT because it was not needed in a function whose only purpose

was to get file attributes.