posix_io.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <unistd.h>
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <sys/mman.h>
00028 #include <fcntl.h>
00029 #include <errno.h>
00030
00031 #include "io_private.h"
00032 #include "posix_io.h"
00033
00034
00036 struct io_data_posix {
00038 int fd;
00039 };
00040
00041 static IOFileRef posix_open(const char *path, int mode);
00042 static int posix_close(IOFileRef f);
00043 static int posix_seek(IOFileRef f, off_t offset, int whence);
00044 static int posix_read(IOFileRef f, void *buf, size_t count);
00045 static off_t posix_filesize(IOFileRef f);
00046 static void *posix_mmap(IOFileRef f, size_t length, off_t offset);
00047 static int posix_munmap(IOFileRef f, void *addr, size_t length);
00048
00050 struct io_methods posix_io_methods = {
00051 &posix_open,
00052 &posix_close,
00053 &posix_seek,
00054 &posix_read,
00055 &posix_filesize,
00056 &posix_mmap,
00057 &posix_munmap
00058 };
00059
00060
00062 static IOFileRef posix_open(const char *path, int mode)
00063 {
00064 struct io_data_posix *data =
00065 (struct io_data_posix *)malloc(sizeof(struct io_data_posix));
00066 IOFileRef f = (IOFileRef)malloc(sizeof(struct _IOFile));
00067
00068 memset(f, 0, sizeof(struct _IOFile));
00069 memset(data, 0, sizeof(struct io_data_posix));
00070
00071 f->methods = &posix_io_methods;
00072 f->_private = data;
00073 f->path = strdup(path);
00074 data->fd = open(path, mode);
00075 if (data->fd == -1) {
00076 free(data);
00077 free(f);
00078 f = NULL;
00079 }
00080
00081
00082 return f;
00083 }
00084
00085
00086
00088 static int posix_close(IOFileRef f)
00089 {
00090 int retval = 0;
00091 struct io_data_posix *data = (struct io_data_posix*)f->_private;
00092
00093 retval = close(data->fd);
00094 free(data);
00095 free(f->path);
00096 return retval;
00097 }
00098
00099
00101 static int posix_seek(IOFileRef f, off_t offset, int whence)
00102 {
00103 int retval = 0;
00104 struct io_data_posix *data = (struct io_data_posix*)f->_private;
00105
00106 retval = lseek(data->fd, offset, whence);
00107 if (retval == -1) {
00108 f->error = errno;
00109 }
00110 else {
00111 f->error = 0;
00112 }
00113 return retval;
00114 }
00115
00116
00118 static int posix_read(IOFileRef f, void *buf, size_t count)
00119 {
00120 int retval = 0;
00121 struct io_data_posix *data = (struct io_data_posix*)f->_private;
00122
00123 retval = read(data->fd, buf, count);
00124 if (retval == -1) {
00125 f->error = errno;
00126 }
00127 else {
00128 f->error = 0;
00129 }
00130 return retval;
00131 }
00132
00133
00134 static off_t posix_filesize(IOFileRef f)
00135 {
00136 off_t size = -1;
00137 struct io_data_posix *data = (struct io_data_posix*)f->_private;
00138 struct stat sb;
00139
00140 if(fstat(data->fd, &sb) >= 0) {
00141 size = sb.st_size;
00142 }
00143
00144 return size;
00145 }
00146
00147
00148
00149 static void *posix_mmap(IOFileRef f, size_t length, off_t offset)
00150 {
00151 struct io_data_posix *data = (struct io_data_posix*)f->_private;
00152
00153 return mmap(NULL, length, PROT_READ, MAP_SHARED, data->fd, offset);
00154 }
00155
00156
00157 static int posix_munmap(IOFileRef f, void *addr, size_t length)
00158 {
00159 (void)f;
00160 return munmap(addr, length);
00161 }