On 11/07/2008, at 12:52 AM, CRPence wrote:
I agree with you that both of those, the *LIB and the database
*FILE,
are native OS/400 object types. I think what you are missing, is the
probability that the code was written something like the following
[not
to imply that I know; I do not]:
dcl is_dir int init 0
dcl is_lnk int init 0
dcl is_ntv int init 0
dcl is_sck int init 0
...
select
when object_is_container() then is_dir = 1;
when object_is_socket() then is_sck = 1;
when object_is_lnk() then is_lnk = 1;
otherwise do;
... if ... is_ntv = 1; ...
end;
end select;
Implication being that probably, once the code determines that the
object is capable of drill-down, being an effective /directory/, the
IsNative likely just remains unset, due to how it was coded.
It's more fundamental than that. The stat() function populates a
structure. One of the sub-fields is st_mode which is a mode_t which
is an unsigned integer. Each bit in the 4-byte integer is either
reserved or has meaning. The left-most 15 bits (i.e., 0-14 in IBM's
bit numbering scheme) are reserved (or not used). The next 5 bits
(15-19) indicate the type of object (note that only bits 16-19 are
used on most (all?) Unix variants). Bits 20 and 21 indicate UID and
GID set. Bit 22 appears reserved. Finally bits 23-31 are permission
bits indicating RWX for each of User (i.e, owner), Group, and Other
(i.e., public).
There are 8 (7 on Unix) object types represented by the 5 type bits:
Regular file
Directory
Character special file
Block special file
FIFO (or pipe)
Symbolic link
Socket
Native object (OS/400 only)
There are a bunch of C macros in sys/stat.h that provide a means of
testing these bits. They are used as follows:
if (S_ISDIR(ifsInfo.st_mode) )
These macros are all of the form where the supplied st_mode is
bitwise-ANDed with a mask to extract the type bits which are then
compared with constants containing the expected bit pattern for that
type. Thus S_ISDIR becomes:
if ( ( ifsInfo.st_mode & 0370000 ) == 0040000 )
NOTE: That this is C so literal numbers beginning with 0 are in
Octal. Converting to hexadecimal makes the bit pattern of types more
obvious:
S_IFFIFO 0010000 0x1000
S_IFCHR 0020000 0x2000
S_IFDIR 0040000 0x4000
S_IFBLK 0060000 0x6000
S_IFREG 0100000 0x8000
S_IFLNK 0120000 0xA000
S_IFSOCK 0140000 0xC000
S_IFNATIVE 0200000 0x10000
Most of these use a single bit to indicate the type but some (BLK,
LNK and SOCK) use 2 bits.
So although most code that uses these macros presumes they are
exclusive and is written like:
if (S_ISREG(buf.st_mode)) ptr = "regular";
else if (S_ISDIR(buf.st_mode)) ptr = "directory";
else if (S_ISCHR(buf.st_mode)) ptr = "character special";
else if (S_ISBLK(buf.st_mode)) ptr = "block special";
else if (S_ISFIFO(buf.st_mode)) ptr = "fifo";
#ifdef S_ISLNK
else if (S_ISLNK(buf.st_mode)) ptr = "symbolic link";
#endif
#ifdef S_ISSOCK
else if (S_ISSOCK(buf.st_mode)) ptr = "socket";
#endif
#ifdef S_ISNATIVE
else if (S_ISNATIVE(buf.st_mode)) ptr = "OS/400 object";
#endif
else ptr = "** unknown mode **";
printf("type %s\n", ptr);
There is nothing in the use of these bits that precludes having more
than one type evaluate to true (except possibly precedence on other
platforms i.e., they are presumed to be unique).
For *LIB and *FILE the S_IFDIR bit is set, for *MBR the S_IFREG bit
is set and none of the three have the S_IFNATIVE bit set. The only
objects that have the S_IFNATIVE bit set are things that are not
*DIR, *STMF, *DDIR, *DSTMF, *LIB, *FILE, or *MBR objects.
Oh ... having written all that I see what you mean. The OS code that
determines which bits to set also presumes a single unique bit
pattern i.e., a given object can only ever be of one type thus it
only sets one pattern.
Hmm, short-sighted design. Oh well, I'll leave this in the archives--
someone else may find it helpful.
However I
doubt even if anyone in development agreed, they'd probably just say
/working as designed/ even though more likely it is /working as
coded/;
or at least state that it is too dangerous to change because someone
[the OS itself, being most notable] may have coded to that anomalous
outcome, irrespective of how illogical. No harm in trying :-)
I'll open this as a documentation issue because the description of
S_ISNATIVE should be more explicit about which OS objects will not be
considered "native".
I can't see this being changed to work as is should (rather than as
it does) simply because Rochester would need to change the
definitions of the various S_ISxxxxx macros to allow for the
S_IFNATIVE bit being set in addition to the S_IFDIR or S_IFREG bits.
Easy enough to change by resetting the OS/400 bit mask of 0370000
(x'1F0000') back to the Unix S_IFMT value of 0170000 (x'F0000') to
ignore the S_IFNATIVE bit on all macros except S_ISNATIVE. However,
because Cs idea of a macro is simply code substitution, lots of
existing code will contain an incorrect bit mask and corresponding
test and thus will break when such a change is implemented.
I'll just have to code around it by testing the st_objtype for the
three anomalous object types.
Regards,
Simon Coulter.
--------------------------------------------------------------------
FlyByNight Software OS/400, i5/OS Technical Specialists
http://www.flybynight.com.au/
Phone: +61 2 6657 8251 Mobile: +61 0411 091 400 /"\
Fax: +61 2 6657 8251 \ /
X
ASCII Ribbon campaign against HTML E-Mail / \
--------------------------------------------------------------------
As an Amazon Associate we earn from qualifying purchases.