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.