The kav_check_mem function will suit your needs when the data object you want to check for viruses already resides in a continuous block of memory. But suppose, for example, that the data is being read from a socket or must be collected from several non-contiguous regions of memory. In such situation you need to allocate a new memory block large enough to hold your data object, then read or otherwise collect the data to this block, and finally pass it to kav_check_mem. This is inefficient, because kav_check_mem internally allocates a shared memory block (the size of its size parameter), copies your data to this block and then calls KAVDaemon to check it. The overhead for allocating this shared memory block and copying you data there may become significant if your data object is large. It could be eliminated, though, if you had an ability to write your data directly to the shared memory block that can be passed to KAVDaemon, thus avoiding the use of the intermediate non-shared memory block. The functions described in this section give you exactly this ability.
The kav_shmem_init function allocates a shared memory block and sets it up so that KAVDaemon can check it. You can then write your data to the block. Once all data is written, call kav_shmem_check to check the shared memory block. If you need to repeat the check for some other data, you can then write that other data to the same shared memory block again, and call kav_shmem_check again to check it. To dispose of the shared memory block once it's no longer needed, use kav_shmem_cleanup.
The formal defintion of the advanced memory checking functions is as follows:
The kav_shmem_init function creates a shared memory segment of size size, sets it up so that KAVDaemon can check it and associates it with the session context ctx. The mem parameter returns a pointer to the segment start. The meaning of the keyfile is a little involved. It's safe to set it to NULL, and if you don't know how System V shared memory functions work, you can leave it at that and skip to the next paragraph. For those who want to know the details, if you set it to a non-NULL value, this value should name an existing accessible file. The kav_shmem_init function will pass it to ftok system function to obtain a System V IPC key_t value, which it will further use to allocate a shared memory segment with shmget. You must ensure that until the shared memory segment is destroyed with kav_shmem_cleanup, you don't call kav_shmem_init again (perhaps from a different thread) with the same non-NULL keyfile. If you do so, the second call will fail. Note that if you set keyfile to NULL, libkavclient will use a temporary file in /tmp directory, which it will create and delete automatically as necessary. If in your application a suitable keyfile exists for other purposes, you can use it with kav_shmem_init to avoid the (very minor) overhead of creating this temporary file. This, however, can be considered an advanced fine-tuning; in most cases you can leave keyfile as NULL.
When kav_shmem_init succeeds, it returns 0. In case of failure, it returns -1. In the latter case, use the kav_get_error function to get the libkavclient error code. Possible error codes that kav_shmem_init can set are as follows:
This error means that the system function ftok failed. Most probably you passed an invalid keyfile parameter to kav_shmem_init, such as a non-existen or non-accessible file. If you encounter this error when passing NULL for keyfile to kav_shmem_init, you have either run into a bug in libkavclient or your system is severely out of memory. Check the system errno value for additional information on why ftok failed.
For some reason, libkavclient failed to create a temporary file, which is necessary to check memory regions. Examine the system errno value to find out why. If you encounter this error, you probably have run into a bug in libkavclient, or something is wrong with your system, such as /tmp directory is not writable.
This error means that libkavclient failed to allocate a necessary amount of shared memory, which it needs to pass memory regions to KAVDaemon for checking. More technically, the system function shmget failed. Examine system errno value to find out why.
This error means that libkavclient failed to attach to the shared memory segment it allocated in order to pass it to KAVDaemon for checking. More technically, the system function shmat failed. Examine system errno value to find out why. It must be either a bug in libkavclient, or your system is severely out of memory.
Your system failed to allocate memory for libkavclient. Most probably you are out of memory.
Once a shared segment is successfully created with kav_shmem_init, you can fill at most size bytes of memory starting at address *mem with the data you want to check. Then call kav_shmem_check. This function checks the data in the segment associated to the session context ctx, of size bytes, for viruses. Note that size must be less then or equal to the size passed to kav_shmem_init (in other words, you can check a part of the segment, but you can't check more data than there is in the segment). Similar to kav_check_mem, the results of the check are recorded in the context, and you can use the functions described in the section called “Interpreting check results” to interpret them.
When kav_shmem_check succeeds, it returns 0. In case of failure, it returns -1. Again, a call is considered successful when KAVDaemon was contacted and reply was received; it has nothing to do with whether viruses were found. If the call fails, use the kav_get_error function to get the libkavclient error code. Possible error codes that kav_shmem_init can set are as follows:
The system failed to create a socket. Examine the system errno value to find out why. This is a rare error, and if you see it, something is wrong with your system.
Connection to KAVDaemon failed. Examine the system errno value to find out why. The most likely reason for this error is that KAVDaemon is not running, or the path to KAVDaemon socket (as set by kav_set_socketpath) is incorrect (in that case errno will be set to ENOENT).
A check is already in progress in the given session context. This can only happen in a multi-threaded application when two threads call one of the checking functions in the same context concurrently.
An error occured while sending the request ro KAVDaemon. Check the system errno value to find out what kind of error.
The request to KAVDaemon was succesfully sent, but some error occurred while waiting for reply. Check the system errno value to find out what kind of error. Note that libkavclient waits for reply using the system select function.
The request to KAVDaemon was succesfully sent, but no response was received from KAVDaemon. The amount of time that libkavclient waits before returning this error can be set by the kav_set_timeout function, and by default is 5 seconds.
libkavclient started reading the reply from KAVDaemon, but some error occurred while reading. Check the system errno value to find out what kind of error.
KAVDaemon was successfully contacted, but it failed to perform the requested check because it didn't find a valid key file. This means that you don't have a valid license to use KAVDaemon (remember, KAVDaemon is commercial software!). You should contact Kaspersky Lab.
KAVDaemon was successfully contacted, but it failed to perform the requested check because it couldn't find its virus definition bases. Either something is wrong with your KAVDaemon configuration, or you need to run kavupdater to download the virus definition bases.
KAVDaemon was successfully contacted, but it failed to perform the requested check because it detected internal integrity violation. Most probably this means that your KAVDaemon binary is corrupt. You need to reinstall it.
This error means that kav_shmem_check is called in a session context, in which kav_shmem_init wasn't called (or the call failed). You may only call kav_shmem_check after kav_shmem_init.
This error means that kav_shmem_check was called with size larger than the size of the shared memory block previously created by kav_shmem_init. Check the size arguments of corresponding kav_shmem_init and kav_shmem_check calls - the latter must be less then or equal to the former.
Your system failed to allocate memory for libkavclient. Most probably you are out of memory.
You can repeat the "write object to memory - check it with kav_shmem_check" cycle as many times as necessary, as long as your data objects fit in the shared memory segment you allocated. Once you are done with the shared memory segment, call kav_shmem_cleanup on the session context to free it. Note that when you free a session context with kav_free, and a shared memory segment is associated to it at this point, the segment will be freed automatically. The kav_shmem_cleanup never fails when given a properly allocated context, and doesn't set libkavclient error code. It is safe (although redundant) to call it more than once on the same context in a row (i.e. it will detect that the shared memory segment is already freed and do nothing on subsequent calls).
It is imperative that your application frees the shared memory segment with kav_shmem_cleanup (directly or indirectly via kav_free) once it has allocated it with kav_shmem_init. If your application exits without freeing any shared memory segments it allocated, the segments continue to exist (the OS doesn't free them automatically) and deplete system resources. In particular, you must ensure that kav_shmem_cleanup is called even if your application is interrupted by a signal.