|
Packit Service |
20376f |
/*
|
|
Packit Service |
20376f |
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
Packit Service |
20376f |
* a Linking Exception. For full terms see the included COPYING file.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
#include "common.h"
|
|
Packit Service |
20376f |
#include "posix.h"
|
|
Packit Service |
20376f |
#include "path.h"
|
|
Packit Service |
20376f |
#include <stdio.h>
|
|
Packit Service |
20376f |
#include <ctype.h>
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
size_t p_fsync__cnt = 0;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#ifndef GIT_WIN32
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#ifdef NO_ADDRINFO
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int p_getaddrinfo(
|
|
Packit Service |
20376f |
const char *host,
|
|
Packit Service |
20376f |
const char *port,
|
|
Packit Service |
20376f |
struct addrinfo *hints,
|
|
Packit Service |
20376f |
struct addrinfo **info)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct addrinfo *ainfo, *ai;
|
|
Packit Service |
20376f |
int p = 0;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
GIT_UNUSED(hints);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if ((ainfo = malloc(sizeof(struct addrinfo))) == NULL)
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if ((ainfo->ai_hostent = gethostbyname(host)) == NULL) {
|
|
Packit Service |
20376f |
free(ainfo);
|
|
Packit Service |
20376f |
return -2;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
ainfo->ai_servent = getservbyname(port, 0);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (ainfo->ai_servent)
|
|
Packit Service |
20376f |
ainfo->ai_port = ainfo->ai_servent->s_port;
|
|
Packit Service |
20376f |
else
|
|
Packit Service |
20376f |
ainfo->ai_port = htons(atol(port));
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
memcpy(&ainfo->ai_addr_in.sin_addr,
|
|
Packit Service |
20376f |
ainfo->ai_hostent->h_addr_list[0],
|
|
Packit Service |
20376f |
ainfo->ai_hostent->h_length);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
ainfo->ai_protocol = 0;
|
|
Packit Service |
20376f |
ainfo->ai_socktype = hints->ai_socktype;
|
|
Packit Service |
20376f |
ainfo->ai_family = ainfo->ai_hostent->h_addrtype;
|
|
Packit Service |
20376f |
ainfo->ai_addr_in.sin_family = ainfo->ai_family;
|
|
Packit Service |
20376f |
ainfo->ai_addr_in.sin_port = ainfo->ai_port;
|
|
Packit Service |
20376f |
ainfo->ai_addr = (struct addrinfo *)&ainfo->ai_addr_in;
|
|
Packit Service |
20376f |
ainfo->ai_addrlen = sizeof(struct sockaddr_in);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
*info = ainfo;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (ainfo->ai_hostent->h_addr_list[1] == NULL) {
|
|
Packit Service |
20376f |
ainfo->ai_next = NULL;
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
ai = ainfo;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
for (p = 1; ainfo->ai_hostent->h_addr_list[p] != NULL; p++) {
|
|
Packit Service |
20376f |
if (!(ai->ai_next = malloc(sizeof(struct addrinfo)))) {
|
|
Packit Service |
20376f |
p_freeaddrinfo(ainfo);
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
memcpy(ai->ai_next, ainfo, sizeof(struct addrinfo));
|
|
Packit Service |
20376f |
memcpy(&ai->ai_next->ai_addr_in.sin_addr,
|
|
Packit Service |
20376f |
ainfo->ai_hostent->h_addr_list[p],
|
|
Packit Service |
20376f |
ainfo->ai_hostent->h_length);
|
|
Packit Service |
20376f |
ai->ai_next->ai_addr = (struct addrinfo *)&ai->ai_next->ai_addr_in;
|
|
Packit Service |
20376f |
ai = ai->ai_next;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
ai->ai_next = NULL;
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
void p_freeaddrinfo(struct addrinfo *info)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct addrinfo *p, *next;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
p = info;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
while(p != NULL) {
|
|
Packit Service |
20376f |
next = p->ai_next;
|
|
Packit Service |
20376f |
free(p);
|
|
Packit Service |
20376f |
p = next;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
const char *p_gai_strerror(int ret)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
switch(ret) {
|
|
Packit Service |
20376f |
case -1: return "Out of memory"; break;
|
|
Packit Service |
20376f |
case -2: return "Address lookup failed"; break;
|
|
Packit Service |
20376f |
default: return "Unknown error"; break;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#endif /* NO_ADDRINFO */
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int p_open(const char *path, volatile int flags, ...)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
mode_t mode = 0;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (flags & O_CREAT) {
|
|
Packit Service |
20376f |
va_list arg_list;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
va_start(arg_list, flags);
|
|
Packit Service |
20376f |
mode = (mode_t)va_arg(arg_list, int);
|
|
Packit Service |
20376f |
va_end(arg_list);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
return open(path, flags | O_BINARY | O_CLOEXEC, mode);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int p_creat(const char *path, mode_t mode)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
return open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC, mode);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int p_getcwd(char *buffer_out, size_t size)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
char *cwd_buffer;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
assert(buffer_out && size > 0);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
cwd_buffer = getcwd(buffer_out, size);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (cwd_buffer == NULL)
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
git_path_mkposix(buffer_out);
|
|
Packit Service |
20376f |
git_path_string_to_dir(buffer_out, size); /* append trailing slash */
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int p_rename(const char *from, const char *to)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
if (!link(from, to)) {
|
|
Packit Service |
20376f |
p_unlink(from);
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!rename(from, to))
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#endif /* GIT_WIN32 */
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
ssize_t p_read(git_file fd, void *buf, size_t cnt)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
char *b = buf;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!git__is_ssizet(cnt)) {
|
|
Packit Service |
20376f |
#ifdef GIT_WIN32
|
|
Packit Service |
20376f |
SetLastError(ERROR_INVALID_PARAMETER);
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
errno = EINVAL;
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
while (cnt) {
|
|
Packit Service |
20376f |
ssize_t r;
|
|
Packit Service |
20376f |
#ifdef GIT_WIN32
|
|
Packit Service |
20376f |
r = read(fd, b, cnt > INT_MAX ? INT_MAX : (unsigned int)cnt);
|
|
Packit Service |
20376f |
#else
|
|
Packit Service |
20376f |
r = read(fd, b, cnt);
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
if (r < 0) {
|
|
Packit Service |
20376f |
if (errno == EINTR || errno == EAGAIN)
|
|
Packit Service |
20376f |
continue;
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
if (!r)
|
|
Packit Service |
20376f |
break;
|
|
Packit Service |
20376f |
cnt -= r;
|
|
Packit Service |
20376f |
b += r;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
return (b - (char *)buf);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int p_write(git_file fd, const void *buf, size_t cnt)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
const char *b = buf;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
while (cnt) {
|
|
Packit Service |
20376f |
ssize_t r;
|
|
Packit Service |
20376f |
#ifdef GIT_WIN32
|
|
Packit Service |
20376f |
assert((size_t)((unsigned int)cnt) == cnt);
|
|
Packit Service |
20376f |
r = write(fd, b, (unsigned int)cnt);
|
|
Packit Service |
20376f |
#else
|
|
Packit Service |
20376f |
r = write(fd, b, cnt);
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
if (r < 0) {
|
|
Packit Service |
20376f |
if (errno == EINTR || GIT_ISBLOCKED(errno))
|
|
Packit Service |
20376f |
continue;
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
if (!r) {
|
|
Packit Service |
20376f |
errno = EPIPE;
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
cnt -= r;
|
|
Packit Service |
20376f |
b += r;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#ifdef NO_MMAP
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#include "map.h"
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int git__page_size(size_t *page_size)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
/* dummy; here we don't need any alignment anyway */
|
|
Packit Service |
20376f |
*page_size = 4096;
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int git__mmap_alignment(size_t *alignment)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
/* dummy; here we don't need any alignment anyway */
|
|
Packit Service |
20376f |
*alignment = 4096;
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
GIT_MMAP_VALIDATE(out, len, prot, flags);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
out->data = NULL;
|
|
Packit Service |
20376f |
out->len = 0;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if ((prot & GIT_PROT_WRITE) && ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)) {
|
|
Packit Service |
20376f |
giterr_set(GITERR_OS, "trying to map shared-writeable");
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
out->data = malloc(len);
|
|
Packit Service |
20376f |
GITERR_CHECK_ALLOC(out->data);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!git__is_ssizet(len) ||
|
|
Packit Service |
20376f |
(p_lseek(fd, offset, SEEK_SET) < 0) ||
|
|
Packit Service |
20376f |
(p_read(fd, out->data, len) != (ssize_t)len)) {
|
|
Packit Service |
20376f |
giterr_set(GITERR_OS, "mmap emulation failed");
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
out->len = len;
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int p_munmap(git_map *map)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
assert(map != NULL);
|
|
Packit Service |
20376f |
free(map->data);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#endif
|