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.10 2006/09/24 13:26:18 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_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++; /* is a socket, use recv/send instead of read/write  */
00134     _setmode(fd, _O_BINARY); /* we never want Windows CR/LF translation */
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 }

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