diff options
author | Thomas Touhey <thomas@touhey.fr> | 2019-04-29 00:01:44 +0200 |
---|---|---|
committer | Thomas Touhey <thomas@touhey.fr> | 2019-04-29 00:01:44 +0200 |
commit | b22ffac673939f19c0c0ea0b3cbb4d48ead95ca2 (patch) | |
tree | 8433c4485b29b927fd8c2b97853c8eb9b6844b67 | |
parent | 4e4da6ef8eaf17386f61c5ac44f3815c0f54047a (diff) |
Added utilities and reorganized the files
-rw-r--r-- | include/libtio.h | 14 | ||||
-rw-r--r-- | include/libtio/stream.h | 14 | ||||
-rw-r--r-- | lib/init.c | 2 | ||||
-rw-r--r-- | lib/stream/generic.c | 299 | ||||
-rw-r--r-- | lib/stream/read.c | 57 | ||||
-rw-r--r-- | lib/stream/read_tm.c | 23 | ||||
-rw-r--r-- | lib/stream/seek.c | 104 | ||||
-rw-r--r-- | lib/stream/serial_attrs.c (renamed from lib/stream/attrs.c) | 85 | ||||
-rw-r--r-- | lib/stream/tm.c | 27 | ||||
-rw-r--r-- | lib/stream/write.c | 58 | ||||
-rw-r--r-- | lib/stream/write_tm.c | 23 |
11 files changed, 379 insertions, 327 deletions
diff --git a/include/libtio.h b/include/libtio.h index 1d0708b..0df8c78 100644 --- a/include/libtio.h +++ b/include/libtio.h @@ -18,12 +18,18 @@ TIO_EXTERN(int) tio_init TIO_EXTERN(void) tio_exit OF((void)); -# define TIO_INIT \ +# ifndef TIO_NOINIT +# include <stdlib.h> + +# define TIO_INIT \ { \ - if (tio_check_version(TIO_VERSION) || tio_init()) \ + if (tio_check_version(TIO_VERSION)) \ + exit(1); \ + if (!(TIO_error = tio_init())) \ + atexit(&tio_exit); \ + else if (TIO_error != tio_error_arg) \ exit(1); \ - \ - atexit(&tio_exit); \ } +# endif #endif /* LIBTIO_H */ diff --git a/include/libtio/stream.h b/include/libtio/stream.h index 2b9cf0f..874c945 100644 --- a/include/libtio/stream.h +++ b/include/libtio/stream.h @@ -98,7 +98,7 @@ typedef int tio_whence_t; struct tio_serial_attrs { unsigned int tio_serial_attrs_flags; - unsigned int tio_serial_attrs_speed; + unsigned long tio_serial_attrs_speed; unsigned char tio_serial_attrs_cc[TIO_SERIAL_ATTRS_NCCS]; }; @@ -119,7 +119,10 @@ struct tio_serial_attrs { # define TIO_B128000 128000 # define TIO_B256000 256000 -/* Here are the control characters you can define: +/* Use `tio_make_serial_speed()` and `tio_make_serial_speed_in_bauds()` to + * make the conversion, it will make your life easier. + * + * Here are the control characters you can define: * `TIO_XON`: the XON character to re-enable transmission (software control); * `TIO_XOFF`: the XOFF charater to disable transmission (software control). */ @@ -382,12 +385,17 @@ struct tio_scsi_functions { TIO_BEGIN_DECLS -/* Default stream serial settings utilities. */ +/* Serial settings utilities. */ TIO_EXTERN(int) tio_make_serial_attrs OF((tio_serial_attrs_t *tio__attrs, char const *tio__raw, unsigned long tio__flags)); +TIO_EXTERN(int) tio_make_serial_speed + OF((unsigned long *tio__speed, unsigned long tio__bauds)); +TIO_EXTERN(int) tio_make_serial_speed_in_bauds + OF((unsigned long *tio__bauds, unsigned long tio__speed)); + /* Open and close a stream. * * Functions that the stream does not override (by not setting the @@ -22,7 +22,7 @@ TIO_LOCAL_DATA(struct exit_queue_chunk *) tio_exit_queue; TIO_EXTERN(int) tio_init(void) { if (tio_initialized) - return (0); + return (tio_error_arg); tio_initialized = 1; /* Initialize the exit queue. */ diff --git a/lib/stream/generic.c b/lib/stream/generic.c new file mode 100644 index 0000000..708bd4a --- /dev/null +++ b/lib/stream/generic.c @@ -0,0 +1,299 @@ +#include "internals.h" + +/* `tio_set_timeouts()`: set the timeouts for the stream. */ + +TIO_EXTERN(int) tio_set_timeouts(tio_stream_t *stream, + tio_timeouts_t const *readtm, tio_timeouts_t const *writetm) +{ + int err; + tio_set_tm_t *stm; + + /* Check that the parent isn't dead. */ + + if (stream->tio_stream_dead_parent) + return (tio_error_unknown); /* FIXME */ + + /* Transmit the request. */ + + if (!(stm = stream->tio_stream_set_tm)) + return (tio_error_op); + if ((err = (*stm)(stream->tio_stream_cookie, readtm, writetm))) + goto fail; + + err = tio_error_ok; +fail: + stream->tio_stream_lasterr = err; + return (err); +} + +/* --- + * Read from a stream, with timeouts or not. + * --- */ + +/* `tio_read()`: read from a stream. */ + +TIO_EXTERN(int) tio_read(tio_stream_t *stream, void *dest, size_t count) +{ + int err; + tio_read_tm_t *rdt; + tio_read_t *rd; + + /* Check if we can read. */ + + if (stream->tio_stream_dead_parent) { + err = tio_error_read; + goto fail; + } + + if ((rdt = stream->tio_stream_read_tm)) { + /* Check that the job isn't already done. */ + + if (!count) + return (tio_error_ok); + + /* Read using the function. */ + + if ((err = (*rdt)(stream->tio_stream_cookie, dest, count, + &stream->tio_stream_read_timeouts))) { + msg((ll_error, "Stream reading failure: %s", tio_error_desc(err))); + goto fail; + } + } else if ((rd = stream->tio_stream_read)) { + /* Check that the job isn't already done. */ + + if (!count) + return (tio_error_ok); + + /* Read using the function. */ + + if ((err = (*rd)(stream->tio_stream_cookie, dest, count))) { + msg((ll_error, "Stream reading failure: %s", tio_error_desc(err))); + goto fail; + } + } else { + err = stream->tio_stream_parent + ? tio_read(stream->tio_stream_parent, dest, count) + : tio_error_read; + goto fail; + } + + /* Move the cursor and return. */ + + stream->tio_stream_offset += (tio_off_t)count; + err = tio_error_ok; +fail: + stream->tio_stream_lasterr = err; + return (err); +} + +/* `tio_read_tm()`: read from a stream, with timeouts. */ + +TIO_EXTERN(int) tio_read_tm(tio_stream_t *stream, void *dest, + size_t count, tio_timeouts_t const *tm) +{ + tio_timeouts_t orig; + int err; + + /* Save the timeouts, then call, then restore them. */ + + if (tm) { + memcpy(&orig, tm, sizeof(orig)); + tio_set_timeouts(stream, tm, NULL); + } else + memcpy(&orig, &stream->tio_stream_read_timeouts, sizeof(orig)); + + err = tio_read(stream, dest, count); + tio_set_timeouts(stream, &orig, NULL); + + return (err); +} + +/* --- + * Write to a stream, with timeouts or not. + * --- */ + +/* `tio_write()`: write to a stream. */ + +TIO_EXTERN(int) tio_write(tio_stream_t *stream, void const *data, + size_t count) +{ + int err; + tio_write_tm_t *wrt; + tio_write_t *wr; + + /* Check if we can write. */ + + if (stream->tio_stream_dead_parent) { + err = tio_error_write; + goto fail; + } + + if ((wrt = stream->tio_stream_write_tm)) { + /* Check that the job isn't already done. */ + + if (!count) + return (tio_error_ok); + + /* Write using the function. */ + + if ((err = (*wrt)(stream->tio_stream_cookie, data, count, + &stream->tio_stream_write_timeouts))) { + msg((ll_error, "Stream writing failure: %s", tio_error_desc(err))); + goto fail; + } + } else if ((wr = stream->tio_stream_write)) { + /* Check that the job isn't already done. */ + + if (!count) + return (tio_error_ok); + + /* Write using the function. */ + + if ((err = (*wr)(stream->tio_stream_cookie, data, count))) { + msg((ll_error, "Stream writing failure: %s", tio_error_desc(err))); + goto fail; + } + } else { + err = stream->tio_stream_parent + ? tio_write(stream->tio_stream_parent, data, count) + : tio_error_write; + goto fail; + } + + /* Move the cursor and return. */ + + stream->tio_stream_offset += (tio_off_t)count; + err = tio_error_ok; +fail: + stream->tio_stream_lasterr = err; + return (err); +} + +/* `tio_write_tm()`: write to a stream, with timeouts. */ + +TIO_EXTERN(int) tio_write_tm(tio_stream_t *stream, void const *data, + size_t count, tio_timeouts_t const *tm) +{ + tio_timeouts_t orig; + int err; + + /* Save the timeouts, then call, then restore them. */ + + if (tm) { + memcpy(&orig, tm, sizeof(orig)); + tio_set_timeouts(stream, tm, NULL); + } else + memcpy(&orig, &stream->tio_stream_write_timeouts, sizeof(orig)); + + err = tio_write(stream, data, count); + tio_set_timeouts(stream, &orig, NULL); + + return (err); +} + +/* --- + * Move around within a generic stream. + * --- */ + +/* `tio_seek()`: move the cursor of the stream. */ + +TIO_EXTERN(int) tio_seek(tio_stream_t *stream, tio_off_t offset, + tio_whence_t whence) +{ + int err; + tio_seek_t *sk; + tio_off_t skip; + + /* Check the whence. */ + + switch (whence) { + case TIO_SEEK_SET: case TIO_SEEK_CUR: case TIO_SEEK_END: + break; + default: + err = tio_error_op; + goto fail; + } + + /* Check that the parent isn't dead. */ + + if (stream->tio_stream_dead_parent) + return (tio_error_seek); + + /* Use different methods according to the stream configuration. */ + + if ((sk = stream->tio_stream_seek)) { + /* Use the dedicated function. */ + + if ((err = (*sk)(stream->tio_stream_cookie, &offset, whence))) + goto fail; + } else if (stream->tio_stream_read + && ((whence == TIO_SEEK_CUR && (skip = offset) > 0) + || (whence == TIO_SEEK_SET + && (skip = offset - stream->tio_stream_offset) > 0))) { + /* Fallback method for skipping bytes: read until N bytes have + * been skipped. */ + + unsigned char buf[128]; + size_t to_skip = (size_t)skip; + + do { + size_t rd = min(to_skip, 128); + + /* Read that much from the stream. */ + + if ((err = tio_read(stream, buf, rd))) + goto fail; + + to_skip -= rd; + } while (to_skip); + } else { + err = tio_error_op; + goto fail; + } + + stream->tio_stream_offset = offset; + err = tio_error_ok; +fail: + stream->tio_stream_lasterr = err; + return (err); +} + +/* `tio_tell()`: get the offset. */ + +TIO_EXTERN(tio_off_t) tio_tell(tio_stream_t *stream) +{ + return (stream->tio_stream_offset); +} + +/* `tio_skip()`: skip bytes. */ + +TIO_EXTERN(int) tio_skip(tio_stream_t *stream, tio_off_t size) +{ + /* Use what has been implemented in `tio_seek()` function to + * skip N bytes. */ + + return (tio_seek(stream, size, TIO_SEEK_CUR)); +} + +/* `tio_get_size()`: get the size of a stream (e.g. file). */ + +TIO_EXTERN(int) tio_get_size(tio_stream_t *stream, tio_off_t *size) +{ + int err; + tio_off_t offset; + + /* Save the initial offset and go to the end of the file. */ + + offset = tio_tell(stream); + if ((err = tio_seek(stream, 0, TIO_SEEK_END))) + return (err); + + /* Get the current position (end of the file = size) and return to + * the initial position. */ + + *size = tio_tell(stream); + if ((err = tio_seek(stream, offset, TIO_SEEK_SET))) + return (err); + + return (tio_error_ok); +} diff --git a/lib/stream/read.c b/lib/stream/read.c deleted file mode 100644 index 6c4d7e7..0000000 --- a/lib/stream/read.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "internals.h" - -/* `tio_read()`: read from a stream. */ - -TIO_EXTERN(int) tio_read(tio_stream_t *stream, void *dest, size_t count) -{ - int err; - tio_read_tm_t *rdt; - tio_read_t *rd; - - /* Check if we can read. */ - - if (stream->tio_stream_dead_parent) { - err = tio_error_read; - goto fail; - } - - if ((rdt = stream->tio_stream_read_tm)) { - /* Check that the job isn't already done. */ - - if (!count) - return (tio_error_ok); - - /* Read using the function. */ - - if ((err = (*rdt)(stream->tio_stream_cookie, dest, count, - &stream->tio_stream_read_timeouts))) { - msg((ll_error, "Stream reading failure: %s", tio_error_desc(err))); - goto fail; - } - } else if ((rd = stream->tio_stream_read)) { - /* Check that the job isn't already done. */ - - if (!count) - return (tio_error_ok); - - /* Read using the function. */ - - if ((err = (*rd)(stream->tio_stream_cookie, dest, count))) { - msg((ll_error, "Stream reading failure: %s", tio_error_desc(err))); - goto fail; - } - } else { - err = stream->tio_stream_parent - ? tio_read(stream->tio_stream_parent, dest, count) - : tio_error_read; - goto fail; - } - - /* Move the cursor and return. */ - - stream->tio_stream_offset += (tio_off_t)count; - err = tio_error_ok; -fail: - stream->tio_stream_lasterr = err; - return (err); -} diff --git a/lib/stream/read_tm.c b/lib/stream/read_tm.c deleted file mode 100644 index 8affbea..0000000 --- a/lib/stream/read_tm.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "internals.h" - -/* `tio_read_tm()`: read from a stream, with timeouts. */ - -TIO_EXTERN(int) tio_read_tm(tio_stream_t *stream, void *dest, - size_t count, tio_timeouts_t const *tm) -{ - tio_timeouts_t orig; - int err; - - /* Save the timeouts, then call, then restore them. */ - - if (tm) { - memcpy(&orig, tm, sizeof(orig)); - tio_set_timeouts(stream, tm, NULL); - } else - memcpy(&orig, &stream->tio_stream_read_timeouts, sizeof(orig)); - - err = tio_read(stream, dest, count); - tio_set_timeouts(stream, &orig, NULL); - - return (err); -} diff --git a/lib/stream/seek.c b/lib/stream/seek.c deleted file mode 100644 index 480fc29..0000000 --- a/lib/stream/seek.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "internals.h" - -/* `tio_seek()`: move the cursor of the stream. */ - -TIO_EXTERN(int) tio_seek(tio_stream_t *stream, tio_off_t offset, - tio_whence_t whence) -{ - int err; - tio_seek_t *sk; - tio_off_t skip; - - /* Check the whence. */ - - switch (whence) { - case TIO_SEEK_SET: case TIO_SEEK_CUR: case TIO_SEEK_END: - break; - default: - err = tio_error_op; - goto fail; - } - - /* Check that the parent isn't dead. */ - - if (stream->tio_stream_dead_parent) - return (tio_error_seek); - - /* Use different methods according to the stream configuration. */ - - if ((sk = stream->tio_stream_seek)) { - /* Use the dedicated function. */ - - if ((err = (*sk)(stream->tio_stream_cookie, &offset, whence))) - goto fail; - } else if (stream->tio_stream_read - && ((whence == TIO_SEEK_CUR && (skip = offset) > 0) - || (whence == TIO_SEEK_SET - && (skip = offset - stream->tio_stream_offset) > 0))) { - /* Fallback method for skipping bytes: read until N bytes have - * been skipped. */ - - unsigned char buf[128]; - size_t to_skip = (size_t)skip; - - do { - size_t rd = min(to_skip, 128); - - /* Read that much from the stream. */ - - if ((err = tio_read(stream, buf, rd))) - goto fail; - - to_skip -= rd; - } while (to_skip); - } else { - err = tio_error_op; - goto fail; - } - - stream->tio_stream_offset = offset; - err = tio_error_ok; -fail: - stream->tio_stream_lasterr = err; - return (err); -} - -/* `tio_tell()`: get the offset. */ - -TIO_EXTERN(tio_off_t) tio_tell(tio_stream_t *stream) -{ - return (stream->tio_stream_offset); -} - -/* `tio_skip()`: skip bytes. */ - -TIO_EXTERN(int) tio_skip(tio_stream_t *stream, tio_off_t size) -{ - /* Use what has been implemented in `tio_seek()` function to - * skip N bytes. */ - - return (tio_seek(stream, size, TIO_SEEK_CUR)); -} - -/* `tio_get_size()`: get the size of a stream (e.g. file). */ - -TIO_EXTERN(int) tio_get_size(tio_stream_t *stream, tio_off_t *size) -{ - int err; - tio_off_t offset; - - /* Save the initial offset and go to the end of the file. */ - - offset = tio_tell(stream); - if ((err = tio_seek(stream, 0, TIO_SEEK_END))) - return (err); - - /* Get the current position (end of the file = size) and return to - * the initial position. */ - - *size = tio_tell(stream); - if ((err = tio_seek(stream, offset, TIO_SEEK_SET))) - return (err); - - return (tio_error_ok); -} diff --git a/lib/stream/attrs.c b/lib/stream/serial_attrs.c index 61db795..3fc0e77 100644 --- a/lib/stream/attrs.c +++ b/lib/stream/serial_attrs.c @@ -1,5 +1,61 @@ #include "internals.h" +/* `tio_make_serial_speed()`: make the serial speed out of a baud speed. */ + +TIO_EXTERN(int) tio_make_serial_speed(unsigned long *speed, + unsigned long bauds) +{ +#define BR_TO_SP(BR, SP) \ + case (BR): *speed = (SP); break; + + switch (bauds) { + BR_TO_SP(110, TIO_B110) + BR_TO_SP(300, TIO_B300) + BR_TO_SP(600, TIO_B600) + BR_TO_SP(1200, TIO_B1200) + BR_TO_SP(2400, TIO_B2400) + BR_TO_SP(4800, TIO_B4800) + BR_TO_SP(9600, TIO_B9600) + BR_TO_SP(14400, TIO_B14400) + BR_TO_SP(19200, TIO_B19200) + BR_TO_SP(38400, TIO_B38400) + BR_TO_SP(57600, TIO_B57600) + BR_TO_SP(115200, TIO_B115200) + BR_TO_SP(128000, TIO_B128000) + BR_TO_SP(256000, TIO_B256000) + } + + return (tio_error_arg); +} + +/* `tio_make_serial_speed_in_bauds()`: make the baud speed out of a serial + * speed. */ + +TIO_EXTERN(int) tio_make_serial_speed_in_bauds(unsigned long *bauds, + unsigned long speed) +{ +#define SP_TO_BR(SP, BR) \ + case (SP): *bauds = (BR); break; + + switch (speed) { + SP_TO_BR(TIO_B110, 110) + SP_TO_BR(TIO_B300, 300) + SP_TO_BR(TIO_B600, 600) + SP_TO_BR(TIO_B1200, 1200) + SP_TO_BR(TIO_B2400, 2400) + SP_TO_BR(TIO_B4800, 4800) + SP_TO_BR(TIO_B9600, 9600) + SP_TO_BR(TIO_B19200, 19200) + SP_TO_BR(TIO_B38400, 38400) + SP_TO_BR(TIO_B57600, 57600) + SP_TO_BR(TIO_B115200, 115200) + SP_TO_BR(TIO_B128000, 128000) + SP_TO_BR(TIO_B256000, 256000) + } + + return (tio_error_arg); +} + /* `reset_serial_attrs()`: reset the serial attributes to reasonable * values using flags. */ @@ -46,7 +102,7 @@ TIO_LOCAL(void) reset_serial_attrs(tio_serial_attrs_t *attrs, TIO_EXTERN(int) tio_make_serial_attrs(tio_serial_attrs_t *attrs, char const *raw, unsigned long flags) { - unsigned int speed = 0; + unsigned long speed = 0; char par = '\0'; int stop = 0; @@ -94,32 +150,7 @@ TIO_EXTERN(int) tio_make_serial_attrs(tio_serial_attrs_t *attrs, /* Get the speed. */ - switch (speed) { - case 1200: - speed = TIO_B1200; - break; - case 2400: - speed = TIO_B2400; - break; - case 4800: - speed = TIO_B4800; - break; - case 9600: - speed = TIO_B9600; - break; - case 19200: - speed = TIO_B19200; - break; - case 38400: - speed = TIO_B38400; - break; - case 57600: - speed = TIO_B57600; - break; - case 115200: - speed = TIO_B115200; - break; - default: + if (tio_make_serial_speed(&speed, speed)) { msg((ll_error, "%u isn't a valid speed!", speed)); return (tio_error_arg); } diff --git a/lib/stream/tm.c b/lib/stream/tm.c deleted file mode 100644 index 6e4067a..0000000 --- a/lib/stream/tm.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "internals.h" - -/* `tio_set_timeouts()`: set the timeouts for the stream. */ - -TIO_EXTERN(int) tio_set_timeouts(tio_stream_t *stream, - tio_timeouts_t const *readtm, tio_timeouts_t const *writetm) -{ - int err; - tio_set_tm_t *stm; - - /* Check that the parent isn't dead. */ - - if (stream->tio_stream_dead_parent) - return (tio_error_unknown); /* FIXME */ - - /* Transmit the request. */ - - if (!(stm = stream->tio_stream_set_tm)) - return (tio_error_op); - if ((err = (*stm)(stream->tio_stream_cookie, readtm, writetm))) - goto fail; - - err = tio_error_ok; -fail: - stream->tio_stream_lasterr = err; - return (err); -} diff --git a/lib/stream/write.c b/lib/stream/write.c deleted file mode 100644 index bc1f01c..0000000 --- a/lib/stream/write.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "internals.h" - -/* `tio_write()`: write to a stream. */ - -TIO_EXTERN(int) tio_write(tio_stream_t *stream, void const *data, - size_t count) -{ - int err; - tio_write_tm_t *wrt; - tio_write_t *wr; - - /* Check if we can write. */ - - if (stream->tio_stream_dead_parent) { - err = tio_error_write; - goto fail; - } - - if ((wrt = stream->tio_stream_write_tm)) { - /* Check that the job isn't already done. */ - - if (!count) - return (tio_error_ok); - - /* Write using the function. */ - - if ((err = (*wrt)(stream->tio_stream_cookie, data, count, - &stream->tio_stream_write_timeouts))) { - msg((ll_error, "Stream writing failure: %s", tio_error_desc(err))); - goto fail; - } - } else if ((wr = stream->tio_stream_write)) { - /* Check that the job isn't already done. */ - - if (!count) - return (tio_error_ok); - - /* Write using the function. */ - - if ((err = (*wr)(stream->tio_stream_cookie, data, count))) { - msg((ll_error, "Stream writing failure: %s", tio_error_desc(err))); - goto fail; - } - } else { - err = stream->tio_stream_parent - ? tio_write(stream->tio_stream_parent, data, count) - : tio_error_write; - goto fail; - } - - /* Move the cursor and return. */ - - stream->tio_stream_offset += (tio_off_t)count; - err = tio_error_ok; -fail: - stream->tio_stream_lasterr = err; - return (err); -} diff --git a/lib/stream/write_tm.c b/lib/stream/write_tm.c deleted file mode 100644 index 84c80ba..0000000 --- a/lib/stream/write_tm.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "internals.h" - -/* `tio_write_tm()`: write to a stream, with timeouts. */ - -TIO_EXTERN(int) tio_write_tm(tio_stream_t *stream, void const *data, - size_t count, tio_timeouts_t const *tm) -{ - tio_timeouts_t orig; - int err; - - /* Save the timeouts, then call, then restore them. */ - - if (tm) { - memcpy(&orig, tm, sizeof(orig)); - tio_set_timeouts(stream, tm, NULL); - } else - memcpy(&orig, &stream->tio_stream_write_timeouts, sizeof(orig)); - - err = tio_write(stream, data, count); - tio_set_timeouts(stream, &orig, NULL); - - return (err); -} |