libopenraw
|
00001 /* 00002 * libopenraw - posix_io.c 00003 * 00004 * Copyright (C) 2005 Hubert Figuiere 00005 * 00006 * This library is free software: you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public License 00008 * as published by the Free Software Foundation, either version 3 of 00009 * the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library. If not, see 00018 * <http://www.gnu.org/licenses/>. 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 }