Next Previous Table of Contents

### 3. Using KDE I/O Slaves

Kurt Granroth <granroth@kde.org>

v0.1, 15, June 1999

This HOWTO describes how the KDE I/O slaves (ioslaves) work. It is intended for both ioslave implementers as well as users. In this document, I will attempt to describe both how ioslaves work as well as how to use them.

### 3.1 Introduction

#### What Are I/O Slaves?

The K Desktop Environment (KDE) I/O slaves (ioslaves) are a series of small programs that have intimate knowledge on working with a very specific protocol. For instance, the HTTP ioslave (`kio_http`) knows all about sending and receiving data to and from a web server. It knows all about SSL, encoding, and what all of the different header fields mean. It knows this so that KDE developers won't have to -- if they want a web page, they merely have to use `kio_http` for it and it will take care of everything for them.

The ioslaves are based on the KIO library (`libkio`). This library implements a method of asynchronous communication between applications as well as provides a "protocol registry" of sorts. This has many advantages. Two of the major ones are:

- The client does not need to know anything about the ioslave that it is calling. It merely specifies the protocol and `cdx/libkio/` will automatically determine the proper ioslave to use.
- All communication is done asynchronously. All `libkio` calls will return immediately. Whenever events occur, `libkio` will send signals altering the client to that fact. This means that the client does not have to engage in any "busy waiting."

Here is a fully working snippet of code to download a web page:

     KIOJob *job = new KIOJob;
     connect(job, SIGNAL(sigData(int, const char*, int)),
             this, SIGNAL(slotData(int, const char*, int)));
     job->get("http://www.kde.org/news_dyn.html");

That's it! When the ioslave is done getting the KDE news page, it will call your application's slotData() function with the page.

#### Copyright

Copyright (c) 1999 Kurt Granroth, All rights reserved. This is free documentware; you can redistribute it and/or modify it under the terms of version 2 or later of the GNU General Public License

### 3.2 Setting Up IOSlaves

Using the KDE ioslaves is very easy once the framework is in place. This section will describe getting the "back-end" stuff setup.

#### The KIO Library

The first part that needs to be installed is the KDE IO library (`libkio`). This library is part of the KDE 2.x `kdelibs` package. It will be installed by default on all KDE 2.x systems when 2.x is finally released. In the meantime, you will need to get it through either CVSUP or the snapshots. See www.kde.org (or a later appendix when I get around to it later) for details on that.

`libkio` depends on the KDE UI library (`libkdeui`), the KDE Core library (`libkdecore`), and Qt (`libqt`). These are the "standard" KDE libraries so there shouldn't be any problems, there.

#### The IOSlaves

There are ioslaves for `http`, `file`, `gzip`, `tar`, `file`, `smb`, `pop3`, and `imap4` as of the time of this writing. They are all found in the `kdebase` package under `kioslaves`. Again, these are available only from the KDE development CVS so you'll need to use CVSUP or the snapshots to retrieve them.

### 3.3 Using ioslaves in your Application

Now that you have the backend stuff all setup, you can start setting up your application to use them. This requires adding the `libkio` library to your linking and including the proper header files.

#### Modifying your Makefile

If you are using the standard KDE automake/autoconf system for your application, then you are in luck! Adding another library is trivial:

- Edit Makefile.am
- Change the line <yourapp>_LDADD to look something like:

           myapp_LDADD = $(LIB_KIO)

That's it! If you are not using the KDE setup, then just make sure that you are including the following in your link stage:

        -lkio -lkdeui -lkdecore -lqt

#### Adding the Proper Headers

This is also simple:

       #include <kio_job.h>

Will take care of everything.

### 3.4 Using IOSlaves via KIOJob

Now that your application is all prepped for using ioslaves, you can actually start using them!

The only class you need to deal with at a client level is the KIOJob class. You will use it to "call" the ioslaves and it will send you signals when it received events from them.

The basic procedure is something like this:

- Create a KIOJob instance
- Connect all of the signals (events) that you are interested in to some local slots (callbacks).
- Send the actual request
- Process the resulting response in your slots.

#### Typical Example

An example looks like so:

     KIOJob *job = new KIOJob;
     connect(job, SIGNAL(sigData(int, const char*, int)),
             this, SLOT(slotData(int, const char*, int)));
     connect(job, SIGNAL(sigError(int, int, const char*)),
             this, SLOT(slotError(int, int, const char*)));
     connect(job, SIGNAL(sigDataEnd(int)),
             this, SLOT(slotDataEnd(int)));
     connect(job, SIGNAL(sigFinished(int)),
             this, SLOT(slotFinished(int)));
     job->get("http://www.pobox.com/~kurt_granroth/index.html");

This will get the web page at the above URL. When the ioslave is done receiving the page, it will send it to you with your `slotData()` function. If there was an error, then you receive it in `slotError()`. If the page was large, then it will be sent in chunks. You know that you are done receiving data when `slotDataEnd()` is called. The `slotFinished()` function is called when the ioslave is completely done.

### 3.5 KIOJob Calls

There are numerous operations that you can do with KIOJob. Some of them are: `put`, `get`, `mkdir`, `copy`, `move`, `del`, `unmount`, and `mount`. I will refer only to `put()` and `get()` in this HOWTO. The others follow similar patterns.

#### get(const char* url)

This is probably the most common operation. It tells the ioslave to "get" the resource described in the URL. This may be a web page, a POP3 message, or a local file -- it all depends on your URL.

This operation is not very interactive. You tell the ioslave what you want and it gets it for you. Period.

Specifically, it will send back your data with the `sigData(int id, char char* data, int length)` signal.

Parameters:

const char *url - The URL of the resource that you wish to get

#### put(const char* url, int mode, bool overwrite, bool resume, int size)

This operation will start the process of "putting" or sending data to the location specified in the URL. This is used, for instance, to send files to a remote FTP server or do do a PUT or POST request with HTTP. It is not quite a straight-forward as a `get()` operation.

The basic procedure looks like:

- Connect `sigReady(int)` to a local slot (e.g., `slotReady(int)`)
- Send a `KIOJob::put(..)` request
- When `slotReady(..)` is called, you know that the ioslave is ready to relay your data to its final destination.
- Send all of your data using the `KIOJob::data(const char*, int)` operation. When you are done, notify the ioslave of this by sending a `KIOJob::dataEnd()`

Some sample code looks like so:

     KIOJob *job;
     char *data = "My message";
     Client::Client()
     {
            job = new KIOJob;
            connect(job, SIGNAL(sigReady(int)), this, SLOT(slotReady(int)));
            connect(job, SIGNAL(sigData(int, const char*, int)),
                    this, SLOT(slotData(int, const char*, int)));
            connect(job, SIGNAL(sigDataEnd(int)),
                    this, SLOT(slotDataEnd(int)));
            job->put("http://server.com/cgi-bin/post.cgi", -1, true, false, strlen(data));
     }

     void Client::sigReady(int id)
     {
        job->data(data, strlen(data));
            job->dataEnd();
     }

Parameters:

const char* url - The end location for your data int mode - Special permissions for your data. This should be set to -1 if there are no special permissions bool overwrite - Instructs the ioslave to overwrite anything that may already be there. bool resume - Instructs the ioslave to resume a previously aborted transaction. int size - This is the size of the data that you will be sending

Beyond that, everything else is identical to the 'get' method.

#### data(void *data, int size)

This is used to send data to an ioslave. It is used in conjunction with the `KIOJob::put(..)` operation. It is almost always called from your object's `slotReady()` slot as you must wait for the `sigReady(int)` signal before sending any data. If your data is greater than 2048 bytes, then you must break it up into many chunks and send each chunk individually.

Parameters:

void *data - Your data that needs to go to the ioslave. This should be no more than 2048 bytes. int size - The size of this data

#### dataEnd()

This is used along with `KIOJob::data(..)` and `KIOJob::put(..)`. It signals the ioslave that you are done sending it data. If you do not send this signal, then the ioslave will essentially hang. You do not need to use this if you are using `KIOJob::get(..)`.

Parameters:

None

### 3.6 KIOJob Signals

All communication from the ioslaves come through KIOJob in the form of signals. There are quite a few of them (see `kio_job.h` for a complete listing), but I'll only discuss the "essential" ones.

#### sigError(int id, int errid, const char* text)

This signal is emitted whenever an error occurs. You should always connect a slot to this signal unless you really don't care if there is an error or not.

Parameters:

int id - The job id int errid - The error code. This corresponds to the list of errors defined in kio_interface.h const char* text - A textual description of the error

#### sigReady(int id)

This signal occurs when the ioslave is ready to accept data. If you are using only `get(..)` methods, then you should not have to connect to this signal. If you are using a `put(..)` method, then you must connect to this signal and begin sending data from there.

Parameters:

int id - The job id

#### sigData(int id, const char *data, int size)

This signal happens whenever the ioslave is sending you data. This is typically the data that it just downloaded. It will never be more than 2048 bytes, so plan on having it called several times. You are responsible for collecting all of the data. You will know that the ioslave is done sending you data when you get the `sigDataEnd(int)` signal.

Parameters:

int id - The job id const char *data - The data that the ioslave just downloaded int size - The size of this data chunk

#### sigDataEnd(int id)

This signal is sent to signify that the ioslave is done sending you data. You should use this signal as an assurance that you can use the data as `sigData(..)` will never again be called.

Parameters:

int id - The job id

#### sigFinished(int id)

This signal indicates the the ioslave is completely done.

Parameters:

int id - The job id

Next Previous Table of Contents