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.
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:
cdx/libkio/
will
automatically determine the proper ioslave to use.
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 (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
Using the KDE ioslaves is very easy once the framework is in place. This section will describe getting the "back-end" stuff setup.
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.
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.
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.
If you are using the standard KDE automake/autoconf system for your application, then you are in luck! Adding another library is trivial:
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
This is also simple:
#include <kio_job.h>
Will take care of everything.
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:
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.
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.
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
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:
sigReady(int)
to a local slot (e.g., slotReady(int)
)KIOJob::put(..)
requestslotReady(..)
is called, you know that the ioslave is ready
to relay your data to its final destination.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.
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
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
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.
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
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
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
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
This signal indicates the the ioslave is completely done.
Parameters:
int id - The job id