]> git.proxmox.com Git - libgit2.git/blame - src/posix.c
treebuilder: fix memory leaks in `write_with_buffer`
[libgit2.git] / src / posix.c
CommitLineData
bb742ede 1/*
359fc2d2 2 * Copyright (C) the libgit2 contributors. All rights reserved.
bb742ede
VM
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
f79026b4
VM
7#include "common.h"
8#include "posix.h"
9#include "path.h"
10#include <stdio.h>
11#include <ctype.h>
12
e6ed0d2f
ET
13size_t p_fsync__cnt = 0;
14
7998ae5a
PB
15#ifndef GIT_WIN32
16
798e4d53 17#ifdef NO_ADDRINFO
71d62d39 18
798e4d53
VM
19int p_getaddrinfo(
20 const char *host,
21 const char *port,
22 struct addrinfo *hints,
23 struct addrinfo **info)
24{
798e4d53
VM
25 struct addrinfo *ainfo, *ai;
26 int p = 0;
71d62d39
RB
27
28 GIT_UNUSED(hints);
29
798e4d53
VM
30 if ((ainfo = malloc(sizeof(struct addrinfo))) == NULL)
31 return -1;
71d62d39
RB
32
33 if ((ainfo->ai_hostent = gethostbyname(host)) == NULL) {
34 free(ainfo);
798e4d53 35 return -2;
71d62d39
RB
36 }
37
798e4d53 38 ainfo->ai_servent = getservbyname(port, 0);
71d62d39 39
798e4d53
VM
40 if (ainfo->ai_servent)
41 ainfo->ai_port = ainfo->ai_servent->s_port;
42 else
43 ainfo->ai_port = atol(port);
44
45 memcpy(&ainfo->ai_addr_in.sin_addr,
46 ainfo->ai_hostent->h_addr_list[0],
47 ainfo->ai_hostent->h_length);
48
49 ainfo->ai_protocol = 0;
50 ainfo->ai_socktype = hints->ai_socktype;
51 ainfo->ai_family = ainfo->ai_hostent->h_addrtype;
52 ainfo->ai_addr_in.sin_family = ainfo->ai_family;
53 ainfo->ai_addr_in.sin_port = ainfo->ai_port;
54 ainfo->ai_addr = (struct addrinfo *)&ainfo->ai_addr_in;
55 ainfo->ai_addrlen = sizeof(struct sockaddr_in);
56
57 *info = ainfo;
71d62d39 58
798e4d53
VM
59 if (ainfo->ai_hostent->h_addr_list[1] == NULL) {
60 ainfo->ai_next = NULL;
61 return 0;
62 }
71d62d39 63
798e4d53 64 ai = ainfo;
71d62d39 65
798e4d53 66 for (p = 1; ainfo->ai_hostent->h_addr_list[p] != NULL; p++) {
ea5942b4
SB
67 if (!(ai->ai_next = malloc(sizeof(struct addrinfo)))) {
68 p_freeaddrinfo(ainfo);
69 return -1;
70 }
9f9df4b6 71 memcpy(ai->ai_next, ainfo, sizeof(struct addrinfo));
798e4d53
VM
72 memcpy(&ai->ai_next->ai_addr_in.sin_addr,
73 ainfo->ai_hostent->h_addr_list[p],
74 ainfo->ai_hostent->h_length);
75 ai->ai_next->ai_addr = (struct addrinfo *)&ai->ai_next->ai_addr_in;
76 ai = ai->ai_next;
77 }
71d62d39 78
798e4d53
VM
79 ai->ai_next = NULL;
80 return 0;
81}
82
83void p_freeaddrinfo(struct addrinfo *info)
84{
85 struct addrinfo *p, *next;
71d62d39 86
798e4d53 87 p = info;
71d62d39 88
798e4d53
VM
89 while(p != NULL) {
90 next = p->ai_next;
91 free(p);
92 p = next;
93 }
94}
95
96const char *p_gai_strerror(int ret)
97{
98 switch(ret) {
71d62d39
RB
99 case -1: return "Out of memory"; break;
100 case -2: return "Address lookup failed"; break;
101 default: return "Unknown error"; break;
798e4d53
VM
102 }
103}
71d62d39 104
798e4d53
VM
105#endif /* NO_ADDRINFO */
106
6a1ca96e 107int p_open(const char *path, volatile int flags, ...)
f79026b4 108{
3191ae89 109 mode_t mode = 0;
110
71d62d39 111 if (flags & O_CREAT) {
3191ae89 112 va_list arg_list;
113
114 va_start(arg_list, flags);
19579847 115 mode = (mode_t)va_arg(arg_list, int);
3191ae89 116 va_end(arg_list);
117 }
118
3d3ea4dc 119 return open(path, flags | O_BINARY | O_CLOEXEC, mode);
f79026b4
VM
120}
121
33127043 122int p_creat(const char *path, mode_t mode)
f79026b4 123{
3d3ea4dc 124 return open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC, mode);
f79026b4
VM
125}
126
7998ae5a
PB
127int p_getcwd(char *buffer_out, size_t size)
128{
129 char *cwd_buffer;
130
131 assert(buffer_out && size > 0);
132
133 cwd_buffer = getcwd(buffer_out, size);
134
135 if (cwd_buffer == NULL)
dda708e7 136 return -1;
7998ae5a
PB
137
138 git_path_mkposix(buffer_out);
deafee7b 139 git_path_string_to_dir(buffer_out, size); /* append trailing slash */
97769280 140
deafee7b 141 return 0;
7998ae5a
PB
142}
143
0c49ec2d
CMN
144int p_rename(const char *from, const char *to)
145{
146 if (!link(from, to)) {
147 p_unlink(from);
dda708e7 148 return 0;
0c49ec2d
CMN
149 }
150
151 if (!rename(from, to))
dda708e7 152 return 0;
0c49ec2d 153
dda708e7 154 return -1;
0c49ec2d
CMN
155}
156
798e4d53 157#endif /* GIT_WIN32 */
7998ae5a 158
c6ba8a37 159ssize_t p_read(git_file fd, void *buf, size_t cnt)
f79026b4
VM
160{
161 char *b = buf;
71d62d39 162
8d534b47
ET
163 if (!git__is_ssizet(cnt)) {
164#ifdef GIT_WIN32
165 SetLastError(ERROR_INVALID_PARAMETER);
166#endif
167 errno = EINVAL;
168 return -1;
169 }
170
f79026b4 171 while (cnt) {
44ef8b1b
RB
172 ssize_t r;
173#ifdef GIT_WIN32
c6ba8a37 174 r = read(fd, b, cnt > INT_MAX ? INT_MAX : (unsigned int)cnt);
44ef8b1b
RB
175#else
176 r = read(fd, b, cnt);
177#endif
f79026b4
VM
178 if (r < 0) {
179 if (errno == EINTR || errno == EAGAIN)
180 continue;
dda708e7 181 return -1;
f79026b4
VM
182 }
183 if (!r)
184 break;
185 cnt -= r;
186 b += r;
187 }
c6ba8a37 188 return (b - (char *)buf);
f79026b4
VM
189}
190
2ba222c5 191int p_write(git_file fd, const void *buf, size_t cnt)
f79026b4 192{
2ba222c5 193 const char *b = buf;
71d62d39 194
f79026b4 195 while (cnt) {
44ef8b1b
RB
196 ssize_t r;
197#ifdef GIT_WIN32
198 assert((size_t)((unsigned int)cnt) == cnt);
199 r = write(fd, b, (unsigned int)cnt);
200#else
201 r = write(fd, b, cnt);
202#endif
f79026b4 203 if (r < 0) {
0197d410 204 if (errno == EINTR || GIT_ISBLOCKED(errno))
f79026b4 205 continue;
dda708e7 206 return -1;
f79026b4
VM
207 }
208 if (!r) {
209 errno = EPIPE;
dda708e7 210 return -1;
f79026b4
VM
211 }
212 cnt -= r;
213 b += r;
214 }
dda708e7 215 return 0;
f79026b4 216}
345eef23 217
7697e541 218#ifdef NO_MMAP
345eef23 219
7697e541
RB
220#include "map.h"
221
62e562f9 222int git__page_size(size_t *page_size)
f7310540
CMN
223{
224 /* dummy; here we don't need any alignment anyway */
62e562f9
AM
225 *page_size = 4096;
226 return 0;
f7310540
CMN
227}
228
87c18197
CMN
229int git__mmap_alignment(size_t *alignment)
230{
231 /* dummy; here we don't need any alignment anyway */
232 *alignment = 4096;
233 return 0;
234}
235
f7310540 236
7697e541
RB
237int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset)
238{
239 GIT_MMAP_VALIDATE(out, len, prot, flags);
240
241 out->data = NULL;
242 out->len = 0;
243
244 if ((prot & GIT_PROT_WRITE) && ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)) {
909d5494 245 giterr_set(GITERR_OS, "trying to map shared-writeable");
7697e541
RB
246 return -1;
247 }
248
249 out->data = malloc(len);
250 GITERR_CHECK_ALLOC(out->data);
251
8d534b47
ET
252 if (!git__is_ssizet(len) ||
253 (p_lseek(fd, offset, SEEK_SET) < 0) ||
254 (p_read(fd, out->data, len) != (ssize_t)len)) {
7697e541
RB
255 giterr_set(GITERR_OS, "mmap emulation failed");
256 return -1;
257 }
258
259 out->len = len;
260 return 0;
261}
262
263int p_munmap(git_map *map)
264{
265 assert(map != NULL);
266 free(map->data);
267
268 return 0;
269}
270
271#endif