- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - OpenVMS
- >
- Re: lstat and case-sensitivity
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Discussions
Discussions
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-24-2016 03:57 PM
03-24-2016 03:57 PM
Re: lstat and case-sensitivity
> LIB$INITIALIZE is in SYS$COMMON:[SYSLIB]STARLET.OLB, which the linker
> processes by default.
Not much use if you're trying to supply your own.
> You may want to show the full link command and the
> exact linker message.
No argument there. As I recall, C++ tends to use/hijack
LIB$INITIALIZE for its own purposes, so, to use it with C++, you need to
create a separate shared image with your own LIB$INITIALIZE, and ask the
linker to get yours, too. But, as I said, I've never done it. A Forum
or Web search (for: C++ LIB$INITIALIZE) might find some details. If you
actually care.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-24-2016 04:43 PM - edited 03-24-2016 04:47 PM
03-24-2016 04:43 PM - edited 03-24-2016 04:47 PM
Re: lstat and case-sensitivity
..>> LIB$INITIALIZE is in SYS$COMMON:[SYSLIB]STARLET.OLB, which the linker
>> processes by default.
>Not much use if you're trying to supply your own.
Your own what? The OP said, "undefined lib$initialize". Which may be a real linker message or not. If that undefined symbol is LIB$INITIALIZE, it is defined in SYS$COMMON:[SYSLIB]STARLET.OLB. You can not have your own symbol LIB$INITIALIZE to get the image initialization done. You have to have your own PSECT LIB$INITIALIZE merged into the pre-fabricated wrappers from the object module LIB$INITIALIZE, which is part of STARLET.OLB.
Edit: Actually, you don't need the symbol LIB$INITIALIZE at all. You only need to include the object module LIB$INITIALIZE.
> ... As I recall, C++ tends to use/hijack
> LIB$INITIALIZE for its own purposes, so, to use it with C++, you need to
> create a separate shared image with your own LIB$INITIALIZE, and ask the
> linker to get yours, too. But, as I said, I've never done it. A Forum
> or Web search (for: C++ LIB$INITIALIZE) might find some details. If you
> actually care.
I wouldn't say hijack. C++ and its RTL (on I64 if I remember correctly) uses the LIB$INITIALIZE mechanism as well. To get your own image initialization done before the RTL's shareable image ones, you have to have a shareable image with your init code which the image activator activates before the C++ RTL. The image activator followes the list of shareable images as the linker sets it up. That is, your link command has to ensure that your (init code in your) shareable image is "in front of" the C++ RTL's one.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-25-2016 06:28 AM
03-25-2016 06:28 AM
Re: lstat and case-sensitivity
As others have correctly noted, this utterly non-modular and nonsensical and ill-considered "design" of the C run-time library means either defining the logical names ahead of image invocation, or — if you want to use the API — invoking the feature set calls in the initialization PSECT, ahead of the main() call. (The main() call invokes the C library initialization code, and which is also why you see that "type GO to get to the start of the main program" in the debugger. )
This scheme all makes sense if you know how the OpenVMS image initialization actually works, but pragmaticallt it's a design that's user-hostile and non-modular at best, and some of the alternative user interfaces possible here could have made this vastly easiler and better.
(If you've inferred that I might not be a proponent of this "design", you probably don't know the half of what I think about this particular and fetid heap of vomitus. This was a Bad Idea when it was built, and the imbroglio has only increased as settings accreted. But I digress.)
When logging bug reports, posting full details and a reproducer really helps — saves folks from guessing what has happened — and it requires less effort on the part of those that might help you to get to the answer that you want and need. Attaching a zip here can work nicely too, as that can contain the entirety of the reproducer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-27-2016 12:50 PM
03-27-2016 12:50 PM
Re: lstat and case-sensitivity
OK. First I would like to point out what behavior I see with lstat (this is simple nothing do with case-sensitivity, something I just stumbled upon).
this is cpp program using lstat() and printing ctime, atime, mtime.
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <errno.h>
#include <unixlib.h>
using namespace std;
int
main(int argc, char** argv)
{
string sFilePath;
cout << "Enter Path: ";
cin >> sFilePath;
struct stat st;
int iRet(0);
if((iRet = lstat(sFilePath.c_str(), &st)) < 0)
{
cerr << "lstat(" << sFilePath << ") failed, error=" << strerror(errno) << endl;
exit(-1);
}
cout << "ctime: " << asctime(localtime(&st.st_ctime));
cout << "mtime: " << asctime(localtime(&st.st_mtime));
cout << "atime: " << asctime(localtime(&st.st_atime));
exit(0);
}
this is the result using this program.
$ test_stat
Enter Path: dka0:[ssq]out.txt;2
ctime: Tue May 15 17:31:22 2012
mtime: Tue May 15 17:32:52 2012
atime: Tue May 15 17:32:52 2012
and this is dir /full result on the same file
$ dir /full dka0:[ssq]out.txt;2
Directory DKA0:[SSQ]
OUT.TXT;2 File ID: (19005,4,0)
Size: 2/32 Owner: [SYSTEM]
Created: 15-MAY-2012 17:31:22.29
Revised: 15-MAY-2012 17:32:52.87 (1)
Expires: 10-MAR-2017 14:07:20.31
Backup: <No backup recorded>
Effective: <None specified>
Recording: <None specified>
Accessed: 15-MAY-2012 17:31:22.29
Attributes: 15-MAY-2012 17:32:52.87
Modified: 15-MAY-2012 17:31:22.29
Linkcount: 1
File organization: Sequential
Shelved state: Online
Caching attribute: Writethrough
File attributes: Allocation: 32, Extend: 0, Global buffer count: 0
Version limit: 3
Record format: VFC, 2 byte header, maximum 0 bytes, longest 107 bytes
Record attributes: Print file carriage control
RMS attributes: None
Journaling enabled: None
File protection: System:RWED, Owner:RWED, Group:RE, World:
Access Cntrl List: (IDENTIFIER=[150,*],ACCESS=READ)
Client attributes: None
Total of 1 file, 2/32 blocks.
$
so this is the lstat() bug that I talked about.
Second. I dont really need DEC$ARGV_PARSE_STYLE but I need DEC$EFS_CASE_PRESERVE instead, I think, to instruct lstat() to treat filename case-sensitively.
So this is the lstat() program (same above program silghtly changed) for case-sensitivity test.
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <errno.h>
#include <unixlib.h>
using namespace std;
#define ENABLE TRUE
#define DISABLE 0
static int set_feature_default(const char *name, int value)
{
int index = decc$feature_get_index(name);;
if (index > 0)
index = decc$feature_set_value (index, 0, value);
return index;
}
static void show_feature_default(const char* name)
{
int index = decc$feature_get_index(name);
if(index > 0)
{
int value = decc$feature_get_value(index, 0);
cout << name << " has value " << value << endl;
}
}
int
main(int argc, char** argv)
{
string sFilePath;
cout << "Enter Path: ";
cin >> sFilePath;
int iCaseSensitive(0);
int prev_value = set_feature_default("DECC$EFS_CASE_PRESERVE", ENABLE);
if(0 != prev_value)
cerr << "Failed to set DECC$EFS_CASE_PRESERVE," << " errno=" << strerror(errno) << endl;
show_feature_default("DECC$EFS_CASE_PRESERVE");
struct stat st;
int iRet(0);
if((iRet = lstat(sFilePath.c_str(), &st)) < 0)
{
cerr << "lstat(" << sFilePath << ") failed, error=" << strerror(errno) << endl;
exit(-1);
}
cout << "ctime: " << asctime(localtime(&st.st_ctime));
cout << "mtime: " << asctime(localtime(&st.st_mtime));
cout << "atime: " << asctime(localtime(&st.st_atime));
exit(0);
}
dir listing on the directory.
$ dir dka0:[ssq]
Directory DKA0:[SSQ]
OUT.SAV;1 out.t;1 OUT.TXT;3 OUT.TXT;2
OUT.TXT;1 out.txt;4 out.txt;3 out.txt;2
OUT_ORIG.SAV;1 out_rest.sav;1 OUT_RESTORE.TXT;1 RESTORE.TXT;1
TESTIDX.ISM;1 This_file^_is_not_OK.txt;1
This_file^%is_not_OK.txt;1 This_file^+is_not_OK.txt;1
This_file^.is_OK.txt;1 This_file^=is_not_OK.txt;1
Total of 18 files.
$
note above, only out.txt;4 exits but both out.txt;2 and OUT.TXT;2 exist. Now trying this program
$ test_stat
Enter Path: dka0:[ssq]out.txt;4
DECC$EFS_CASE_PRESERVE has value 1
lstat(dka0:[ssq]out.txt;4) failed, error=no such file or directory
$ test_stat
Enter Path: dka0:[ssq]out.txt;2
DECC$EFS_CASE_PRESERVE has value 1
ctime: Tue May 15 17:31:22 2012
mtime: Tue May 15 17:32:52 2012
atime: Tue May 15 17:32:52 2012
$ test_stat
Enter Path: dka0:[ssq]OUT.TXT;2
DECC$EFS_CASE_PRESERVE has value 1
ctime: Tue May 15 17:31:22 2012
mtime: Tue May 15 17:32:52 2012
atime: Tue May 15 17:32:52 2012
$
Also note that these are on IA64, we dont have Alpha or VAX.
Rationale on why I am doing this - In my program (the real bigger one), I have a vital place where I need to do a lstat() on a file to grab some attributes (I am primarily a UNIX programmer making some code transition to OpenVMS, hence UNIX C-api come handy to me always). This is where it came to my notice that lstat() always fails when the volume has case-sensitivity enabled and there is a file with lower case only. Also, to note, that a subsequent sys$open() on the same full actually works.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-27-2016 12:56 PM
03-27-2016 12:56 PM
Re: lstat and case-sensitivity
this is the full link command
$ CXXLINK/exe=test_stat.exe test_stat.obj,SYS$SHARE:STARLET.OLB
%ILINK-E-INVLDHDR, invalid ELF header; field 'ehdr$b_ei_mag0' has invalid value %X09
module: <unassigned>
file: SYS$COMMON:[SYSLIB]STARLET.OLB;1
%ILINK-W-NUDFSYMS, 1 undefined symbol:
%ILINK-I-UDFSYM, int lib$initialize()
%ILINK-W-USEUNDEF, undefined symbol int lib$initialize() referenced
source code name: "lib$initialize()"
section: .sdata
offset: %X0000000000000010
module: TEST_STAT
file: DNFS1:[cxunix.source.CommClient.ClProxyConnAPI.Client.backup]TEST_STAT.OBJ;32
the highlighted line is what I am curious about.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-27-2016 02:18 PM - edited 03-27-2016 02:23 PM
03-27-2016 02:18 PM - edited 03-27-2016 02:23 PM
Re: lstat and case-sensitivity
> $ CXXLINK/exe=test_stat.exe test_stat.obj,SYS$SHARE:STARLET.OLB
> %ILINK-E-INVLDHDR, invalid ELF header; field 'ehdr$b_ei_mag0' has invalid value %X09
Without any qualifier, the linker expects object files as arguments. STARLET.OLB is an object library. If you want to resolve from a library, you need to add the /LIBRARY qualifier to the object library. However, as already mentioned, this object library is already processed, by default. You may end up with "%ILINK-W-MULDEF" warning messages.
On the other hand, you are using CXXLINK, which does some postprocessing on the VMS linker output: something like "%ILINK-I-UDFSYM, LIB$INITIALIZE__XV" is converted to "%ILINK-I-UDFSYM, int lib$initialize()" - these examples are taken from Alpha, so the mangled name on I64 may be slightly different.. The linker resolves mangled names, CXXLINK hides these names and shows the demangled names. Essentially you have an unresolved symbol like "LIB$INITIALIZE__XV", which is not defined in any object module in STARLET.OLB, as the wanted, real name in that library and its module is "LIB$INITIALIZE." In other words, you need to wrap the "extern int lib$initialize();" with `extern "C" { ... }.'
For many VMS programmers, referencing the symbol LIB$INITIALIZE is just more convenient - as STARLET.OLB is searched by default for that symbol, than explicitly including the needed object module with a linker command string like "SYS$SHARE:STARLET/LIB/INCL=LIB$INITIALIZE".
- « Previous
-
- 1
- 2
- Next »