IBM COBOL on AIX file access - file

We are migrating a bunch of COBOL programs from z/OS to AIX 7. We are using the IBM COBOL Compiler (5.1) on AIX. Now I don't understand how the file access and the file system work for COBOL on AIX.
The COBOL code is straight forward with
SELECT :FILE: ASSIGN TO :FILE:
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
STATUS IS S-STATUS.
and then doing an OPEN INPUT
This compiled fine on AIX:
PP 5724-Z87 IBM COBOL for AIX 5.1.0 in progress ...
LineID Message code Message text
91 IGYGR1216-I A "RECORDING MODE" of "F" was assumed for file
"CUSTOMERS".
94 IGYGR1216-I A "RECORDING MODE" of "F" was assumed for file
"LIST1".
97 IGYGR1216-I A "RECORDING MODE" of "F" was assumed for file "UINPUT".
Messages Total Informational Warning Error Severe Terminating
Printed: 3 3
End of compilation 1, program xxxxx, highest severity: Informational.
Now the problem is, that when running the program the file is not found. It gives Status code: 37
I know that I have to provide a file system for the file on the shell (ksh), as such:
export CUSTOMERS="STL-CUSTOMERS". The file is in the same directory as the program.
My question is this: Which file system to use? I tried "STL" which seemed to me like the "standard" AIX file system (which is JFS2). But that doesn't work. The other option are (from the COBOL on AIX Programming Guide 5.1):
DB2
SdU (SMARTdata Utilities)
SFS (Encina Structured File Server)
STL (standard language)
QSAM (queued sequential access method)
RSD (record sequential delimited)
We tried all and the file system that worked was "QSAM". The file is a text file (ASCII), that was transfered from the mainframe. But not directly, it was first copied by FTP and then converted to ASCII on Windows (we had to fix the line breaks). When playing around with it to make it work, we edited the file with vi to make the lines 80 characters each. So it was edited on AIX and looks like a ordinary text file on AIX.
Why would COBOL still want QSAM as "file system"? What does the term "file system" mean here any way? It seems that it is not in the sense of a real file system such as JFS.

I can see where this would be confusing... Especially coming from a Non-POSIX environment.
I'll start with the answer, and then provide more information.
For a normal text file, you want RSD, and to make sure that the \n is column 81.
A record length of 80 is just the data portion, not including the delimiter.
QSAM (fixed length) would appear to work, but would return the \n as part of the data!
Your FS=37 means that the attributes of the file don't match what the program is asking for (more esoteric than, say, FS=39 - invalid fixed attributes). In this case, it means the file you wanted to open was not, really, a STL file.
By filesystem we mean how the data is physically stored on the platter, SSD, RAM, ... More accurately, how we format the record before handing it off to the next lower level of I/O.
There are two basic types of filesystems:
Native (on top of JFS2, JFS, NFS, CIFS, ...) RSD, QSAM, LSQ, STL, SdU. These filesystems can be operated on by standard OS utilities
Non-Native (on top of another product) DB2 (DB2) and SFS (TxSeries/CICS). These filesystems are invisible to standard OS utilities
Then, there are groupings by type of COBOL organization (preferred):
Sequential: All filesystems support Sequential...z/OS: QSAM, VSAM
Relative: STL, SdU, SFS, DB2...........z/OS: VSAM
Indexed: STL, SdU, SFS, DB2...........z/OS: VSAM
Of the Native filesystems, QSAM(variable), STL and SDU contain metadata, making them not really viewable in vi,cat,... Ok... you can open them in vi, but it will look like utter garbage.
QSAM is a faithful implementation of z/OS:
Fixed length records: Raw data, no BDW/RDW, no line delimiters (\n).
Variable length records: RDW + raw data (no \n)... However there is no BDW.
RSD is a normal stream (text) file; each record is terminated with \n, which is not counted in the record length (the program will never see them).
LSQ (Line Sequential) is the same as on z/OS - messy semantics.
VSAM is an alias for a filesystem that provides all the features of z/OS VSAM.
Unfortunately, for historical reasons, it points to SdU...
STL is, by far and away, better at everything than is SdU.
SdU was the first filesystem to cover QSAM and VSAM, but is old and decrepit, compared to STL.

Related

Renaming & moving my file based on the size is not always working in c. Why?

I have an application, written in C, which generates various data parameters that I am logging into a text file named debug_log.txt. Whenever this log file reaches 1 MB, I am renaming the filename with timestamp ex debug_log_20200106_133000.txt & moving it in same directory. I am then reopening debug_log.txt to log new parameters.
if(stat("/home/log/debug_log.txt", &statFiledbg) == 0)
{
if(statFiledbg.st_size >= 1048576) // 1MB
{
current_time = time(0);
strftime(time_buffer, sizeof(time_buffer), "%Y%m%d_%H-%M-%S", gmtime(&current_time));
sprintf(strSysCmddbg, "mv /home/log/debug_log.txt /home/log/debug_log%s.txt", time_buffer);
system(strSysCmddbg);
fp_dbglog = freopen("/home/log/debug_log.txt", "w", fp_dbglog);
}
}
The code works most of the time until it doesn't. After running the application for couple days, I see that debug_log.txt grows beyond 1 MB while the last moved & renamed log file is empty.
What could be the reason?
Use the rename function from the C standard library (in stdio.h) and check errno if it failed to know the exact reason why it is failing.
When working with files, and I/O in general, there are many, many things that can go wrong.
One of my senior developer in the company told me so. Is there anything wrong with using system()?
Yes: it is unnecessary (C and POSIX provide you with a function for basic usages like this), nonportable (it assumes you are in a system that has a "mv"), slower (it needs to spawn another process) and wrong for many use cases (eg. here there is no way to know what exactly failed unless you save the textual output of mv).
See questions and answers like Moving a file on Linux in C for an in-depth explanation.

How to get display devices name in Linux

I'd like to find linux analogs of EnumDisplayDevices and EnumDisplaySettingsEx WinAPI functions.
The info I need to get is display name and state (if it active or not), width, height, bits per pixel and frequency.
How can I get this info using C (C++)?
Thanks.
As mentioned by 'Some programmer dude' in the comments you can have to go through the X window system. Most specifically one option would be the RandR protocol. Here is the protocol specification as well as the source code of the command xrandr that invokes the XRR functions and outputs most of the info that you want on the terminal. Look for the place where the
XRRScreenResources *res
is populated and then how the modes are fetched from it using the find_mode() function.
other commands that might assist you and don't go over the RandR extensions could be xprop(1), xdpyinfo(1), xwininfo(1)
Some programmer dude and ramrunner are absolutely correct. For most Linux systems, the graphical "desktop" is based on X Windows. Command-line tools for querying your X "display" include xrandr and xdpyinfo. The C-language source code for both are freely available; you can find many example programs with a Google search.
... HOWEVER ...
X Windows is "client/server". Your Linux "desktop" need not be on your physical PC; your X "display" could just as easily be a Windows desktop. In this case - xrandr and xdpyinfo are still applicable: they refer to where you're displaying (e.g. an XMing client on Windows), and not the physical host Linux is running on.
If you want to query the graphics devicews on your physical server ... then you'll instead use commands like lshw -c display or get-edid

File Config, creation and usage in C unix

I'm trying to understand how I can create a ".config" file containing a bunch of parameters to later use to set up the variables in my C project on Unix.
I created my ".config" file using sudo nano test.config and wrote some stuff inside such as:
#N is this
N 10
#p is that
p 0.002
#T is this
T 10
Now that I did that how can I read its content and use it to initialize my variables?
The several answers to this question explain how to parse that config file, but you could use standard parsing techniques (perhaps your own recursive descent parser) or Glib's lexical scanning or key-value pair parser (or use something else). You certainly should define and document (perhaps using EBNF) what is the format of that textual configuration file (and what the various entries there represent: for example, if that configuration file refers to other files, how do you handle spaces in such file paths, etc....). A common (but not universal) convention is to consider as comments so skip any line starting with #.
Another question is how to get that config file while running in an arbitrary working directory. You just need to build the absolute path of your file (for fopen(3) or open(2)), e.g. with
char configpath[100];
snprintf(configpath, sizeof(configpath), "%s/.test.config", getenv("HOME"));
You could test before that getenv("HOME") is not NULL, but in practice that is very unlikely; see environ(7) and getenv(3); and the case when it gives a very long file path is also unlikely; you might test that snprintf(3) returns a count less than sizeof(configpath) or use asprintf(3).
You might use other functions, e.g. glob(3) or wordexp(3) to get that file path (but you probably should stick to snprintf or asprintf with getenv("HOME")...).
You might consider instead embedding some scriptable interpreter like lua or guile in your program (but that is a strong architectural design decision). Then the configuration file becomes some (Turing-complete!) script.
BTW, there is no need to use sudo to edit that configuration file (under your home directory), and you might decide to also read some system-wide configuration under /etc/

Default extension for message catalog files

I want to localize my application using the catopen()/catgets() family of functions.
As far as I understand, in the absence of NLSPATH variable, message catalogs will be looked up under /usr/share/locale/xx_YY/LC_MESSAGES.
What is the "traditional" file extension for message catalog files? I see some code examples using *.cat while others don't use any extension at all. Is it dependent on a particular UNIX flavour?
On my Linux boxes I see plenty of *.mo files, but those are GNU gettext archives. It seems catgets() can rarely be seen "in the wild" nowadays.
I meant this to be a comment, but it's a bit too long :P
Looking at the doc you've linked to, it seems probably that the code isn't opinionated as to file extension. Since you're not using MIME or anything to automatically find a handler for this file, the only requirement is likely to be that the name is correct. In UNIX, especially in the shell, file extensions often mean nothing to the system - fo example, any file extension can be used on an executable script as long as the executable bit is set and the shebang line at the top of the file specifies an appropriate interpreter.
It's possible the user community, if one still exists for this crufty sounding library, has a standard naming convention that the docs don't describe - but I wouldn't sweat it too much. It's trival to change file names, even if it means a recompile ( command line variables would make the program agnostic as to file name and extension )

Powerflex Database File extensions

I am trying to understand the different file extensions for the pfxplus powerflex database. Could someone please help telling me briefly what each file is for?
.k1
.k2
.k3
...
.k13
.k14
.k15
.fd
.def
.hdr
.prc
.pc3
Data files:
OK, so .dat is the data file.
.k1 -> .k15 are index files.
These are the critical data files for runtime. (Combined with filelist.cfg or pffiles.tab similar to define what files are available overall).
.fd is the file definition, needed for compiling programs
.tag (which you did not mention) is needed only if you need to access field names at run time (such as using a generic report tool)
.def is the file definition in human readable form, and is not needed by any process but is produced so a programmer or user can understand the file structure.
Run time:
The .ptc files are the compiled threads interpreted by the powerflex runtime.
The .prc file is a resource file that is used at runtime in conjunction with the .ptc file - it defines how a character based program is to look in a gui environment in "g-mode". It was the cheap way to upgrade character based programs when windows first started getting popular usage.
.hdr and .pc3 escape me at the moment, but are vaguely familiar - .hdr is probably another data file used with compression or special field types for later versions of pfxplus. .pc3 may in fact be the .ptc files...

Resources