#ifndef KIio
#define KIio
/* <k/io.h>
 * ~ lexi hale <lexi@hale.su>
 * this header declares IO primitive functions and
 * structures. it is the same for all platforms.
 * platform-specific code is found in the *.platform.h
 * files.
 */

#include <k/type.h>
#include <k/mem.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef enum kiostream_kind {
	kiostream_closed,
	  // this kiostream cannot be written to
	kiostream_file,
	  // this kiostream represents a file
	kiostream_sock,
	  // this kiostream is attached to a socket,
	  // UNIX, IP, or otherwise
	kiostream_term,
	  // this socket is being used to communicate
	  // directly with a human being
	kiostream_ansi,
	  // like kiostream_term, but can also understand
	  // ANSI control codes
	kiostream_pipe,
	  // this kiostream sends or receives data to
	  // another running process
	kiostream_other
	  // no fuckin idea
} kiostream_kind;

typedef struct kiostream {
	kiostream_kind kind;
	ifelse(target_posix,`yes',`
		int platform_fd;
	')dnl
} kiostream;

typedef struct kiochan {
	kiostream in;
	  // text can be read from this stream
	kiostream out;
	  // text can be written to this stream
} kiochan;

#include <k/internal.egroup.h>
typedef enum kiocond {
	/* to check if a call failed, perform (x >= kiocond_fail) where x
	 * is that call's return value. more typically however you should
	 * select explicitly against kiocond_ok or kiocond_partial, since
	 * those situations will usually need to be handled differently. */

	kiocond_ok = kiocond_id, // success

	kiocond_partial, // partial read or write
	kiocond_poll, // call would block
	kiocond_interrupt, // call was interrupted by signal

    kiocond_fail, // action failed - unspecified reason
	kiocond_fail_closed_stream, // action failed because stream is closed
	kiocond_fail_invalid,
	kiocond_fail_io,
	kiocond_fail_no_peer,
	kiocond_fail_no_space,
	kiocond_fail_forbidden,
	kiocond_fail_over_quota,
	kiocond_fail_pfault,
	kiocond_fail_too_big,
	kiocond_fail_stream_mismatch,
} kiocond;

#include <k/str.h>

kiocond kiosend(kiochan, ksraw, sz*); // send data to a channel
kiocond kiosendall(kiochan, ksraw); // keep sending data to a channel until it's all sent
kiocond kiorecv(kiochan, ksraw*); // receive data from a channel
kmptr kiorecvall(kiochan, kmcell*, kmkind); // automatically allocate a bufer for a channel
  // kmkind is only used if kmcell* is null
kiocond kiocon(kiochan, kiochan); // connect one channel to another

#ifdef __cplusplus
}
#endif

#endif
