ioctl()--Change Descriptor Attributes


Syntax
#include <sys/types.h>
#include <sys/ioctl.h>

int ioctl(int descriptor,
          unsigned long request,
          ...)


Threadsafe: Conditional; see Usage Notes.

The ioctl() function is used to obtain or change the attributes of a file or socket descriptor.

Parameters

descriptor
(Input) The descriptor whose attributes are retrieved or changed. The descriptor points to a file or a socket.

request
(Input) The request that is to be performed on the descriptor. Figure 1-8 lists the ioctl() requests that are supported.

Figure 1-8. ioctl() Requests Supported by Sockets
Request Description
FIONBIO Set/reset nonblocking I/O flag.
FIOASYNC Set/clear flag that allows the receipt of asynchronous I/O signals (SIGIO).
FIONREAD Return the number of octets available to be read.
FIOSETOWN Set the process ID or process group ID that is to receive the SIGIO and SIGURG signals.
FIOGETOWN Get the process ID or process group ID that is to receive the SIGIO and SIGURG signals.
SIOCATMARK Return the value indicating whether socket's read pointer is currently at the out-of-band mark.
SIOCSPGRP Set the process ID or process group ID that is to receive the SIGIO and SIGURG signals.
SIOCGPGRP Get the process ID or process group ID that is to receive the SIGIO and SIGURG signals.
SIOCADDRT Add an entry to the interface routing table. Valid for sockets with address family of AF_INET.
SIOCDELRT Delete an entry from the interface routing table. Valid for sockets with address family of AF_INET.
SIOCGRTCONF Get the route configuration list. Valid for sockets with address family of AF_INET.
SIOCGIFADDR Get the interface address. Valid for sockets with address family of AF_INET.
SIOCGIFFLAGS Get interface flags. Valid for sockets with address family of AF_INET.
SIOCGIFBRDADDR Get the interface broadcast address. Valid for sockets with address family of AF_INET.
SIOCGIFNETMASK Get the mask for the network portion of the interface address. Valid for sockets with address family of AF_INET.
SIOCGIFMTU Get the interface network MTU. Valid for sockets with address family of AF_INET.
SIOCGIFRBUFS Get the interface reassembly buffer size. Valid for sockets with address family of AF_INET.
SIOCGIFLIND Get the interface line description name. Valid for sockets with address family of AF_INET.
SIOCGIFTOS Get the interface type-of-service (TOS). Valid for sockets with address family of AF_INET.
SIOCGIFCONF Get the interface configuration list. Valid for sockets with address family of AF_INET.
Start of changeSIOCSENDQ Return the number of octets on the send queue that have not been acknowledged by the remote system. Valid for sockets with address family of AF_INET and socket type of SOCK_STREAM.End of change
SIOCGPXRTCONF Get a list of IPX routes. Valid for sockets with address family of AF_NS.
SIOCGPXRTE Get an IPX route entry. Valid for sockets with address family of AF_NS.
SIOCGPXSRV Get a list of available IPX services of the specified service type. Valid for sockets with address family of AF_NS.
SIOCGPXSRVCONF Get a list of available IPX services. Valid for sockets with address family of AF_NS.
SIOCPXADVSRV Advertise Service. Valid for sockets with address family of AF_NS.
SIOCPXSHDSRV Shutdown Service. Valid for sockets with address family of AF_NS.
SIOCSTELRSC Set telephony resources. Valid for sockets with address family of AF_TELEPHONY.

...
(Input/output) A variable number of optional parameters that is dependent on the request.

Following are more details about the requests listed in Figure 1-8.

FIONBIO:

For the FIONBIO request, the third parameter, argument, represents a pointer to an integer flag. A nonzero value sets the nonblocking I/O flag for the descriptor; a zero value resets the flag.

FIOSETOWN and SIOCSPGRP:

For the FIOSETOWN and SIOCSPGRP requests, the third parameter, argument, represents a pointer to a signed integer that contains the process ID or the process group ID to which the socket should send asynchronous signals such as SIGURG. A process ID is specified as a positive integer, and a process group ID is specified as a negative integer. Specifying a 0 value resets the socket such that no asynchronous signals will be delivered. Specifying a process ID or a process group ID requests that sockets begin sending the SIGURG signal to the specified ID when out-of-band data arrives on the socket.

FIOGETOWN and SIOCGPGRP:

For the FIOGETOWN and SIOCGPGRP requests, the third parameter, argument, represents a pointer to a signed integer that will contain the process ID or the process group ID to which the socket is currently sending asynchronous signals such as SIGURG. A process ID is returned as a positive integer, and a process group ID is specified as a negative integer. A 0 value returned indicates that no asynchronous signals can be generated by the socket. A positive or a negative value indicates that the socket has been set to generate SIGURG signals.

FIOASYNC:

For the FIOASYNC request, the third parameter, argument, represents a pointer to an integer flag. A nonzero value sets the socket to generate SIGIO signals, while a zero value sets the socket to not generate SIGIO signals. Note that before the SIGIO signals can be delivered, you must use either the FIOSETOWN or SIOCSPGRP ioctl() request, or the F_SETOWN fcntl() command to set a process ID or a process group ID to indicate what process or group of processes will receive the signal. Once conditioned to send SIGIO signals, a socket will generate SIGIO signals whenever certain significant conditions change on the socket. For example, SIGIO will be generated when normal data arrives on the socket, when out-of-band data arrives on the socket (in addition to the SIGURG signal), when an error occurs on the socket, or when end-of-file is received on the socket. It is also generated when a connection request is received on the socket (if it is a socket on which the listen() verb has been done). Also note that a socket can be set to generate the SIGIO signal by using the fcntl() command F_SETFL with a flag value specifying FASYNC.

FIONREAD:

For the FIONREAD request, the third parameter, argument, represents a pointer to an integer that is set to the number of octets available to be read.

SIOCATMARK:

For the SIOCATMARK request, the third parameter, argument, represents a pointer to an integer flag. If the socket's read pointer is currently at the out-of-band mark, the flag is set to a nonzero value. If it is not, the flag is set to zero.

SIOCADDRT and SIOCDELRT:

For the SIOCADDRT and SIOCDELRT requests, the third parameter, argument, represents a pointer to the structure rtentry, which is defined in <net/route.h>:

      struct rtentry [
         struct sockaddr rt_dst;
         struct sockaddr rt_mask;
         struct sockaddr rt_gateway;
         int rt_mtu;
         u_short rt_flags;
         u_short rt_refcnt;
         u_char rt_protocol;
         u_char rt_TOS;
         char rt_if[IFNAMSIZ];
      ];

The rt_dst, rt_mask, and rt_gateway fields are the route destination address, route address mask, and gateway address, respectively. rt_mtu is the maximum transfer unit associated with the route. rt_flags contains flags that give some information about a route (for example, whether the route was created dynamically, whether the route is usable, type of route, and so on). rt_refcnt indicates the number of references that exist to the route entry. rt_protocol indicates how the route entry was generated (for example, configuration, ICMP redirect, and so on). rt_tos is the type of service associated with the route. rt_if is a NULL-terminated string that represents the interface IP address in dotted decimal format that is associated with the route.

To add a route, the following fields must be set:

In addition, the rt_flags bit flags can be set to the following:

To delete a route, the following fields must be set:

All other fields are ignored when adding or removing an entry.

Note: For the SIOCGRTCONF request, for which a list of route entries is returned, all the fields in an rtentry structure are set to a value.

SIOCGRTCONF:

For the SIOCGRTCONF request, the third parameter, argument, represents a pointer to the structure rtconf, also defined in <net/route.h>:

      struct rtconf [
         int rtc_len;
         int rtc_configured;
         int rtc_returned;
         union {
          caddr_t rtcu_buf;
          struct rtentry *rtcu_req;
         } rtc_rtcu;
      ];

rtc_len is a value-result field. The caller passes the size of the buffer pointed to by rtcu_buf. On return, rtc_len contains the amount of storage that was used in the buffer pointed to by rtcu_buf for the route entries. rtc_configured is the number of route entries in the route table. rtc_returned is the number of route entries that were returned (this is dependent on the size of the buffer pointed to by rtcu_buf). rtcu_buf is the user buffer in which a list of route entries will be stored.

To get the route configuration list, the following fields must be set:

SIOCGIFADDR, . . . SIOCGIFTOS:

For the SIOCGIFADDR , SIOCGIFFLAGS , SIOCGIFBRDADDR, SIOCGIFNETMASK, SIOCGIFMTU , SIOCGIFRBUFS , SIOCGIFLIND , and SIOCGIFTOS requests, the third parameter, argument, represents a pointer to the structure ifreq, defined in <net/if.h>:

      struct ifreq {
         char ifr_name[IFNAMSIZE];
         union {
          struct sockaddr ifru_addr;
          struct sockaddr ifru_mask;
          struct sockaddr ifru_broadaddr;
          short ifru_flags;
          int ifru_mtu;
          int infu_rbufsize;
          char ifru_linename[10];
          char ifru_TOS;
         } ifr_ifru;
      };

ifr_name is the name of the interface for which information is to be retrieved. The OS/400 implementation requires this field to be set to a NULL-terminated string that represents the interface IP address in dotted decimal format. Depending on the request, one of the fields in the ifr_ifru union will be set upon return from the ioctl() call. ifru_addr is the local IP address of the interface. ifru_mask is the subnetwork mask associated with the interface. ifru_broadaddr is the broadcast address. ifru_flags contains flags that give some information about an interface (for example, token-ring routing support, whether interface is active, broadcast address, and so on). ifru_mtu is the maximum transfer unit configured for the interface. ifru_rbufsize is the reassembly buffer size of the interface. ifru_linename is the line name associated with the interface. ifru_TOS is the type of service configured for the interface.

Note: For the SIOCGIFCONF request, for which a list of interface entries is returned, the ifr_name and ifru_addr fields in an ifreq structure will be set to a value.

SIOCGIFCONF:

For the SIOCGIFCONF request, the third parameter, argument, represents a pointer to the structure ifconf, defined in <net/if.h>:

      struct ifconf [
         int ifc_len;
         int ifc_configured;
         int ifc_returned;
         union {
          caddr_t ifcu_buf;
          struct ifreq *ifcu_req;
         } ifc_ifcu;
      ];

ifc_len is a value-result field. The caller passes the size of the buffer pointed to by ifcu_buf. On return, ifc_len contains the amount of storage that was used in the buffer pointed to by ifcu_buf for the interface entries. ifc_configured is the number of interface entries in the interface table. ifc_returned is the number of interface entries that were returned (this is dependent on the size of the buffer pointed to by ifcu_buf). ifcu_buf is the user buffer in which a list of interface entries will be stored.

To get the interface configuration list, the following fields must be set:

Start of changeSIOCSENDQ:

For the SIOCSENDQ request, the third parameter, argument, represents a pointer to an integer that is set to the number of octets yet to be acknowledged as being received by the remote TCP transport driver.

Notes:

  1. SIOCSENDQ is used after a series of blocking or non-blocking send operations to see if the sent data has reached the transport layer on the remote system. Note that this does not not guarantee the data has reached the remote application.

  2. When SIOCSENDQ is used in a multithreaded application, the actions of other threads must be considered by the application. SIOCSENDQ provides a result for a socket descriptor at the given point in time when the ioctl()) request is received by the TCP transport layer. Blocking send operations that have not completed, as well as non-blocking send operations in other threads issued after the SIOCSENDQ ioctl(), are not reflected in the result obtained for the SIOCSENDQ ioctl().

  3. In a situation where the application has multiple threads sending data on the same socket descriptor, the application should not assume that all data has been received by the remote side when 0 is returned if the application is not positive that all send operations in the other threads were complete at the time the SIOCSENDQ ioctl() was issued. An application should issue the SIOCSENDQ ioctl() only after it has completed all of the send operations. No value is added by querying the machine to see if it has sent all of the data when the application itself has not sent all of the data in a given unit of work.End of change

SIOCGPXRTCONF:

For the SIOCGPXRTCONF request, the third parameter, argument, represents a pointer to the structure ipxrt_conf, defined in <netns/ipx.h>:


struct ipxrt_conf {                   /* get route configuration     */
   int ipxrt_len;                     /* length of user buffer       */
   int ipxrt_configured;              /* number of routes configured */
   int ipxrt_returned;                /* number of routes returned   */
   union {
      caddr_t              ipxrt_buf; /* user-supplied buffer address*/
      struct ipxrt_entry * ipxrt_list;/* returned list of routes     */
   } ipxrt_ulist;
};

ipxrt_len is a value-result field. The caller passes the size of the buffer pointed to by ipxrt_buf. On return, ipxrt_len will contain the amount of storage that was used in the buffer pointed to by ipxrt_buf for the route entries. ipxrt_configured is the number of route entries in the route table. ipxrt_returned is the number of route entries that were returned (this is dependent on the size of the buffer pointed to by ipxrt_buf). ipxrt_buf is the user buffer in which a list of route entries will be stored. A route entry is represented by the structure ipxrt_entry defined in <netns/ipx.h>:

Figure 1-9. ipxrt_entry Structure


struct ipxrt_entry {                  /* IPX route entry             */
   u_int           ipxrt_circuit;     /* IPX circuit by which
                                         route was learned           */
   struct timeval  ipxrt_tod;         /* Time of day at which route
                                         was learned                 */
   u_int           ipxrt_net;         /* IPX network number          */
   u_short         ipxrt_ticks;       /* time to network             */
   u_short         ipxrt_hops;        /* hops to network             */
   u_short         ipxrt_maxPDU;      /* maximum PDU length for route*/
   union   ns_host ipxrt_nexthop;     /* next hop                    */
   u_char          reserved[3];       /* reserved - 0x00             */
   u_char          ipxrt_infosrc;     /* information source          */
};

Note that the ipxrt_tod field that is returned is adjusted to Greenwich mean time based on the value specified in the system value QUTCOFFSET. The structure timeval is defined in <sys/time.h>:

Figure 1-10. timeval Structure

struct timeval {
   long  tv_sec;     /* second       */
   long  tv_usec;    /* microseconds */
};

The address of the tv_sec member can be cast to time_t * and used as input to the ctime() function.

To get the route configuration list, the following fields must be set:

SIOCGPXRTE:

For the SIOCGPXRTE request, the third parameter, argument, represents a pointer to the structure ipxrt_req, defined in <netns/ipx.h>:


struct ipxrt_req {                    /* get a single route entry   */
    struct ns_addr     ipxrtr_addr;   /* input - remote address for
                                         which a route will be
                                         returned                   */
    struct ipxrt_entry ipxrtr_entry;  /* output - returned route
                                         entry                      */
};

ns_addr is the address for which route information is to be returned. If the network number is an external network, the host and port fields are ignored. If the external network is unknown, [ENETUNREACH] is returned. If the network number is local, then the host and the port fields should both be specified. If there is not a socket bound to the specified port number on the local network, [ECONNREFUSED] is returned.

ipxrtr_entry is the returned route entry, as represented by the structure ipxrt_entry defined in <netns/ipx.h> as shown in Figure 1-9. Note that the ipxrt_tod field that is returned is adjusted to Greenwich mean time based on the value specified in the system value QUTCOFFSET. It is defined as a timeval structure as defined in <sys/time.h> and shown in Figure 1-10. The address of the tv_sec member can be cast to time_t * and used as input to the ctime() function.

SIOCGPXSRV:

For the SIOCGPXSRV request, the third parameter, argument, represents a pointer to the structure ipxsrv_query_service, defined in <netns/ipx.h>:


struct ipxsrv_query_service {         /* get a service entry        */
    u_short   ipxsrv_type;
    struct ipxsrv_conf ipxsrv_matches;/* returned services that
                                         matched the requested type */
};

ipxsrv_type specifies the type of services for which a list of services is being requested. ipxsrv_matches is a structure, ipxsrv_conf, that contains the list of services that match the specified ipxsrv_type. The structure ipxsrv_conf is defined in <netns/ipx.h>:

Figure 1-11. ipxsrv_conf Structure


struct ipxsrv_conf {                  /* get list of services        */
   int ipxsrv_len;                    /* length of user buffer       */
   int ipxsrv_configured;             /* number of servers configured*/
   int ipxsrv_returned;               /* number of servers returned  */
   union {
      caddr_t               ipxsrv_buf;
                                     /* user-supplied buffer address */
      struct ipxsrv_entry * ipxsrv_list;/* returned list of servers  */
   } ipxsrv_ulist;
};

The ipxsrv_conf structure contains the following fields:

Notes:

  1. ipxsrv_len is a value-result field. The caller passes the size of the buffer pointed to by ipxsrv_buf.

  2. ipxsrv_conf is the number of service entries available to be returned.

  3. ipxsrv_returned is the number of entries returned in ipxsrv_buf.

  4. ipxsrv_buf is a buffer supplied by the user in which the requested service entries are returned.

  5. On return from the call, ipxsrv_len will contain the amount of storage that was used in the buffer pointed to by ipxsrv_buf.

On return from the call, the ipxsrv_buf buffer will contain an array of returned service entries, represented by the structure ipxsrv_entry defined in <netns/ipx.h>:

Figure 1-12. ipxsrv_entry Structure


struct ipxsrv_entry {                 /* SPX/IPX service entry       */
   u_int           ipxsrv_circuit;    /* IPX circuit by which
                                         service was learned         */
   struct timeval  ipxsrv_tod;        /* Time of day at which service
                                         was learned                 */
   u_short         ipxsrv_type;       /* service type                */
   u_short         ipxsrv_hops;       /* number of hops to server    */
   char            ipxsrv_name[48];   /* server name                 */
   struct ns_addr  ipxsrv_address;    /* server address              */
   u_char          reserved[3];       /* reserved - 0x00             */
   u_char          ipxsrv_infosrc;    /* information source          */
};

Note that the ipxsrv_tod field that is returned is adjusted to Greenwich mean time based on the value specified in the system value QUTCOFFSET. It is defined as a timeval structure as defined in <sys/time.h> and shown in Figure 1-10. The address of the tv_sec member can be cast to time_t * and used as input to the ctime() function. Also, be aware that the service name returned in ipxsrv_name is returned in the default coded character set identifier (CCSID) currently in effect for the job.

To get the list of all services of type ipxsrv_type, the following fields must be set:

To get only the number of service entries available of type ipxsrv_type, you can specify ipxsrv_buf as NULL and ipxsrv_len as zero.

SIOCGPXSRVCONF:

For the SIOCGPXSRVCONF request, the third parameter, argument, represents a pointer to the structure ipxsrv_conf, defined in <netns/ipx.h> and shown in Figure 1-11.

The ipxsrv_conf structure contains the following fields:

Notes:

  1. ipxsrv_len is a value-result field. The caller passes the size of the buffer pointed to by ipxsrv_buf.

  2. ipxsrv_conf is the number of service entries available to be returned.

  3. ipxsrv_returned is the number of entries returned in ipxsrv_buf.

  4. ipxsrv_buf is a buffer supplied by the user in which the requested service entries are returned.

  5. On return from the call, ipxsrv_len will contain the amount of storage that was used in the buffer pointed to by ipxsrv_buf.

On return from the call, the ipxsrv_buf buffer will contain an array of returned service entries, represented by the structure ipxsrv_entry defined in <netns/ipx.h> and shown in Figure 1-12. Note that the ipxsrv_tod field that is returned is adjusted to Greenwich mean time based on the value specified in the system value QUTCOFFSET. It is defined as a timeval structure as defined in <sys/time.h> and shown in Figure 1-10. The address of the tv_sec member can be cast to time_t * and used as input to the ctime() function. Also, be aware that the service name returned in ipxsrv_name is returned in the default coded character set identifier (CCSID) currently in effect for the job.

To get the list of all services, the following fields must be set:

To get only the number of service entries available, you can specify ipxsrv_buf as NULL and ipxsrv_len as zero.

SIOCPXADVSRV:

For the SIOCPXADVSRV request, the third parameter, argument, represents a pointer to the structure ipxsrv_advertise, defined in <netns/ipx.h>:


struct ipxsrv_advertise {
   u_short ipxsrv_type;               /* service type       */
   char    ipxsrv_name[48];           /* service name       */
};

ipxsrv_type is the type of service that you are requesting to advertise. ipxsrv_name is the name of the service that you are advertising.

Notes:

  1. This service name is assumed to be in the default coded character set identifier (CCSID) currently in effect for the job, and the characters must be single-byte characters. If a double-byte character is encountered, [ECONVERT] is returned.

  2. The characters are translated to CCSID 850. After translation, the characters must be represented by a hexadecimal value of X'0x20' through X'0x7f' inclusive, with the exception that the characters X'0x2a' (*), X'0x2c' (,), X'0x2f' (/), X'0x3a' (:), X'0x3b'(;), X'0x3f' (?), and X'0x5c' (\) are not valid. Characters that are not valid are rejected with [EINVAL].

  3. The name must be null-terminated with the null terminating character '\0'. [EFAULT] is returned for strings that are not null-terminated.

  4. The socket on which this request is issued must be in a bound state or the SIOCPXADVSRV will be rejected with an errno of [EPERM].

SIOCPXSHDSRV:

For the SIOCPXSHDSRV request, the third parameter, argument, represents a pointer to an IPX service name, defined by the user as a 48-character buffer.

Notes:

  1. This service name is assumed to be in the default coded character set identifier (CCSID) currently in effect for the job, and the characters must be single-byte characters. If a double-byte character is encountered, [ECONVERT] is returned.

  2. The characters are translated to CCSID 850. After translation, the characters must be represented by a hexadecimal value of X'0x20' through X'0x7f' inclusive, with the exception that the characters X'0x2a' (*), X'0x2c' (,), X'0x2f' (/), X'0x3a' (:), X'0x3b'(;), X'0x3f' (?), and X'0x5c' (\) are not valid. Characters that are not valid are rejected with [EINVAL].

  3. The name must be null-terminated with the null-terminating character '\0'. [EFAULT] is returned for strings that are not null-terminated.

  4. The name must have been advertised on the local host by successfully running an SIOCPXADVSRV request, or the SIOCPXSHDSRV will fail with an errno of [ENOENT].

SIOCSTELRSC:

For the SIOCSTELRSC request, the third parameter, argument, represents a pointer to a TelResource structure, which is defined in <nettel/tel.h>.


struct TelResource {                 /* telephony resource structure */
   int    trCount;                   /* number of devices            */
   char   trReserved[12];            /* reserved                     */
   void*  trResourceList;            /* pointer to array of system
                                        pointers                     */
};

trCount1 is the number of devices that are to be associated with the socket, trReserved is a reserved field, and trResourceList is a pointer to an array of space pointers. Each of these space pointers is the address of a device that will be associated with the socket.

Notes:

  1. This request will associate one or more telephony (*TEL) network devices with a socket. Once the association is made, it will last until the socket is closed.

  2. The user is responsible for resolving each device name to a system pointer.

  3. Before the device can be associated with a socket, the following conditions must be met:

  4. The user must have at least operational authority for the devices to be associated with the socket.

  5. A device cannot be associated with more than one socket at a time.

  6. If the SIOCSTELRSC request fails for any reason, none of the specified devices will be associated the socket.

  7. For more information about this request and the AF_TELEPHONY address family, please see the Sockets Programming book.

Return Value

ioctl() returns an integer. Possible values are:

Error Conditions

When ioctl() fails, errno can be set to one of the following:

[EBADF]
Descriptor not valid.
[ECONVERT]
Conversion error.

You passed a service name for the SIOCPXADVSRV or the SIOCPXSHDSRV request that contained a double-byte character.

[ECONNREFUSED]
The destination socket refused an attempted connect operation.

No sockets application is currently bound to the network services address port number as specified in your SIOCGPXRTE request.

[EFAULT]
Bad address.

The system detected an address which was not valid while attempting to access an optional parameter, or the optional parameter contained an address which was not valid.

[EINVAL]
Parameter not valid.

This error code indicates one of the following:

[EIO]
Input/output error.
[ENOBUFS]
There is not enough buffer space for the requested operation.
[ENOENT]
No such file or directory.

The process issued an ioctl() with the SIOCPXSHDSRV request, and the service has not been advertised by the local node.

[ENETUNREACH]
Cannot reach the destination network.

The network number specified in your SIOCGPXRTE request is unknown.

[EPERM]
Operation not permitted.

This error code indicates one of the following:

[EPIPE]
Broken pipe.
[EUNKNOWN]
Unknown system state.
[EUNATCH]
The protocol required to support the specified address family is not available at this time.

Error Messages

CPE3418 E
Possible APAR condition or hardware failure.
CPF9872 E
Program or service program &1 in library &2 ended. Reason code &3.
CPFA081 E
Unable to set return value or error code.

Usage Notes

  1. This function will fail with error code [ENOTSAFE] when all the following conditions are true:

  2. A program must have the appropriate privilege *IOSYSCFG to issue any of the following requests: SIOCADDRT and SIOCDELRT .

Related Information


Top | Sockets APIs | APIs by category


[Information Center Home Page | Feedback ] [Legal | AS/400 Glossary]