gerb_file.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00029 #ifdef HAVE_CONFIG_H
00030 #include "config.h"
00031 #endif
00032
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 #include <string.h>
00036
00037 #include <sys/types.h>
00038 #include <sys/stat.h>
00039 #ifdef HAVE_UNISTD_H
00040 #include <unistd.h>
00041 #endif
00042 #ifdef HAVE_SYS_MMAN_H
00043 #include <sys/mman.h>
00044 #endif
00045 #include <errno.h>
00046
00047 #include "gerbv.h"
00048 #include "gerb_file.h"
00049
00050
00051 #define dprintf if(DEBUG) printf
00052
00053 gerb_file_t *
00054 gerb_fopen(char const * filename)
00055 {
00056 gerb_file_t *fd;
00057 struct stat statinfo;
00058
00059 dprintf("---> Entering gerb_fopen, filename = %s\n", filename);
00060 #ifdef HAVE_SYS_MMAN_H
00061 fd = (gerb_file_t *)g_malloc(sizeof(gerb_file_t));
00062 if (fd == NULL) {
00063 return NULL;
00064 }
00065
00066 dprintf(" Doing fopen\n");
00067 fd->fd = fopen(filename, "r");
00068 if (fd->fd == NULL) {
00069 g_free(fd);
00070 return NULL;
00071 }
00072
00073 dprintf(" Doing fstat\n");
00074 fd->ptr = 0;
00075 fd->fileno = fileno(fd->fd);
00076 if (fstat(fd->fileno, &statinfo) < 0) {
00077 fclose(fd->fd);
00078 g_free(fd);
00079 return NULL;
00080 }
00081
00082 dprintf(" Checking S_ISREG\n");
00083 if (!S_ISREG(statinfo.st_mode)) {
00084 fclose(fd->fd);
00085 g_free(fd);
00086 errno = EISDIR;
00087 return NULL;
00088 }
00089
00090 dprintf(" Checking statinfo.st_size\n");
00091 if ((int)statinfo.st_size == 0) {
00092 fclose(fd->fd);
00093 g_free(fd);
00094 errno = EIO;
00095 return NULL;
00096 }
00097
00098 dprintf(" Doing mmap\n");
00099 fd->datalen = (int)statinfo.st_size;
00100 fd->data = (char *)mmap(0, statinfo.st_size, PROT_READ, MAP_PRIVATE,
00101 fd->fileno, 0);
00102 if(fd->data == MAP_FAILED) {
00103 fclose(fd->fd);
00104 g_free(fd);
00105 fd = NULL;
00106 }
00107 #else
00108
00109 fd = (gerb_file_t *)g_malloc(sizeof(gerb_file_t));
00110 if (fd == NULL) {
00111 return NULL;
00112 }
00113
00114 if (stat(filename, &statinfo) < 0) {
00115 fclose(fd->fd);
00116 g_free(fd);
00117 return NULL;
00118 }
00119
00120 fd->fd = fopen(filename, "rb");
00121 fd->ptr = 0;
00122 fd->fileno = fileno(fd->fd);
00123 if (fstat(fd->fileno, &statinfo) < 0) {
00124 fclose(fd->fd);
00125 g_free(fd);
00126 return NULL;
00127 }
00128 if (!S_ISREG(statinfo.st_mode)) {
00129 fclose(fd->fd);
00130 g_free(fd);
00131 errno = EISDIR;
00132 return NULL;
00133 }
00134 if ((int)statinfo.st_size == 0) {
00135 fclose(fd->fd);
00136 g_free(fd);
00137 errno = EIO;
00138 return NULL;
00139 }
00140 fd->datalen = (int)statinfo.st_size;
00141 fd->data = calloc(1, statinfo.st_size + 1);
00142 if (fd->data == NULL) {
00143 fclose(fd->fd);
00144 g_free(fd);
00145 return NULL;
00146 }
00147 if (fread((void*)fd->data, 1, statinfo.st_size, fd->fd) != statinfo.st_size) {
00148 fclose(fd->fd);
00149 g_free(fd->data);
00150 g_free(fd);
00151 return NULL;
00152 }
00153 rewind (fd->fd);
00154 #endif
00155
00156 dprintf("<--- Leaving gerb_fopen\n");
00157 return fd;
00158 }
00159
00160
00161 int
00162 gerb_fgetc(gerb_file_t *fd)
00163 {
00164
00165 if (fd->ptr >= fd->datalen)
00166 return EOF;
00167
00168 return (int) fd->data[fd->ptr++];
00169 }
00170
00171
00172 int
00173 gerb_fgetint(gerb_file_t *fd, int *len)
00174 {
00175 long int result;
00176 char *end;
00177
00178 errno = 0;
00179 result = strtol(fd->data + fd->ptr, &end, 10);
00180 if (errno) {
00181 GERB_COMPILE_ERROR("Failed to read integer");
00182 return 0;
00183 }
00184
00185 if (len) {
00186 *len = end - (fd->data + fd->ptr);
00187 }
00188
00189 fd->ptr = end - fd->data;
00190
00191 if (len && (result < 0))
00192 *len -= 1;
00193
00194 return (int)result;
00195 }
00196
00197
00198 double
00199 gerb_fgetdouble(gerb_file_t *fd)
00200 {
00201 double result;
00202 char *end;
00203
00204 errno = 0;
00205 result = strtod(fd->data + fd->ptr, &end);
00206 if (errno) {
00207 GERB_COMPILE_ERROR("Failed to read double");
00208 return 0.0;
00209 }
00210
00211 fd->ptr = end - fd->data;
00212
00213 return result;
00214 }
00215
00216
00217 char *
00218 gerb_fgetstring(gerb_file_t *fd, char term)
00219 {
00220 char *strend = NULL;
00221 char *newstr;
00222 char *i, *iend;
00223 int len;
00224
00225 iend = fd->data + fd->datalen;
00226 for (i = fd->data + fd->ptr; i < iend; i++) {
00227 if (*i == term) {
00228 strend = i;
00229 break;
00230 }
00231 }
00232
00233 if (strend == NULL)
00234 return NULL;
00235
00236 len = strend - (fd->data + fd->ptr);
00237
00238 newstr = (char *)g_malloc(len + 1);
00239 if (newstr == NULL)
00240 return NULL;
00241 strncpy(newstr, fd->data + fd->ptr, len);
00242 newstr[len] = '\0';
00243 fd->ptr += len;
00244
00245 return newstr;
00246 }
00247
00248
00249 void
00250 gerb_ungetc(gerb_file_t *fd)
00251 {
00252 if (fd->ptr)
00253 fd->ptr--;
00254
00255 return;
00256 }
00257
00258
00259 void
00260 gerb_fclose(gerb_file_t *fd)
00261 {
00262 if (fd) {
00263 #ifdef HAVE_SYS_MMAN_H
00264 if (munmap(fd->data, fd->datalen) < 0)
00265 GERB_FATAL_ERROR("munmap:%s", strerror(errno));
00266 #else
00267 g_free(fd->data);
00268 #endif
00269 if (fclose(fd->fd) == EOF)
00270 GERB_FATAL_ERROR("fclose:%s", strerror(errno));
00271 g_free(fd);
00272 }
00273
00274 return;
00275 }
00276
00277
00278 char *
00279 gerb_find_file(char const * filename, char **paths)
00280 {
00281 char *curr_path = NULL;
00282 char *complete_path = NULL;
00283 int i;
00284
00285 for (i = 0; paths[i] != NULL; i++) {
00286
00287
00288
00289
00290 if (paths[i][0] == '$') {
00291 char *env_name, *env_value, *tmp;
00292 int len;
00293
00294
00295
00296 tmp = strchr(paths[i], G_DIR_SEPARATOR);
00297 if (tmp == NULL)
00298 len = strlen(paths[i]) - 1;
00299 else
00300 len = tmp - paths[i] - 1;
00301 env_name = (char *)g_malloc(len + 1);
00302 if (env_name == NULL)
00303 return NULL;
00304 strncpy(env_name, (char *)(paths[i] + 1), len);
00305 env_name[len] = '\0';
00306
00307 env_value = getenv(env_name);
00308 if (env_value == NULL) break;
00309 curr_path = (char *)g_malloc(strlen(env_value) + strlen(&paths[i][len + 1]) + 1);
00310 if (curr_path == NULL)
00311 return NULL;
00312 strcpy(curr_path, env_value);
00313 strcat(curr_path, &paths[i][len + 1]);
00314 g_free(env_name);
00315 } else {
00316 curr_path = paths[i];
00317 }
00318
00319
00320
00321
00322 complete_path = (char *)g_malloc(strlen(curr_path) + strlen(filename) + 2);
00323 if (complete_path == NULL)
00324 return NULL;
00325 strcpy(complete_path, curr_path);
00326 complete_path[strlen(curr_path)] = G_DIR_SEPARATOR;
00327 complete_path[strlen(curr_path) + 1] = '\0';
00328 strncat(complete_path, filename, strlen(filename));
00329
00330 if (paths[i][0] == '$') {
00331 g_free(curr_path);
00332 curr_path = NULL;
00333 }
00334
00335 if (access(complete_path, R_OK) != -1)
00336 break;
00337
00338 g_free(complete_path);
00339 complete_path = NULL;
00340 }
00341
00342 if (complete_path == NULL)
00343 errno = ENOENT;
00344
00345 return complete_path;
00346 }