00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <fcntl.h>
00013 #include <unistd.h>
00014 #include <u/libu.h>
00015 #include <klone/io.h>
00016 #include <klone/io.h>
00017 #include <klone/ioprv.h>
00018
00019 struct io_fd_s
00020 {
00021 struct io_s io;
00022 int fd;
00023 int flags;
00024 int issock;
00025 };
00026
00027 typedef struct io_fd_s io_fd_t;
00028
00029 static ssize_t io_fd_read(io_fd_t *io, char *buf, size_t size);
00030 static ssize_t io_fd_write(io_fd_t *io, const char *buf, size_t size);
00031 static ssize_t io_fd_seek(io_fd_t *io, size_t off);
00032 static ssize_t io_fd_tell(io_fd_t *io);
00033 static int io_fd_term(io_fd_t *io);
00034
00035 static ssize_t io_fd_read(io_fd_t *ifd, char *buf, size_t size)
00036 {
00037 ssize_t c;
00038
00039 dbg_return_if (ifd == NULL, ~0);
00040 dbg_return_if (buf == NULL, ~0);
00041
00042 again:
00043 if(!ifd->issock)
00044 c = read(ifd->fd, buf, size);
00045 else
00046 c = recv(ifd->fd, buf, size, 0);
00047 if(c < 0 && (errno == EINTR || errno == EAGAIN))
00048 goto again;
00049
00050 dbg_err_if(c == -1);
00051
00052 return c;
00053 err:
00054 dbg_strerror(errno);
00055 return -1;
00056 }
00057
00058 static ssize_t io_fd_write(io_fd_t *ifd, const char *buf, size_t size)
00059 {
00060 ssize_t c;
00061
00062 dbg_return_if (ifd == NULL, ~0);
00063 dbg_return_if (buf == NULL, ~0);
00064
00065 again:
00066 if(!ifd->issock)
00067 c = write(ifd->fd, buf, size);
00068 else
00069 c = send(ifd->fd, buf, size, 0);
00070 if(c < 0 && (errno == EINTR || errno == EAGAIN))
00071 goto again;
00072
00073 dbg_err_if(c == -1);
00074
00075 return c;
00076 err:
00077 return -1;
00078 }
00079
00080 static ssize_t io_fd_seek(io_fd_t *ifd, size_t off)
00081 {
00082 dbg_return_if (ifd == NULL, -1);
00083
00084 return lseek(ifd->fd, off, SEEK_SET);
00085 }
00086
00087 static ssize_t io_fd_tell(io_fd_t *ifd)
00088 {
00089 dbg_return_if (ifd == NULL, -1);
00090
00091 return lseek(ifd->fd, 0, SEEK_CUR);
00092 }
00093
00094 static int io_fd_term(io_fd_t *ifd)
00095 {
00096 dbg_return_if (ifd == NULL, ~0);
00097
00098 if(ifd->flags & IO_FD_CLOSE)
00099 {
00100 #ifdef OS_WIN
00101 if(ifd->issock)
00102 {
00103 closesocket(ifd->fd);
00104 } else
00105 close(ifd->fd);
00106 #else
00107 close(ifd->fd);
00108 #endif
00109 ifd->fd = -1;
00110 }
00111
00112 return 0;
00113 }
00114
00115 int io_fd_create(int fd, int flags, io_t **pio)
00116 {
00117 io_fd_t *ifd = NULL;
00118
00119 dbg_err_if (pio == NULL);
00120
00121 dbg_err_if(io_create(io_fd_t, (io_t**)&ifd));
00122
00123 ifd->fd = fd;
00124 ifd->flags = flags;
00125 ifd->io.read = (io_read_op) io_fd_read;
00126 ifd->io.write = (io_write_op) io_fd_write;
00127 ifd->io.seek = (io_seek_op) io_fd_seek;
00128 ifd->io.tell = (io_tell_op) io_fd_tell;
00129 ifd->io.term = (io_term_op) io_fd_term;
00130
00131 #ifdef OS_WIN
00132 u_long ret;
00133 if(ioctlsocket(fd, FIONREAD, &ret) == 0)
00134 ifd->issock++;
00135 _setmode(fd, _O_BINARY);
00136 #endif
00137
00138 *pio = (io_t*)ifd;
00139
00140 return 0;
00141 err:
00142 if(ifd)
00143 io_free((io_t*)ifd);
00144 return ~0;
00145 }