iofd.c
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_close(io_fd_t *io);
00034 static int io_fd_free(io_fd_t *io);
00035
00036 static ssize_t io_fd_read(io_fd_t *ifd, char *buf, size_t size)
00037 {
00038 ssize_t c;
00039
00040 dbg_return_if (ifd == NULL, ~0);
00041 dbg_return_if (buf == NULL, ~0);
00042
00043 again:
00044 if(!ifd->issock)
00045 c = read(ifd->fd, buf, size);
00046 else
00047 c = recv(ifd->fd, buf, size, 0);
00048
00049 if(c < 0 && errno == EINTR)
00050 goto again;
00051
00052 dbg_err_sif(c == -1);
00053
00054 return c;
00055 err:
00056 return -1;
00057 }
00058
00059 static ssize_t io_fd_write(io_fd_t *ifd, const char *buf, size_t size)
00060 {
00061 ssize_t c;
00062
00063 dbg_return_if (ifd == NULL, ~0);
00064 dbg_return_if (buf == NULL, ~0);
00065
00066 again:
00067 if(!ifd->issock)
00068 c = write(ifd->fd, buf, size);
00069 else
00070 c = send(ifd->fd, buf, size, 0);
00071
00072 if(c < 0 && errno == EINTR)
00073 goto again;
00074
00075 dbg_err_sif(c == -1);
00076
00077 return c;
00078 err:
00079 return -1;
00080 }
00081
00082 static ssize_t io_fd_seek(io_fd_t *ifd, size_t off)
00083 {
00084 dbg_return_if (ifd == NULL, -1);
00085
00086 return lseek(ifd->fd, off, SEEK_SET);
00087 }
00088
00089 static ssize_t io_fd_tell(io_fd_t *ifd)
00090 {
00091 dbg_return_if (ifd == NULL, -1);
00092
00093 return lseek(ifd->fd, 0, SEEK_CUR);
00094 }
00095
00096
00097 static int io_fd_close(io_fd_t *ifd)
00098 {
00099 dbg_return_if (ifd == NULL, ~0);
00100
00101 if(ifd->flags & IO_FD_CLOSE && ifd->fd != -1)
00102 {
00103 #ifdef OS_WIN
00104 if(ifd->issock)
00105 {
00106 closesocket(ifd->fd);
00107 } else
00108 close(ifd->fd);
00109 #else
00110 close(ifd->fd);
00111 #endif
00112 ifd->fd = -1;
00113 }
00114
00115 return 0;
00116 }
00117
00118 static int io_fd_free(io_fd_t *ifd)
00119 {
00120 dbg_if(io_fd_close(ifd));
00121
00122 return 0;
00123 }
00124
00125 int io_fd_get_d(io_t *io)
00126 {
00127 io_fd_t *ifd = (io_fd_t*)io;
00128 dbg_err_if(io == NULL);
00129 dbg_err_if(ifd->io.type != IO_TYPE_FD);
00130
00131 return ifd->fd;
00132 err:
00133 return -1;
00134 }
00135
00136 int io_fd_create(int fd, int flags, io_t **pio)
00137 {
00138 io_fd_t *ifd = NULL;
00139
00140 dbg_err_if (pio == NULL);
00141
00142 dbg_err_if(io_create(io_fd_t, (io_t**)&ifd));
00143
00144 ifd->io.type = IO_TYPE_FD;
00145
00146 ifd->fd = fd;
00147 ifd->flags = flags;
00148 ifd->io.read = (io_read_op) io_fd_read;
00149 ifd->io.write = (io_write_op) io_fd_write;
00150 ifd->io.seek = (io_seek_op) io_fd_seek;
00151 ifd->io.tell = (io_tell_op) io_fd_tell;
00152 ifd->io.close = (io_close_op) io_fd_close;
00153 ifd->io.free = (io_free_op) io_fd_free;
00154
00155 #ifdef OS_WIN
00156 u_long ret;
00157 if(ioctlsocket(fd, FIONREAD, &ret) == 0)
00158 ifd->issock++;
00159 _setmode(fd, _O_BINARY);
00160 #endif
00161
00162 *pio = (io_t*)ifd;
00163
00164 return 0;
00165 err:
00166 if(ifd)
00167 io_free((io_t*)ifd);
00168 return ~0;
00169 }