#include <Qp0lstdi.h> int Qp0lSetAttr (Qlg_Path_Name_T *Path_Name, char *Buffer_ptr, uint Buffer_Size, uint Follow_Symlnk, ...);
The Qp0lSetAttr() function sets one of a set of defined attributes, on each call, for the object that is referred to by the input *Path_Name. The object must exist, the user must have authority to it, and the attribute must be supported by the file system to which the object belongs. When an attribute is not supported by the file system, Qp0lSetAttr() will fail with ENOTSUP. See the Usage Notes for more information.
If the last component of the Path_Name parameter is a symbolic link, the Qp0lSetAttr() either sets the attribute of the symbolic link or sets the attribute of the object that the symbolic link names. This depends on the value of the Follow_Symlnk parameter.
All times that are set by Qp0lSetAttr() are in seconds since the Epoch so that they are consistent with UNIX-type APIs. The Epoch is the time 0 hours, 0 minutes, 0 seconds, January 1, 1970, Coordinated Universal Time. If the system date is set prior to 1970, all time values will be zero.
The following table describes the format of the entry in the buffer.
Buffer Pointer | |||
---|---|---|---|
Offset | Type | Field | |
Dec | Hex | ||
0 | 0 | BINARY(4) | Offset to next attribute entry |
4 | 4 | BINARY(4) | Attribute identification |
8 | 8 | BINARY(4) | Size of attribute data |
12 | C | CHAR(4) | Reserved |
16 | 10 | CHAR(*) | Attribute data |
Attribute data. The value to which the attribute is set.
Attribute identification. The constant identifying the attribute being set. Valid values are:
4 | QP0L_ATTR_CREATE_TIME: (UNSIGNED (BINARY(4)) The time the object was created. | |||||||||||
5 | QP0L_ATTR_ACCESS_TIME: (UNSIGNED (BINARY(4)) The time the object's data was last accessed. | |||||||||||
7 | QP0L_ATTR_MODIFY_TIME: (UNSIGNED (BINARY(4)) The time the object's data was last changed. | |||||||||||
17 | QP0L_ATTR_PC_READ_ONLY: (CHAR(1)) Whether the
object can be written to or deleted, have its extended attributes changed or
deleted, or have its size changed. Valid values are:
|
|||||||||||
18 | QP0L_ATTR_PC_HIDDEN: (CHAR(1)) Whether the object
can be displayed using an ordinary directory listing.
|
|||||||||||
19 | QP0L_ATTR_PC_SYSTEM: (CHAR(1)) Whether the object
is a system file and is excluded from normal directory searches.
|
|||||||||||
20 | QP0L_ATTR_PC_ARCHIVE: (CHAR(1)) Whether the
object has changed since the last time the file was saved or reset by a PC
client.
|
|||||||||||
21 | QP0L_ATTR_SYSTEM_ARCHIVE: (CHAR(1)) Whether the
object has changed and needs to be saved. It is set on when an object's change
time is updated, and set off when the object has been saved.
|
|||||||||||
22 | QP0L_ATTR_CODEPAGE: (BINARY(4)) The code page used to derive a coded character set identifier (CCSID) used for the data in the file or the extended attributes of the directory. | |||||||||||
26 | QP0L_ATTR_ALWCKPWRT: (CHAR(1)) Whether a stream
file (*STMF) can be shared with readers and writers during the
save-while-active checkpoint processing. Setting this attribute may cause
unexpected results.
See the Back up your server
topic for details on this attribute.
|
|||||||||||
27 | QP0L_ATTR_CCSID: (BINARY(4)) The CCSID of the
data and extended attributes of the object. |
|||||||||||
31 | QP0L_ATTR_DISK_STG_OPT (CHAR(1)) Which option
should be used to determine how auxiliary storage is allocated by the system
for the specified object. The option will take effect immediately and be part
of the next auxiliary storage allocation for the object. This option can only
be specified for byte stream files in the "root" (/), QOpenSys and user-defined
file systems. This option will be ignored for *TYPE1 byte stream files. Valid
values are:
|
|||||||||||
32 | QP0L_ATTR_MAIN_STG_OPT: (CHAR(1)) Which option
should be used to determine how main storage is allocated and used by the
system for the specified object. The option will take effect the next time the
specified object is opened. This option can only be specified for byte stream
files in the "root" (/), QOpenSys and user-defined file systems. Valid values
are:
|
|||||||||||
35 | QP0L_ATTR_CRTOBJSCAN: (CHAR(1)) Whether the
objects created in a directory will be scanned when exit programs are
registered with any of the integrated file system scan-related exit points.
The integrated file system scan-related exit points are:
This attribute can only be specified for directories in the "root" (/), QOpenSys and user-defined file systems. Even though this attribute can be set for *TYPE1 and *TYPE2 directories, only objects which are in *TYPE2 directories will actually be scanned, no matter what value is set for this attribute. Valid values are:
|
|||||||||||
36 | QP0L_ATTR_SCAN: (CHAR(1)) Whether the object
will be scanned when exit programs are registered with any of the integrated
file system scan-related exit points.
The integrated file system scan-related exit points are:
This attribute can only be specified for stream files in the "root" (/), QOpenSys and user-defined file systems that are not virtual volumes or network server storage spaces. Even though this attribute can be set for objects in *TYPE1 and *TYPE2 directories, only objects which are in *TYPE2 directories will actually be scanned, no matter what value is set for this attribute. Valid values are:
|
|||||||||||
38 | QP0L_ATTR_ALWSAV: (CHAR(1)) Whether the object
can be saved or not.
Note: It is highly recommended that this attribute not be changed for any system created objects. Valid values are:
|
|||||||||||
39 | QP0L_ATTR_RSTDRNMUNL: (CHAR(1))
Restricted renames and unlinks for objects within a directory. Objects can be linked into
a directory that has this attribute set on, but cannot be renamed or unlinked from it
unless one or more of the following are true for the user performing the operation:
|
|||||||||||
41 | QP0L_ATTR_CRTOBJAUD: (CHAR(10)) The create object auditing value
associated with the directory. This is the auditing value given to any objects
created in the directory.
This attribute can only be specified for directories
in the "root" (/), QOpenSys, QSYS.LIB, independent ASP QSYS.LIB,
QFileSvr.400 and user-defined file systems.
Valid values are:
|
|||||||||||
200 | QP0L_ATTR_RESET_DATE: (UNSIGNED (BINARY(2)) The
count of the number of days an object has been used. Usage has different
meanings according to the file system and according to the individual object
types supported within a file system. Usage can indicate the opening or closing
of a file or can refer to adding links, renaming, restoring, or checking out an
object. The usage information format is defined in the Qp0lstdi.h header file
as data type Qp0l_Usage_t and is shown in the following table. This attribute
can be set to zero only. An attempt to set to any other value will result in
errno [EINVAL].
When this attribute is set, the date use count reset for the object is set to the current date. |
|||||||||||
300 | QP0L_ATTR_SUID: (CHAR(1)) Set effective user ID
(UID) at execution time. This value is ignored if the specified object is a
directory. Valid values are:
|
|||||||||||
301 | QP0L_ATTR_SGID: (CHAR(1)) Set effective group ID
(GID) at execution time. Valid values are:
|
Offset to next attribute entry. (Output) This field is not used by the Qp0lSetAttr() function. It is provided for alignment so that the same buffer format returned from the Qp0lGetAttr() function can be used as input to the Qp0lSetAttr() function.
Reserved. A reserved field. This field must be set to binary zero.
Size of attribute data. The exact size of the data for this attribute. If this size does not match the size that the system stores for this attribute, [EINVAL] is returned.
0 | QP0L_DONOT_FOLLOW_SYMLNK: A symbolic link in the last component is not followed. Attributes of the symbolic link object are set. |
1 | QP0L_FOLLOW_SYMLNK: A symbolic link in the last component is followed. The attributes of the object contained in the symbolic link are set. |
Note: Adopted authority is not used.
Authorization Required for Qp0lSetAttr() (excluding QSYS.LIB, independent ASP QSYS.LIB, and QDLS) | ||
---|---|---|
Object Referred to | Authority Required | errno |
Each directory, preceding the last component, in the path name except when setting the QP0L_ATTR_CRTOBJAUD attribute. | *X | EACCES |
Object, when setting the QP0L_ATTR_RESET_DATE, QP0L_ATTR_ALWCKPWRT, QP0L_ATTR_ALWSAV, QP0L_ATTR_DISK_STG_OPT or QP0L_ATTR_MAIN_STG_OPT attribute | *OBJMGT | EACCES |
Object, when setting the QP0L_ATTR_CREATE_TIME, QP0L_ATTR_ACCESS_TIME, or QP0L_ATTR_MODIFY_TIME attribute to the current time | Owner or *W (See Note) | EACCES |
Object, when setting the QP0L_ATTR_RSTDRNMUNL, QP0L_ATTR_SUID, or QP0l_ATTR_SGID values | Owner (See Note) | EPERM |
Object, when setting the QP0L_ATTR_CREATE_TIME, QP0L_ATTR_ACCESS_TIME, or QP0L_ATTR_MODIFY_TIME attribute to a specific time | *W | EPERM |
User, when setting the QP0L_ATTR_CRTOBJSCAN or QP0L_ATTR_SCAN attribute | *ALLOBJ, *SECADM | EPERM |
User, when setting the QP0L_ATTR_CRTOBJAUD attribute | *AUDIT | EPERM |
Object, when setting any other attribute | *W | EACCES |
Note: If the file system supports *ALLOBJ special authority and if you have *ALLOBJ special authority, you do not need the listed object authority. |
Authorization Required for Qp0lSetAttr() in the QSYS.LIB and independent ASP QSYS.LIB File Systems | ||
---|---|---|
Object Referred to | Authority Required | errno |
Each directory, preceding the last component, in the path name except when setting the QP0L_ATTR_CRTOBJAUD attribute. | *X | EACCES |
Object, when setting the QP0L_ATTR_RESET_DATE attribute and the object type is *FILE | *OBJOPR and *OBJMGT | EACCES or EPERM |
Object, when setting the QP0L_ATTR_RESET_DATE attribute and the object is a database file member | *X and *OBJMGT | EACCES or EPERM |
Object, when setting the QP0L_ATTR_RESET_DATE attribute and the object is neither a *FILE object type nor a database file member | *OBJMGT | EACCES or EPERM |
User, when setting the QP0L_ATTR_CRTOBJAUD attribute | *AUDIT | EPERM |
Authorization Required for Qp0lSetAttr() in the QDLS File System | ||
---|---|---|
Object Referred to | Authority Required | errno |
Each directory, preceding the last component, in the path name | *X | EACCES |
Object, when setting the QP0L_ATTR_RESET_DATE attribute | *W, *OBJMGT (See Note) | EACCES |
Object, when setting any other attribute | *W (See Note) | EACCES |
Note: If you have *ALLOBJ special authority, you do not need the listed object authority. |
0 | The Qp0lSetAttr() API was successful. |
-1 | The Qp0lSetAttr() API was not successful. The errno global variable is set to indicate the error. |
If the Qp0lSetAttr() API is not successful, errno indicates one of the following errors:
Error condition | Additional information |
---|---|
[EACCES] |
If you are accessing a remote file through the Network File System, update operations to file permissions at the server are not reflected at the client until updates to data that is stored locally by the Network File System take place. (Several options on the Add Mounted File System (ADDMFS) command determine the time between refresh operations of local data.) Access to a remote file may also fail due to different mappings of user IDs (UID) or group IDs (GID) on the local and remote systems. |
[EAGAIN] | |
[EBADFID] | |
[EBADNAME] | |
[EBUSY] | |
[ECANCEL] | |
[ECONVERT] | |
[EDAMAGE] | |
[EFAULT] | |
[EINTR] | |
[EINVAL] | |
[EIO] | |
[EJRNDAMAGE] | |
[EJRNENTTOOLONG] | |
[EJRNINACTIVE] | |
[EJRNRCVSPC] | |
[ELOOP] | |
[ENAMETOOLONG] | |
[ENEWJRN] | |
[ENEWJRNRCV] | |
[ENOENT] | |
[ENOMEM] | |
[ENOSPC] | |
[ENOTAVAIL] | |
[ENOTDIR] | |
[ENOTSAFE] | |
[ENOTSUP] | |
[EOFFLINE] | |
[EPERM] | |
[EROOBJ] | |
[ESCANFAILURE] |
You have attempted to modify an object that has been marked as a scan failure due to processing by an exit program associated with the scan-related integrated file system exit points. |
[EUNKNOWN] |
Additionally, if interaction with a file server is required to access the object, errno could also indicate one of the following errors:
Error condition | Additional information |
---|---|
[EADDRNOTAVAIL] | |
[ECONNABORTED] | |
[ECONNREFUSED] | |
[ECONNRESET] | |
[EHOSTDOWN] | |
[EHOSTUNREACH] | |
[ENETDOWN] | |
[ENETRESET] | |
[ENETUNREACH] | |
[ESTALE] |
If you are accessing a remote file through the Network File System, the file may have been deleted at the server. |
[ETIMEDOUT] | |
[EUNATCH] |
The following messages may be sent from this function:
Message ID | Error Message Text |
---|---|
CPFA0D4 E | File system error occurred. Error number &1. |
CPF3CF2 E | Error(s) occurred during running of &1 API. |
CPF9872 E | Program or service program &1 in library &2 ended. Reason code &3. |
CPE3418 E | Possible APAR condition or hardware failure. |
The QP0L_ATTR_CREATE_TIME and QP0L_ATTR_RESET_DATE attributes are supported for objects of type *STMF only. Attempts to set them on other objects will result in the operation failing with errno set to [ENOTSUP].
The QP0L_ALWSAV_YES value cannot be specified for the QP0L_ATTR_ALWSAV attribute for /dev/null, /dev/zero or objects of type *SOCKET. Attempts to set it on these objects will result in the operation failing with errno set to [ENOTSUP].
The QP0L_ATTR_SGID attribute of the directory affects what the group ID (GID) is for objects that are created in the directory. If the QP0L_ATTR_SGID attribute of the parent directory is off, the group ID (GID) is set to the effective GID of the thread creating the object. If the QP0L_ATTR_SGID attribute of the parent directory is on, the group ID (GID) of the new object is set to the GID of the parent directory. For all other file systems, the GID of the new object is set to the GID of the parent directory.
When setting the QP0L_ATTR_RSTDRNMUNL, QP0L_ATTR_SUID, or QP0L_ATTR_SGID attributes on an object that has a primary group, it must match the primary group ID or one of the supplemental group IDs of the caller of this API; otherwise, the QP0L_ATTR_SGID attribute is set to QP0L_SGID_OFF.
The following attributes may be set on objects in these file systems:
When you set the QP0L_ATTR_RESET_DATE attribute of a database file, all members in that file will have their days used count reset to 0 also.
Attempting to set any other attribute other than QP0L_ATTR_SUID or QP0L_ATTR_SGID will result in the operation failing with errno set to [ENOTSUP].
QSYS.LIB and Independent ASP QSYS.LIB do not support setting the QP0L_ATTR_SUID or QP0L_ATTR_SGID attributes. They will be ignored if specified.
When you set the following attributes on objects in the Network File System, the operation will fail with the errno set to [ENOTSUP] if the attribute is not set to the following attribute value.
The QP0L_ATTR_CREATE_TIME, QP0L_ATTR_RESET_DATE, QP0L_ATTR_CODEPAGE, QP0L_ATTR_CCSID, QP0L_ATTR_ALWSAV, QP0L_ATTR_ALWCKPWRT, QP0L_ATTR_DISK_STG_OPT, QP0L_ATTR_MAIN_STG_OPT and QP0L_ATTR_CRTOBJAUD attributes cannot be set on objects within the Network File System or they will result in the operation failing with errno set to [ENOTSUP].
The NFS client supports the QP0L_ATTR_SUID, QP0L_ATTR_SGID, and QP0L_ATTR_RSTDRNMUNL attributes by passing them to the server over the network and surfacing them to the caller. Whether a particular network file system supports the setting of these attributes depends on the server. Most servers have the capability of masking off the QP0L_ATTR_SUID and QP0L_ATTR_SGID attributes if the NOSUID option is specified on the export. The default, however, is to support these attributes.
The QNetWare File System does not support setting the QP0L_ATTR_RSTDRNMUNL, QP0L_ATTR_SYSTEM_ARCHIVE, QP0L_ATTR_RESET_DATE, QP0L_ATTR_CRTOBJAUD attributes. If you set any attribute on a NetWare Directory Services (NDS) object, the operation will fail with errno set to [ENOTSUP].
QNetWare supports the QP0L_ATTR_SUID and QP0L_ATTR_SGID attributes by passing them to the server and surfacing them to the caller. Some versions of NetWare may support the attributes and others may not.
The following attributes may be set on objects in this file system:
Attempting to set any other than the QP0L_ATTR_SUID or QP0L_ATTR_SGID attributes will result in the operation failing with errno set to [ENOTSUP].
QDLS does not support setting the QP0L_ATTR_SUID or QP0L_ATTR_SGID attributes. They will be ignored if specified.
If you set the QP0L_ALWSAV_YES value for the QP0L_ATTR_ALWSAV attribute, the operation will fail with errno set to [ENOTSUP].
QOPT does not support setting the QP0L_ATTR_SUID, QP0L_ATTR_SGID, QP0L_ATTR_RSTDRNMUNL, or QP0L_ATTR_CRTOBJAUD attributes for any optical media format. If any attribute is specified, the operation will fail with errno set to [ENOTSUP].
QFileSvr.400 supports the QP0L_ATTR_SUID, QP0L_ATTR_SGID, and QP0L_ATTR_RSTDRNMUNL attributes by passing them to the server and surfacing them to the caller.
QFileSvr.400 does not support setting the QP0L_ATTR_ALWSAV attribute. The operation will fail if this attribute is specified.
QFileSvr.400 supports setting the QP0L_ATTR_CRTOBJAUD attribute. However, the QSECOFR user profiles on the source and target system must be enabled, and their passwords must match for the operation to succeed.
The following attributes may be set on objects in this file system:
Attempting to set any other than the QP0L_ATTR_SUID or QP0L_ATTR_SGID attributes will result in the operation failing with errno set to [ENOTSUP].
QNTC does not support setting the QP0L_ATTR_SUID or QP0L_ATTR_SGID attributes. They will be ignored if specified.
See Code disclaimer information for information pertaining to code examples.
The following is an example showing a call to the Qp0lSetAttr() and the Qp0lGetAttr() APIs.
/***************************************************************/ #include "Qp0lstdi.h" #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <sys/types.h> int GetAttrObject( Qlg_Path_Name_T *Pathname_ptr, char *Buffer_ptr, unsigned int Buffer_size) { /**************************************************************/ /* Local variables */ /**************************************************************/ struct attrStruct { Qp0l_AttrTypes_List_t attr_struct; uint AttrTypes[10]; }; struct attrStruct Attr_types_ptr; unsigned int buff_size_needed; unsigned int num_bytes_returned; unsigned int follow_sym; int rc; /**************************************************************/ /* Start of executable code */ /**************************************************************/ /**************************************************************/ /* Initialize Get Attributes Parameters */ /**************************************************************/ memset((void *)&Attr_types_ptr, 0x00,sizeof(struct attrStruct)); Attr_types_ptr.attr_struct.Number_Of_ReqAttrs = 3; Attr_types_ptr.AttrTypes[0] = QP0L_ATTR_PC_READ_ONLY; Attr_types_ptr.AttrTypes[1] = QP0L_ATTR_PC_HIDDEN; Attr_types_ptr.AttrTypes[2] = QP0L_ATTR_CODEPAGE; buff_size_needed = 0; follow_sym = QP0L_FOLLOW_SYMLNK; /**************************************************************/ /* Call Qp0lGetAttr() to retrieve attributes. */ /**************************************************************/ rc = Qp0lGetAttr(Pathname_ptr, (Qp0l_AttrTypes_List_t *)&Attr_types_ptr, Buffer_ptr, Buffer_size, &buff_size_needed, &num_bytes_returned, follow_sym); if((rc == 0) && /* If successful, but */ (num_bytes_returned <= 0)) /* Incorrect bytes returned */ rc = EUNKNOWN; /* Unknown error */ return(rc); } /* End GetAttrObject() */ int SetAttrObject( Qlg_Path_Name_T *Pathname_ptr, char *Buffer_ptr, unsigned int Buffer_size) { /**************************************************************/ /* Local variables */ /**************************************************************/ unsigned int follow_sym; int rc; int done = 0; unsigned int attrSize; Qp0l_Attr_Header_t *attrPtr; /**************************************************************/ /* Start of executable code */ /**************************************************************/ /**************************************************************/ /* Initialize Set Attributes Parameters */ /**************************************************************/ follow_sym = QP0L_FOLLOW_SYMLNK; /**************************************************************/ /* Qp0lSetAttr() only sets one attribute at a time. The */ /* buffer from Qp0lGetAttr may contain more than one */ /* attribute to set. We may have to call Qp0lSetAttr() */ /* multiple times. The Next_Attr_Offset value is the key. */ /* If it is greater than zero, then there is another */ /* attribute in the buffer. Also, it is important to note */ /* that the value stored there is the offset from the start */ /* of the buffer, not the offset from the start of the */ /* current entry. */ /**************************************************************/ attrPtr = (Qp0l_Attr_Header_t *)Buffer_ptr; while(!done) { attrSize = attrPtr->Attr_Size + sizeof(Qp0l_Attr_Header_t); /* Calculate attr size */ /*********************************************************/ /* Call Qp0lSetAttr() to set the attribute */ /*********************************************************/ rc=Qp0lSetAttr(Pathname_ptr, (char *)attrPtr, attrSize, follow_sym); if(rc != 0) /* If the function failed */ done = 1; /* End the loop */ else if(attrPtr->Next_Attr_Offset > 0) /* If more data */ attrPtr = (Qp0l_Attr_Header_t *) /* Set attribute */ (Buffer_ptr + attrPtr->Next_Attr_Offset); /* pointer */ else /* No more data */ done = 1; /* End the loop */ } return(rc); } /* End SetAttrObject() */ int main (int argc, char *argv[]) { #define MYPN "FRED" #define MYPN2 "FRED2" /**************************************************************/ /* Local variables */ /**************************************************************/ const char US_const[3] = "US"; const char Language_const[4] = "ENU"; const char Path_Name_Del_const[2] = "/"; typedef struct pnstruct { Qlg_Path_Name_T qlg_struct; char pn[sizeof(MYPN)]; } ; typedef struct pnstruct2 { Qlg_Path_Name_T qlg_struct; char pn[sizeof(MYPN2)]; } ; struct pnstruct pns; struct pnstruct2 pns2; int rc; char BufferArea[250]; unsigned int buffer_size = 250; /**************************************************************/ /* Start of executable code */ /**************************************************************/ /**************************************************************/ /* Initialize Pathname for original object */ /**************************************************************/ memset((void *)&pns, 0, sizeof(struct pnstruct)); pns.qlg_struct.CCSID = 37; memcpy(pns.qlg_struct.Country_ID,US_const,2); memcpy(pns.qlg_struct.Language_ID,Language_const,3);; pns.qlg_struct.Path_Type = 0; pns.qlg_struct.Path_Length = sizeof(MYPN) - 1; memcpy(pns.qlg_struct.Path_Name_Delimiter,Path_Name_Del_const,1); memcpy(pns.pn,MYPN,sizeof(MYPN)); /**************************************************************/ /* Call GetAttrObject to retrieve attributes from the source */ /* object. */ /**************************************************************/ rc = GetAttrObject((Qlg_Path_Name_T *)&pns, BufferArea, buffer_size); if (rc == 0) /* If GetAttr succeeded */ { /************************************************************/ /* Initialize Pathname for target object */ /************************************************************/ memset((void *)&pns2, 0, sizeof(struct pnstruct2)); pns2.qlg_struct.CCSID = 37; memcpy(pns2.qlg_struct.Country_ID,US_const,2); memcpy(pns2.qlg_struct.Language_ID,Language_const,3);; pns2.qlg_struct.Path_Type = 0; pns2.qlg_struct.Path_Length = sizeof(MYPN2)-1; memcpy(pns2.qlg_struct.Path_Name_Delimiter,Path_Name_Del_const,1); memcpy(pns2.pn,MYPN2,sizeof(MYPN2)); /************************************************************/ /* Call SetAttrObject to set attributes on the target */ /* object. */ /************************************************************/ rc=SetAttrObject((Qlg_Path_Name_T *)&pns2, BufferArea, buffer_size); if (rc != 0) { rc = errno; /* return errno from SetAttrObject */ printf("Qp0lSetAttr() for %s failed with %i.\n",pns2.pn,rc); } } /* end check GetAttrObject rc */ else /* GetAttrObject failed */ { rc = errno; /* return errno from GetAttrObject */ printf("Qp0lGetAttr() for %s failed with %s.\n",pns.pn,rc); } return(rc); } /* end main */
Top | UNIX-Type APIs | APIs by category |