]> git.proxmox.com Git - libgit2.git/blame - src/posix.c
Bump debhelper compatibility level to 13
[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 */
eae0bfdc 7
f79026b4 8#include "posix.h"
eae0bfdc 9
f79026b4
VM
10#include "path.h"
11#include <stdio.h>
12#include <ctype.h>
13
e6ed0d2f
ET
14size_t p_fsync__cnt = 0;
15
7998ae5a
PB
16#ifndef GIT_WIN32
17
798e4d53 18#ifdef NO_ADDRINFO
71d62d39 19
798e4d53
VM
20int p_getaddrinfo(
21 const char *host,
22 const char *port,
23 struct addrinfo *hints,
24 struct addrinfo **info)
25{
798e4d53
VM
26 struct addrinfo *ainfo, *ai;
27 int p = 0;
71d62d39
RB
28
29 GIT_UNUSED(hints);
30
22a2d3d5 31 if ((ainfo = git__malloc(sizeof(struct addrinfo))) == NULL)
798e4d53 32 return -1;
71d62d39
RB
33
34 if ((ainfo->ai_hostent = gethostbyname(host)) == NULL) {
22a2d3d5 35 git__free(ainfo);
798e4d53 36 return -2;
71d62d39
RB
37 }
38
798e4d53 39 ainfo->ai_servent = getservbyname(port, 0);
71d62d39 40
798e4d53
VM
41 if (ainfo->ai_servent)
42 ainfo->ai_port = ainfo->ai_servent->s_port;
43 else
eae0bfdc 44 ainfo->ai_port = htons(atol(port));
798e4d53
VM
45
46 memcpy(&ainfo->ai_addr_in.sin_addr,
47 ainfo->ai_hostent->h_addr_list[0],
48 ainfo->ai_hostent->h_length);
49
50 ainfo->ai_protocol = 0;
51 ainfo->ai_socktype = hints->ai_socktype;
52 ainfo->ai_family = ainfo->ai_hostent->h_addrtype;
53 ainfo->ai_addr_in.sin_family = ainfo->ai_family;
54 ainfo->ai_addr_in.sin_port = ainfo->ai_port;
55 ainfo->ai_addr = (struct addrinfo *)&ainfo->ai_addr_in;
56 ainfo->ai_addrlen = sizeof(struct sockaddr_in);
57
58 *info = ainfo;
71d62d39 59
798e4d53
VM
60 if (ainfo->ai_hostent->h_addr_list[1] == NULL) {
61 ainfo->ai_next = NULL;
62 return 0;
63 }
71d62d39 64
798e4d53 65 ai = ainfo;
71d62d39 66
798e4d53 67 for (p = 1; ainfo->ai_hostent->h_addr_list[p] != NULL; p++) {
22a2d3d5 68 if (!(ai->ai_next = git__malloc(sizeof(struct addrinfo)))) {
ea5942b4
SB
69 p_freeaddrinfo(ainfo);
70 return -1;
71 }
9f9df4b6 72 memcpy(ai->ai_next, ainfo, sizeof(struct addrinfo));
798e4d53
VM
73 memcpy(&ai->ai_next->ai_addr_in.sin_addr,
74 ainfo->ai_hostent->h_addr_list[p],
75 ainfo->ai_hostent->h_length);
76 ai->ai_next->ai_addr = (struct addrinfo *)&ai->ai_next->ai_addr_in;
77 ai = ai->ai_next;
78 }
71d62d39 79
798e4d53
VM
80 ai->ai_next = NULL;
81 return 0;
82}
83
84void p_freeaddrinfo(struct addrinfo *info)
85{
86 struct addrinfo *p, *next;
71d62d39 87
798e4d53 88 p = info;
71d62d39 89
798e4d53
VM
90 while(p != NULL) {
91 next = p->ai_next;
22a2d3d5 92 git__free(p);
798e4d53
VM
93 p = next;
94 }
95}
96
97const char *p_gai_strerror(int ret)
98{
99 switch(ret) {
71d62d39
RB
100 case -1: return "Out of memory"; break;
101 case -2: return "Address lookup failed"; break;
102 default: return "Unknown error"; break;
798e4d53
VM
103 }
104}
71d62d39 105
798e4d53
VM
106#endif /* NO_ADDRINFO */
107
6a1ca96e 108int p_open(const char *path, volatile int flags, ...)
f79026b4 109{
3191ae89 110 mode_t mode = 0;
111
c25aa7cd
PP
112 #ifdef GIT_DEBUG_STRICT_OPEN
113 if (strstr(path, "//") != NULL) {
114 errno = EACCES;
115 return -1;
116 }
117 #endif
118
71d62d39 119 if (flags & O_CREAT) {
3191ae89 120 va_list arg_list;
121
122 va_start(arg_list, flags);
19579847 123 mode = (mode_t)va_arg(arg_list, int);
3191ae89 124 va_end(arg_list);
125 }
126
3d3ea4dc 127 return open(path, flags | O_BINARY | O_CLOEXEC, mode);
f79026b4
VM
128}
129
33127043 130int p_creat(const char *path, mode_t mode)
f79026b4 131{
3d3ea4dc 132 return open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC, mode);
f79026b4
VM
133}
134
7998ae5a
PB
135int p_getcwd(char *buffer_out, size_t size)
136{
137 char *cwd_buffer;
138
c25aa7cd
PP
139 GIT_ASSERT_ARG(buffer_out);
140 GIT_ASSERT_ARG(size > 0);
7998ae5a
PB
141
142 cwd_buffer = getcwd(buffer_out, size);
143
144 if (cwd_buffer == NULL)
dda708e7 145 return -1;
7998ae5a
PB
146
147 git_path_mkposix(buffer_out);
deafee7b 148 git_path_string_to_dir(buffer_out, size); /* append trailing slash */
97769280 149
deafee7b 150 return 0;
7998ae5a
PB
151}
152
0c49ec2d
CMN
153int p_rename(const char *from, const char *to)
154{
155 if (!link(from, to)) {
156 p_unlink(from);
dda708e7 157 return 0;
0c49ec2d
CMN
158 }
159
160 if (!rename(from, to))
dda708e7 161 return 0;
0c49ec2d 162
dda708e7 163 return -1;
0c49ec2d
CMN
164}
165
798e4d53 166#endif /* GIT_WIN32 */
7998ae5a 167
c6ba8a37 168ssize_t p_read(git_file fd, void *buf, size_t cnt)
f79026b4
VM
169{
170 char *b = buf;
71d62d39 171
8d534b47
ET
172 if (!git__is_ssizet(cnt)) {
173#ifdef GIT_WIN32
174 SetLastError(ERROR_INVALID_PARAMETER);
175#endif
176 errno = EINVAL;
177 return -1;
178 }
179
f79026b4 180 while (cnt) {
44ef8b1b
RB
181 ssize_t r;
182#ifdef GIT_WIN32
c6ba8a37 183 r = read(fd, b, cnt > INT_MAX ? INT_MAX : (unsigned int)cnt);
44ef8b1b
RB
184#else
185 r = read(fd, b, cnt);
186#endif
f79026b4
VM
187 if (r < 0) {
188 if (errno == EINTR || errno == EAGAIN)
189 continue;
dda708e7 190 return -1;
f79026b4
VM
191 }
192 if (!r)
193 break;
194 cnt -= r;
195 b += r;
196 }
c6ba8a37 197 return (b - (char *)buf);
f79026b4
VM
198}
199
2ba222c5 200int p_write(git_file fd, const void *buf, size_t cnt)
f79026b4 201{
2ba222c5 202 const char *b = buf;
71d62d39 203
f79026b4 204 while (cnt) {
44ef8b1b
RB
205 ssize_t r;
206#ifdef GIT_WIN32
c25aa7cd 207 GIT_ASSERT((size_t)((unsigned int)cnt) == cnt);
44ef8b1b
RB
208 r = write(fd, b, (unsigned int)cnt);
209#else
210 r = write(fd, b, cnt);
211#endif
f79026b4 212 if (r < 0) {
0197d410 213 if (errno == EINTR || GIT_ISBLOCKED(errno))
f79026b4 214 continue;
dda708e7 215 return -1;
f79026b4
VM
216 }
217 if (!r) {
218 errno = EPIPE;
dda708e7 219 return -1;
f79026b4
VM
220 }
221 cnt -= r;
222 b += r;
223 }
dda708e7 224 return 0;
f79026b4 225}
345eef23 226
7697e541 227#ifdef NO_MMAP
345eef23 228
7697e541
RB
229#include "map.h"
230
62e562f9 231int git__page_size(size_t *page_size)
f7310540
CMN
232{
233 /* dummy; here we don't need any alignment anyway */
62e562f9
AM
234 *page_size = 4096;
235 return 0;
f7310540
CMN
236}
237
87c18197
CMN
238int git__mmap_alignment(size_t *alignment)
239{
240 /* dummy; here we don't need any alignment anyway */
241 *alignment = 4096;
242 return 0;
243}
244
f7310540 245
22a2d3d5 246int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset)
7697e541 247{
c25aa7cd
PP
248 const char *ptr;
249 size_t remaining_len;
250
7697e541
RB
251 GIT_MMAP_VALIDATE(out, len, prot, flags);
252
c25aa7cd
PP
253 /* writes cannot be emulated without handling pagefaults since write happens by
254 * writing to mapped memory */
255 if (prot & GIT_PROT_WRITE) {
256 git_error_set(GIT_ERROR_OS, "trying to map %s-writeable",
257 ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED) ? "shared": "private");
258 return -1;
259 }
7697e541 260
c25aa7cd
PP
261 if (!git__is_ssizet(len)) {
262 errno = EINVAL;
7697e541
RB
263 return -1;
264 }
265
c25aa7cd 266 out->len = 0;
22a2d3d5 267 out->data = git__malloc(len);
ac3d33df 268 GIT_ERROR_CHECK_ALLOC(out->data);
7697e541 269
c25aa7cd
PP
270 remaining_len = len;
271 ptr = (const char *)out->data;
272 while (remaining_len > 0) {
273 ssize_t nb;
274 HANDLE_EINTR(nb, p_pread(fd, (void *)ptr, remaining_len, offset));
275 if (nb <= 0) {
276 git_error_set(GIT_ERROR_OS, "mmap emulation failed");
277 git__free(out->data);
278 out->data = NULL;
279 return -1;
280 }
281
282 ptr += nb;
283 offset += nb;
284 remaining_len -= nb;
7697e541
RB
285 }
286
287 out->len = len;
288 return 0;
289}
290
291int p_munmap(git_map *map)
292{
c25aa7cd 293 GIT_ASSERT_ARG(map);
22a2d3d5 294 git__free(map->data);
7697e541 295
c25aa7cd
PP
296 /* Initializing will help debug use-after-free */
297 map->len = 0;
298 map->data = NULL;
299
7697e541
RB
300 return 0;
301}
302
303#endif