]>
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 | */ | |
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 |
13 | size_t p_fsync__cnt = 0; |
14 | ||
7998ae5a PB |
15 | #ifndef GIT_WIN32 |
16 | ||
798e4d53 | 17 | #ifdef NO_ADDRINFO |
71d62d39 | 18 | |
798e4d53 VM |
19 | int 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 | ||
83 | void 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 | ||
96 | const 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 | 107 | int 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 | 122 | int 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 |
127 | int 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 |
144 | int 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 | 159 | ssize_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 | 191 | int 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 | 222 | int 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 |
229 | int 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 |
237 | int 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 | ||
263 | int p_munmap(git_map *map) | |
264 | { | |
265 | assert(map != NULL); | |
266 | free(map->data); | |
267 | ||
268 | return 0; | |
269 | } | |
270 | ||
271 | #endif |