Fix coding rule violation
[platform/core/system/tizen-platform-config.git] / src / buffer.c
1 /*
2  * Copyright (C) 2013-2014 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                 } else if (errno != EAGAIN && errno != EINTR) {
66                         free(memory);
67                         return -1;
68                 }
69         }
70 }
71
72 int buffer_create(struct buffer *buffer, const char *pathname)
73 {
74         int fd, result;
75         struct stat bstat;
76         void *memory;
77         size_t length;
78
79         result = open(pathname, O_RDONLY);
80         if (result >= 0) {
81                 fd = result;
82                 result = fstat(fd, &bstat);
83                 if (result == 0) {
84                         length = (size_t)bstat.st_size;
85                         if (bstat.st_size != (off_t)length) {
86                                 errno = EOVERFLOW;
87                                 result = -1;
88                         } else {
89                                 memory = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
90                                 if (memory != MAP_FAILED) {
91                                         buffer->buffer = memory;
92                                         buffer->length = length;
93                                         buffer->mapped = 1;
94                                 } else {
95                                         result = buffread(buffer, fd);
96                                 }
97                         }
98                 }
99                 close(fd);
100         }
101         return result;
102 }
103
104 int buffer_destroy(struct buffer *buffer)
105 {
106         if (buffer->mapped)
107                 return munmap(buffer->buffer, buffer->length);
108         free(buffer->buffer);
109         return 0;
110 }
111