1

As part of a Cobol program I'm modifying, stat function needs to be called to retrieve the details of a file. This is in Linux 7.6. But when I run the program, I get the error

Load error : file 'stat' error code: 173, pc=C6, call=1, seg=0 173 Called program file not found in drive/directory

If I use stat on a file from command line, it works and the details are retrieved. I don't understand why the call to stat fails from cobol.

I checked for stat in .so files in /usr/lib. Could find stat in libc_nonshared.a

Also tried to change the call from stat to stat64 after changing the stat structure. stat64 also throws the same error.

Did anyone else faced this issue. Any pointers to move forward will be of great help.

       R0001.
          DISPLAY 'Program STARTED'
          ACCEPT WS-FILENAME2 FROM COMMAND-LINE
          MOVE 00025  TO FCD-NAME-LENGTH
          MOVE x'00'                 TO WS-FILENAME2(FCD-NAME-LENGTH:1)
          DISPLAY 'FILENAME : ' WS-FILENAME2
          CALL 'stat' USING WS-FILENAME2
                            ST-BUF
               RETURNING WS-RETURN-CODE.
          DISPLAY 'STAT CALL COMPLETE'
          DISPLAY 'RETURN CODE: ' WS-RETURN-CODE
          IF WS-RETURN-CODE NOT = ZERO
             SET GNIO-RC-ERR-DATEXT TO TRUE
             GO TO R0099
          END-IF.
          DISPLAY 'DEVICE VALUE : ' ST-DEV-LINUX
          DISPLAY 'INODE VALUE  : ' ST-INO64-LINUX
          DISPLAY 'ATIME        : ' ST-ATIME-LINUX
          DISPLAY 'CTIME        : ' ST-CTIME-LINUX
          DISPLAY 'MTIME        : ' ST-MTIME-LINUX
          DISPLAY 'SIZE64       : ' ST-SIZE64-LINUX
          DISPLAY 'BLOCKS64     : ' ST-BLOCKS64-LINUX.
       R0099.
          EXIT.
          STOP RUN.

Load error : file 'stat' error code: 173, pc=C6, call=1, seg=0 173 Called program file not found in drive/directory

  • Try to use the full path, e.g. `/usr/bin/stat`. –  Aug 06 '19 at 13:01
  • Still the same error Load error : file '/usr/bin/stat' error code: 253, pc=C6, call=1, seg=0 253 Cannot load file - unsupported format – Sanyo Alexis Aug 06 '19 at 13:08
  • What does `type stat` say from the command-line? –  Aug 06 '19 at 13:09
  • Actually not the same error. Earlier it was "file not found in directory". Now on using /usr/bin/stat, the error is "Unsupported format" as shown above – Sanyo Alexis Aug 06 '19 at 13:16
  • Try to run your COBOL environment like this: `LD_LIBRARY_PATH=$COBDIR/lib:$LD_LIBRARY_PATH; export $LD_LIBRARY_PATH `. –  Aug 06 '19 at 13:16
  • stat is hashed (/usr/bin/stat) This is what type stat shows – Sanyo Alexis Aug 06 '19 at 13:17
  • You best should set LD_LIBRARY_PATH (like I commented above) in your ~/.bashrc. That way your environment is set up ok. In other words, add: LD_LIBRARY_PATH=$COBDIR/lib:$LD_LIBRARY_PATH; export $LD_LIBRARY_PATH to your .bashrc. After doing that, for the current session, then just re-source .bashrc: `source ~/.bashrc`. –  Aug 06 '19 at 13:19
  • exported LD_LIBRARY_PATH. Now value is /opt/microfocus/VisualCOBOL/lib:/opt/microfocus/VisualCOBOL/lib:/opt/microfocus/VisualCOBOL/lib::/usr/local/lib:/lib. Unfortunately, same error comes up after compiling & running the program again – Sanyo Alexis Aug 06 '19 at 13:21
  • Is this open-cobol? –  Aug 06 '19 at 13:22
  • For other systems, to do the equivalent of the LD_LIBRARY_PATH setting, ref. to here: https://community.microfocus.com/t5/Net-Express-Server-Express/173-Called-program-not-found-in-directory/ta-p/1735904 (please carefully note they unwisely precede the different examples with a dash; the dash is NOT part of the setting). –  Aug 06 '19 at 13:26
  • This is visual cobol. Checked the link you gave and this being Linux, library path should be set like you mentioned. Edited the .bashrc and sourced it. But still the same. I don't understand why stat works in command line and not in cobol – Sanyo Alexis Aug 06 '19 at 13:39
  • It must be some environment setting. Please make sure that when you do `echo $LD_LIBRARY_PATH` from the command line it prints the setting like you cited earlier. Other than that, check and double check your environment settings for VC. –  Aug 06 '19 at 13:52
  • Where did the additional `:/usr/local/lib:/lib` in your LD_LIBRARY_PATH come from? Try to add `:/lib64` to it as well. Basically, when you do `ldd /usr/bin/stat`, your program (stat) needs to be able to access all the directories mentioned there. –  Aug 06 '19 at 14:24
  • There is no "Linux 7.6". You may want to replace that with the name of the distribution you use... – Murphy Aug 06 '19 at 15:43
  • 1
    The `stat` command (called from the command line) and the `stat` function are completely different things! – Simon Sobisch Aug 06 '19 at 21:06
  • As you want to call a C system function I highly suggest to use static linking. To do so define an appropriate call-convention in special-names like `CALL-CONVENTION 8 IS STATIC` and then do `CALL STATIC 'stat' ...`. If this works (can't check and the documentation is only minimal) then I'll recreate this as an answer. – Simon Sobisch Aug 06 '19 at 21:18
  • If I add CALL-CONVENTION 8 IS STATIC I get the compilation errors. 15 DECIMAL-POINT IS COMMA. * 71-S***************** ** ** PROCEDURE DIVISION missing or unknown statement 17 INPUT-OUTPUT SECTION. * 82-S************ ** ** COBOL Division or Section header encountered in incorrect order 18 FILE-CONTROL – Sanyo Alexis Aug 07 '19 at 13:43
  • Couldn't find any help in microfcus documentation on this. – Sanyo Alexis Aug 07 '19 at 13:44
  • Tried this - created another cobol program with just the stat call. Compiled it into an executable. Called this program from my original program. Now the error is different..............."Cannot load file - unsupported format", not "Called program file not found in drive/directory" – Sanyo Alexis Aug 07 '19 at 14:05
  • I suggest editing your question to show what you've tried (at least the static call-convention part), enable others to review this for possible issues, too (and to not recommend the same you've already tried - not everyone reads question-comments [especially when there are so much] before posting an answer). – Simon Sobisch Aug 12 '19 at 11:59

2 Answers2

1

I was able to get this to run but only after first piecing together the structure in COBOL and. after forcing a static call, linking in the system lib's when compiling.

Here's what I have from a program named callstat2:

   01 ST-STRUCT.
      05  ST-DEV-LINUX             PIC 9(9) COMP-5.
      05                           PIC X(4).
      05  ST-INO64-LINUX           PIC 9(9) COMP-5.
      05                           pic x(4).
      05  ST-NLINK                 PIC 9(9) COMP-5.
      05                           PIC X(4).
      05  ST-MODE                  PIC 9(9) COMP-5.
      05  ST-UID                   PIC 9(9) COMP-5.
      05  ST-GUID                  PIC 9(9) COMP-5.
      05                           PIC X(4).
      05  ST-RDEV-LINUX            PIC 9(9) COMP-5.
      05                           PIC X(4).
      05  ST-SIZE                  PIC 9(9) COMP-5.
      05                           PIC X(4).
      05  ST-BLOCKSIZE-LINUX       PIC 9(9) COMP-5.
      05                           PIC X(4).
      05  ST-BLOCKS                PIC 9(9) COMP-5.
      05                           PIC X(4).
      05  ST-ATIME-LINUX           PIC 9(10) COMP-5.
      05                           PIC 9(10) COMP-5.
      05  ST-MTIME-LINUX           PIC 9(10) COMP-5.
      05                           PIC 9(10) COMP-5.
      05  ST-CTIME-LINUX           PIC 9(10) COMP-5.


      CALL STATIC 'stat' USING WS-FILENAME2
                               ST-STRUCT 
                     RETURNING WS-RETURN-CODE
      END-CALL

Compile with the -L switch.

cobc -x  callstat2.cob -L/usr/lib/x86_64-linux-gnu

PS. callstat1 worked as well but it uses C module wrappers to make the system calls to stat and ctime.

Jim Castro
  • 864
  • 5
  • 10
  • That is GnuCOBOL, not MicroFocus ;-) I *guess* it is similar (other than the likely need to define the `CALL-CONVENTION` in `SPECIAL-NAMES`), but I don't know. – Simon Sobisch Aug 12 '19 at 11:57
0

On my machine, the stat symbol is not present, alternative exists.

I suspect it is because the 'C' headers use macro's to redirect it to another symbol.

     $ readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep " stat"   
 286: 000000000010ca10   108 FUNC    WEAK   DEFAULT   14 statvfs64@@GLIBC_2.2.5
 644: 000000000010ca10   108 FUNC    WEAK   DEFAULT   14 statvfs@@GLIBC_2.2.5
 870: 000000000010c6a0   486 FUNC    GLOBAL DEFAULT   14 statx@@GLIBC_2.28
1719: 000000000010c9b0    33 FUNC    WEAK   DEFAULT   14 statfs@@GLIBC_2.2.5
1930: 000000000010c9b0    33 FUNC    WEAK   DEFAULT   14 statfs64@@GLIBC_2.2.5


     $ readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep " printf"
 633: 0000000000062830   197 FUNC    GLOBAL DEFAULT   14 printf@@GLIBC_2.2.5
1578: 0000000000062750    28 FUNC    GLOBAL DEFAULT   14 printf_size_info@@GLIBC_2.2.5
2008: 0000000000061c90  2745 FUNC    GLOBAL DEFAULT   14 printf_size@@GLIBC_2.2.5
Stephen Gennard
  • 1,910
  • 16
  • 21