1a72e76654c09035d10900cb0a46798532113e24
[platform/core/system/tizen-platform-wrapper.git] / src / buffer.c
1 /*
2  * Copyright (C) 2013 Intel Corporation.
3  * 
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  * Authors:
19  *   José Bollo <jose.bollo@open.eurogiciel.org>
20  *   Stéphane Desneux <stephane.desneux@open.eurogiciel.org>
21  *   Jean-Benoit Martin <jean-benoit.martin@open.eurogiciel.org>
22  *
23  */
24
25 #define _GNU_SOURCE
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <errno.h>
35 #include <sys/mman.h>
36 #include <sys/stat.h>
37
38 #include "buffer.h"
39
40 static int buffread( struct buffer *buffer, int fd)
41 {
42     const int size = 4096;
43     void *p;
44     char *memory = NULL;
45     size_t length = 0;
46     ssize_t status;
47
48     /* do read */
49     for(;;) {
50         p = realloc( memory, length + size);
51         if (p == NULL) {
52             free( memory);
53             return -1;
54         }
55         memory = p;
56         status = read( fd, memory+length, size);
57         if (status == 0) {
58             buffer->buffer = memory;
59             buffer->length = length;
60             buffer->mapped = 0;
61             return 0;
62         }
63         if (status > 0) {
64             length = length + (int)status;
65         }
66         else if (errno != EAGAIN && errno != EINTR) {
67             free( memory);
68             return -1;
69         }   
70     }
71 }
72
73 int buffer_create( struct buffer *buffer, const char *pathname)
74 {
75     int fd, result;
76     struct stat bstat;
77     void *memory;
78     size_t length;
79
80     result = open(pathname, O_RDONLY);
81     if (result >= 0)
82     {
83         fd = result;
84         result = fstat(fd, &bstat);
85         if (result == 0)
86         {
87             length = (size_t)bstat.st_size;
88             if (bstat.st_size != (off_t)length)
89             {
90                 errno = EOVERFLOW;
91                 result = -1;
92             }
93             else
94             {
95                 memory = mmap(NULL,length,PROT_READ,MAP_PRIVATE,fd,0);
96                 if (memory != MAP_FAILED) {
97                     buffer->buffer = memory;
98                     buffer->length = length;
99                     buffer->mapped = 1;
100                 }
101                 else {
102                     result = buffread( buffer, fd);
103                 }
104             }
105         }
106         close(fd);
107     }
108     return result;
109 }
110
111 int buffer_destroy( struct buffer *buffer)
112 {
113     if (buffer->mapped)
114         return munmap(buffer->buffer, buffer->length);
115     free( buffer->buffer);
116     return 0;
117 }
118
119