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_sif(c == -1);
00051
00052 return c;
00053 err:
00054 return -1;
00055 }
00056
00057 static ssize_t io_fd_write(io_fd_t *ifd, const char *buf, size_t size)
00058 {
00059 ssize_t c;
00060
00061 dbg_return_if (ifd == NULL, ~0);
00062 dbg_return_if (buf == NULL, ~0);
00063
00064 again:
00065 if(!ifd->issock)
00066 c = write(ifd->fd, buf, size);
00067 else
00068 c = send(ifd->fd, buf, size, 0);
00069 if(c < 0 && (errno == EINTR || errno == EAGAIN))
00070 goto again;
00071
00072 dbg_err_sif(c == -1);
00073
00074 return c;
00075 err:
00076 return -1;
00077 }
00078
00079 static ssize_t io_fd_seek(io_fd_t *ifd, size_t off)
00080 {
00081 dbg_return_if (ifd == NULL, -1);
00082
00083 return lseek(ifd->fd, off, SEEK_SET);
00084 }
00085
00086 static ssize_t io_fd_tell(io_fd_t *ifd)
00087 {
00088 dbg_return_if (ifd == NULL, -1);
00089
00090 return lseek(ifd->fd, 0, SEEK_CUR);
00091 }
00092
00093 static int io_fd_term(io_fd_t *ifd)
00094 {
00095 dbg_return_if (ifd == NULL, ~0);
00096
00097 if(ifd->flags & IO_FD_CLOSE)
00098 {
00099 #ifdef OS_WIN
00100 if(ifd->issock)
00101 {
00102 closesocket(ifd->fd);
00103 } else
00104 close(ifd->fd);
00105 #else
00106 close(ifd->fd);
00107 #endif
00108 ifd->fd = -1;
00109 }
00110
00111 return 0;
00112 }
00113
00114 int io_fd_create(int fd, int flags, io_t **pio)
00115 {
00116 io_fd_t *ifd = NULL;
00117
00118 dbg_err_if (pio == NULL);
00119
00120 dbg_err_if(io_create(io_fd_t, (io_t**)&ifd));
00121
00122 ifd->fd = fd;
00123 ifd->flags = flags;
00124 ifd->io.read = (io_read_op) io_fd_read;
00125 ifd->io.write = (io_write_op) io_fd_write;
00126 ifd->io.seek = (io_seek_op) io_fd_seek;
00127 ifd->io.tell = (io_tell_op) io_fd_tell;
00128 ifd->io.term = (io_term_op) io_fd_term;
00129
00130 #ifdef OS_WIN
00131 u_long ret;
00132 if(ioctlsocket(fd, FIONREAD, &ret) == 0)
00133 ifd->issock++;
00134 _setmode(fd, _O_BINARY);
00135 #endif
00136
00137 *pio = (io_t*)ifd;
00138
00139 return 0;
00140 err:
00141 if(ifd)
00142 io_free((io_t*)ifd);
00143 return ~0;
00144 }