Line Flow Count Block(s) Source
1 - /*
2 - * Copyright (C) the libgit2 contributors. All rights reserved.
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 - */
7 -
8 - #include "posix.h"
9 -
10 - #include "path.h"
11 - #include <stdio.h>
12 - #include <ctype.h>
13 -
14 - size_t p_fsync__cnt = 0;
15 -
16 - #ifndef GIT_WIN32
17 -
18 - #ifdef NO_ADDRINFO
19 -
20 - int p_getaddrinfo(
21 - const char *host,
22 - const char *port,
23 - struct addrinfo *hints,
24 - struct addrinfo **info)
25 - {
26 - struct addrinfo *ainfo, *ai;
27 - int p = 0;
28 -
29 - GIT_UNUSED(hints);
30 -
31 - if ((ainfo = git__malloc(sizeof(struct addrinfo))) == NULL)
32 - return -1;
33 -
34 - if ((ainfo->ai_hostent = gethostbyname(host)) == NULL) {
35 - git__free(ainfo);
36 - return -2;
37 - }
38 -
39 - ainfo->ai_servent = getservbyname(port, 0);
40 -
41 - if (ainfo->ai_servent)
42 - ainfo->ai_port = ainfo->ai_servent->s_port;
43 - else
44 - ainfo->ai_port = htons(atol(port));
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;
59 -
60 - if (ainfo->ai_hostent->h_addr_list[1] == NULL) {
61 - ainfo->ai_next = NULL;
62 - return 0;
63 - }
64 -
65 - ai = ainfo;
66 -
67 - for (p = 1; ainfo->ai_hostent->h_addr_list[p] != NULL; p++) {
68 - if (!(ai->ai_next = git__malloc(sizeof(struct addrinfo)))) {
69 - p_freeaddrinfo(ainfo);
70 - return -1;
71 - }
72 - memcpy(ai->ai_next, ainfo, sizeof(struct addrinfo));
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 - }
79 -
80 - ai->ai_next = NULL;
81 - return 0;
82 - }
83 -
84 - void p_freeaddrinfo(struct addrinfo *info)
85 - {
86 - struct addrinfo *p, *next;
87 -
88 - p = info;
89 -
90 - while(p != NULL) {
91 - next = p->ai_next;
92 - git__free(p);
93 - p = next;
94 - }
95 - }
96 -
97 - const char *p_gai_strerror(int ret)
98 - {
99 - switch(ret) {
100 - case -1: return "Out of memory"; break;
101 - case -2: return "Address lookup failed"; break;
102 - default: return "Unknown error"; break;
103 - }
104 - }
105 -
106 - #endif /* NO_ADDRINFO */
107 -
108 152065 2 int p_open(const char *path, volatile int flags, ...)
109 - {
110 152065 2 mode_t mode = 0;
111 -
112 152065 2 if (flags & O_CREAT) {
113 - va_list arg_list;
114 -
115 19675 3 va_start(arg_list, flags);
116 19675 3-5 mode = (mode_t)va_arg(arg_list, int);
117 19675 6 va_end(arg_list);
118 - }
119 -
120 152065 7 return open(path, flags | O_BINARY | O_CLOEXEC, mode);
121 - }
122 -
123 2081 2 int p_creat(const char *path, mode_t mode)
124 - {
125 2081 2 return open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC, mode);
126 - }
127 -
128 ##### 2 int p_getcwd(char *buffer_out, size_t size)
129 - {
130 - char *cwd_buffer;
131 -
132 ##### 2-4 assert(buffer_out && size > 0);
133 -
134 ##### 5 cwd_buffer = getcwd(buffer_out, size);
135 -
136 ##### 6 if (cwd_buffer == NULL)
137 ##### 7 return -1;
138 -
139 - git_path_mkposix(buffer_out);
140 ##### 8 git_path_string_to_dir(buffer_out, size); /* append trailing slash */
141 -
142 ##### 9 return 0;
143 - }
144 -
145 13862 2 int p_rename(const char *from, const char *to)
146 - {
147 13862 2,3 if (!link(from, to)) {
148 5504 4 p_unlink(from);
149 5504 5 return 0;
150 - }
151 -
152 8358 6,7 if (!rename(from, to))
153 8334 8 return 0;
154 -
155 24 9 return -1;
156 - }
157 -
158 - #endif /* GIT_WIN32 */
159 -
160 135839 2 ssize_t p_read(git_file fd, void *buf, size_t cnt)
161 - {
162 135839 2 char *b = buf;
163 -
164 135899 2,3 if (!git__is_ssizet(cnt)) {
165 - #ifdef GIT_WIN32
166 - SetLastError(ERROR_INVALID_PARAMETER);
167 - #endif
168 ##### 4 errno = EINVAL;
169 ##### 5 return -1;
170 - }
171 -
172 264795 6,18 while (cnt) {
173 - ssize_t r;
174 - #ifdef GIT_WIN32
175 - r = read(fd, b, cnt > INT_MAX ? INT_MAX : (unsigned int)cnt);
176 - #else
177 155375 7 r = read(fd, b, cnt);
178 - #endif
179 155558 8 if (r < 0) {
180 ##### 9-12 if (errno == EINTR || errno == EAGAIN)
181 ##### 13 continue;
182 ##### 14 return -1;
183 - }
184 155558 15 if (!r)
185 26662 16 break;
186 128896 17 cnt -= r;
187 128896 17 b += r;
188 - }
189 136082 19 return (b - (char *)buf);
190 - }
191 -
192 34956 2 int p_write(git_file fd, const void *buf, size_t cnt)
193 - {
194 34956 2 const char *b = buf;
195 -
196 63432 2,17 while (cnt) {
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 28476 3 r = write(fd, b, cnt);
203 - #endif
204 28476 4 if (r < 0) {
205 ##### 5-10 if (errno == EINTR || GIT_ISBLOCKED(errno))
206 ##### 11 continue;
207 ##### 12 return -1;
208 - }
209 28476 13 if (!r) {
210 ##### 14 errno = EPIPE;
211 ##### 15 return -1;
212 - }
213 28476 16 cnt -= r;
214 28476 16 b += r;
215 - }
216 34956 18 return 0;
217 - }
218 -
219 - #ifdef NO_MMAP
220 -
221 - #include "map.h"
222 -
223 - int git__page_size(size_t *page_size)
224 - {
225 - /* dummy; here we don't need any alignment anyway */
226 - *page_size = 4096;
227 - return 0;
228 - }
229 -
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 -
237 -
238 - int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset)
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)) {
246 - git_error_set(GIT_ERROR_OS, "trying to map shared-writeable");
247 - return -1;
248 - }
249 -
250 - out->data = git__malloc(len);
251 - GIT_ERROR_CHECK_ALLOC(out->data);
252 -
253 - if (!git__is_ssizet(len) ||
254 - (p_lseek(fd, offset, SEEK_SET) < 0) ||
255 - (p_read(fd, out->data, len) != (ssize_t)len)) {
256 - git_error_set(GIT_ERROR_OS, "mmap emulation failed");
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);
267 - git__free(map->data);
268 -
269 - return 0;
270 - }
271 -
272 - #endif