Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

iofd.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005, 2006 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: iofd.c,v 1.9 2006/04/22 13:14:46 tat Exp $
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; /* must be the first item */
00022     int fd;
00023     int flags;
00024     int issock;     /* >0 if fd is a SOCKET (win32 only) */
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++; /* is a socket, use recv/send instead of read/write  */
00135     _setmode(fd, _O_BINARY); /* we never want Windows CR/LF translation */
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 }

←Products
© 2005-2006 - KoanLogic S.r.l. - All rights reserved