[Info-vax] Looking for documentation for programming with symlinks
Mark Berryman
mark at theberrymans.com
Sun Nov 10 22:51:38 EST 2019
On 11/9/19 6:55 PM, John E. Malmberg wrote:
> On 11/9/2019 10:41 AM, John Reagan wrote:
>> On Friday, November 8, 2019 at 7:34:50 PM UTC-5, John E. Malmberg wrote:
>>> On 11/8/2019 10:13 AM, John Reagan wrote:
>>>> On Friday, November 8, 2019 at 9:04:57 AM UTC-5, John E. Malmberg
>>>> wrote:
>>>>> Hello,
>>>>>
>>>>> I am looking for documentation on programming symlinks using system
>>>>> services.
>>>>>
>>>>> Particularly the usages of:
>>>>>
>>>>> ATR$C_SYMLINK
>>>>> ATR$S_SYMLINK
>>>>>
>>>>> FAB$C_SYMLINK
>>>>> FAB$C_SYMBOLIC_LINK
>>>>>
>>>>> naml$v_symlink_in_path
>>>>> naml$v_object_symlink
>>>>>
>>>>> I think I can figure most of it out by looking at the header files
>>>>> generated by SDL.
>>>>>
>>>>> Regards,
>>>>> -John
>>>>> wb8tyw at qsl.net_work
>>>>
>>>> The ATR$ symbols are the F11XQP file attribute for a symlink. The
>>>> FAB$ ones are for creating/accessing a symlink. For the NAML$ bits,
>>>> I searched ALL the listings on a full Itanium build disk and found no
>>>> uses of SYMLNK_IN_PATH at all. For OBJECT_SYMLINK, I found one place
>>>> in the CRTL that looks at it, but I found zero places that set it.
>>>
>>> While something in the CRTL has to check if a file is a symlink for the
>>> difference in stat or lstat.
>>>
>>> In my case I need to check if the file is a symlink, and if it is, I
>>> have to check to see if the symlink is to a directory.
>>>
>>> I am already using sys$parse and sys$search to see if the file or link
>>> exists, so I am trying to get the additional information as efficiently
>>> as possible.
>>>
>>> Regards,
>>> -John
>>
>> Well, from POSIX, you'd call lstat() on the file and check the
>> returned mode in the stat buffer to see if S_IFLNK. That's what most of
>> the ACRTL does and what any other program should do.
>
> I may need to run some more tests on lstat() Currently I am showing in
> my tests:
>
> $ create sys$disk:[]test."
> $ create/symlink="./test" sys$disk:[]^9test.
>
> The CRTL lstat("^9test") is returning st_mode as 100000 instead of
> 120000 as expected if my test logic is correct.
>
> I am getting the expected st_mode of 120000 for symlinks to directories.
>
>> If you want the VMS behind-the-scenes approach (and what the CRTL
>> uses at the bottom), open a channel, use a $QIO to get the IO$_ACCESS
>> file characteristics longword (you'll need a FIB and an attribute
>> list asking for ATR$C_RECATTR) and look at
>>
>> 8 67497 /*
>> 8 67498 ** Check for a
>> symbolic link file
>> 8 67499 */
>> 8 67500 if (
>> (recattr.fat$v_fileorg == FAT$C_SPECIAL) &&
>> 8 67501
>> (recattr.fat$b_special_type == FAT$C_SYMBOLIC_LINK) )
>>
>
> I already have a $search() FAB/NAML structures, so I was hoping that I
> could just get the information there.
If you already have a fab from a $search, do a $open, the
characteristics will be filled in. If that is all you need, you can try
doing a minimalist open by setting the fab$v_ufo and fab$v_upi flags and
see if the necessary characteristics are still filled in.
If you need to know what filename the symlink points to, connect a RAB
and do a $read. Here is a snippet of code I have been using with great
success as a replacement for CRTL readlink call:
int rms_readlink(char *link, char *target, size_t target_len)
{
.
.
.
fab.fab$v_bio = 1; //block I/O
fab.fab$v_get = 1; //perform a GET
naml.naml$v_open_special = 1; //do not follow symlinks
naml.naml$v_no_short_upcase = 1; //maintain ODS-5 case
status = SYS$OPEN(&fab); //open the file
if (!$VMS_STATUS_SUCCESS(status)) {
decc$$translate(status);
return -1;
}
if ((fab.fab$b_org != FAB$C_SPECIAL) || (fab.fab$b_rat !=
FAB$C_SYMBOLIC_LINK)) {
SYS$CLOSE(&fab); //not a symlink
errno = EINVAL;
return -1;
}
rab.rab$l_fab = &fab;
rab.rab$w_usz = target_len;
rab.rab$l_ubf = target;
status = SYS$CONNECT(&rab);
if ($VMS_STATUS_SUCCESS(status)) status = SYS$READ(&rab);
SYS$CLOSE(&fab);
if (!$VMS_STATUS_SUCCESS(status)) {
decc$$translate(status);
return -1;
}
target[rab.rab$w_rsz] = 0;
return rab.rab$w_rsz;
}
More information about the Info-vax
mailing list