]>
Commit | Line | Data |
---|---|---|
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 |
14 | size_t p_fsync__cnt = 0; |
15 | ||
7998ae5a PB |
16 | #ifndef GIT_WIN32 |
17 | ||
798e4d53 | 18 | #ifdef NO_ADDRINFO |
71d62d39 | 19 | |
798e4d53 VM |
20 | int 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 | ||
0c9c969a | 31 | if ((ainfo = git__malloc(sizeof(struct addrinfo))) == NULL) |
798e4d53 | 32 | return -1; |
71d62d39 RB |
33 | |
34 | if ((ainfo->ai_hostent = gethostbyname(host)) == NULL) { | |
0c9c969a | 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++) { |
0c9c969a | 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 | ||
84 | void 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; | |
0c9c969a | 92 | git__free(p); |
798e4d53 VM |
93 | p = next; |
94 | } | |
95 | } | |
96 | ||
97 | const 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 | 108 | int p_open(const char *path, volatile int flags, ...) |
f79026b4 | 109 | { |
3191ae89 | 110 | mode_t mode = 0; |
111 | ||
71d62d39 | 112 | if (flags & O_CREAT) { |
3191ae89 | 113 | va_list arg_list; |
114 | ||
115 | va_start(arg_list, flags); | |
19579847 | 116 | mode = (mode_t)va_arg(arg_list, int); |
3191ae89 | 117 | va_end(arg_list); |
118 | } | |
119 | ||
3d3ea4dc | 120 | return open(path, flags | O_BINARY | O_CLOEXEC, mode); |
f79026b4 VM |
121 | } |
122 | ||
33127043 | 123 | int p_creat(const char *path, mode_t mode) |
f79026b4 | 124 | { |
3d3ea4dc | 125 | return open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC, mode); |
f79026b4 VM |
126 | } |
127 | ||
7998ae5a PB |
128 | int p_getcwd(char *buffer_out, size_t size) |
129 | { | |
130 | char *cwd_buffer; | |
131 | ||
132 | assert(buffer_out && size > 0); | |
133 | ||
134 | cwd_buffer = getcwd(buffer_out, size); | |
135 | ||
136 | if (cwd_buffer == NULL) | |
dda708e7 | 137 | return -1; |
7998ae5a PB |
138 | |
139 | git_path_mkposix(buffer_out); | |
deafee7b | 140 | git_path_string_to_dir(buffer_out, size); /* append trailing slash */ |
97769280 | 141 | |
deafee7b | 142 | return 0; |
7998ae5a PB |
143 | } |
144 | ||
0c49ec2d CMN |
145 | int p_rename(const char *from, const char *to) |
146 | { | |
147 | if (!link(from, to)) { | |
148 | p_unlink(from); | |
dda708e7 | 149 | return 0; |
0c49ec2d CMN |
150 | } |
151 | ||
152 | if (!rename(from, to)) | |
dda708e7 | 153 | return 0; |
0c49ec2d | 154 | |
dda708e7 | 155 | return -1; |
0c49ec2d CMN |
156 | } |
157 | ||
798e4d53 | 158 | #endif /* GIT_WIN32 */ |
7998ae5a | 159 | |
c6ba8a37 | 160 | ssize_t p_read(git_file fd, void *buf, size_t cnt) |
f79026b4 VM |
161 | { |
162 | char *b = buf; | |
71d62d39 | 163 | |
8d534b47 ET |
164 | if (!git__is_ssizet(cnt)) { |
165 | #ifdef GIT_WIN32 | |
166 | SetLastError(ERROR_INVALID_PARAMETER); | |
167 | #endif | |
168 | errno = EINVAL; | |
169 | return -1; | |
170 | } | |
171 | ||
f79026b4 | 172 | while (cnt) { |
44ef8b1b RB |
173 | ssize_t r; |
174 | #ifdef GIT_WIN32 | |
c6ba8a37 | 175 | r = read(fd, b, cnt > INT_MAX ? INT_MAX : (unsigned int)cnt); |
44ef8b1b RB |
176 | #else |
177 | r = read(fd, b, cnt); | |
178 | #endif | |
f79026b4 VM |
179 | if (r < 0) { |
180 | if (errno == EINTR || errno == EAGAIN) | |
181 | continue; | |
dda708e7 | 182 | return -1; |
f79026b4 VM |
183 | } |
184 | if (!r) | |
185 | break; | |
186 | cnt -= r; | |
187 | b += r; | |
188 | } | |
c6ba8a37 | 189 | return (b - (char *)buf); |
f79026b4 VM |
190 | } |
191 | ||
2ba222c5 | 192 | int p_write(git_file fd, const void *buf, size_t cnt) |
f79026b4 | 193 | { |
2ba222c5 | 194 | const char *b = buf; |
71d62d39 | 195 | |
f79026b4 | 196 | while (cnt) { |
44ef8b1b RB |
197 | ssize_t r; |
198 | #ifdef GIT_WIN32 | |
199 | assert((size_t)((unsigned int)cnt) == cnt); | |
200 | r = write(fd, b, (unsigned int)cnt); | |
201 | #else | |
202 | r = write(fd, b, cnt); | |
203 | #endif | |
f79026b4 | 204 | if (r < 0) { |
0197d410 | 205 | if (errno == EINTR || GIT_ISBLOCKED(errno)) |
f79026b4 | 206 | continue; |
dda708e7 | 207 | return -1; |
f79026b4 VM |
208 | } |
209 | if (!r) { | |
210 | errno = EPIPE; | |
dda708e7 | 211 | return -1; |
f79026b4 VM |
212 | } |
213 | cnt -= r; | |
214 | b += r; | |
215 | } | |
dda708e7 | 216 | return 0; |
f79026b4 | 217 | } |
345eef23 | 218 | |
7697e541 | 219 | #ifdef NO_MMAP |
345eef23 | 220 | |
7697e541 RB |
221 | #include "map.h" |
222 | ||
62e562f9 | 223 | int git__page_size(size_t *page_size) |
f7310540 CMN |
224 | { |
225 | /* dummy; here we don't need any alignment anyway */ | |
62e562f9 AM |
226 | *page_size = 4096; |
227 | return 0; | |
f7310540 CMN |
228 | } |
229 | ||
87c18197 CMN |
230 | int git__mmap_alignment(size_t *alignment) |
231 | { | |
232 | /* dummy; here we don't need any alignment anyway */ | |
233 | *alignment = 4096; | |
234 | return 0; | |
235 | } | |
236 | ||
f7310540 | 237 | |
0c9c969a | 238 | int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset) |
7697e541 RB |
239 | { |
240 | GIT_MMAP_VALIDATE(out, len, prot, flags); | |
241 | ||
242 | out->data = NULL; | |
243 | out->len = 0; | |
244 | ||
245 | if ((prot & GIT_PROT_WRITE) && ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)) { | |
ac3d33df | 246 | git_error_set(GIT_ERROR_OS, "trying to map shared-writeable"); |
7697e541 RB |
247 | return -1; |
248 | } | |
249 | ||
0c9c969a | 250 | out->data = git__malloc(len); |
ac3d33df | 251 | GIT_ERROR_CHECK_ALLOC(out->data); |
7697e541 | 252 | |
8d534b47 ET |
253 | if (!git__is_ssizet(len) || |
254 | (p_lseek(fd, offset, SEEK_SET) < 0) || | |
255 | (p_read(fd, out->data, len) != (ssize_t)len)) { | |
ac3d33df | 256 | git_error_set(GIT_ERROR_OS, "mmap emulation failed"); |
7697e541 RB |
257 | return -1; |
258 | } | |
259 | ||
260 | out->len = len; | |
261 | return 0; | |
262 | } | |
263 | ||
264 | int p_munmap(git_map *map) | |
265 | { | |
266 | assert(map != NULL); | |
0c9c969a | 267 | git__free(map->data); |
7697e541 RB |
268 | |
269 | return 0; | |
270 | } | |
271 | ||
272 | #endif |