libgit2/src/posix.c
Russell Belfer 97769280ba Use git_buf for path storage instead of stack-based buffers
This converts virtually all of the places that allocate GIT_PATH_MAX
buffers on the stack for manipulating paths to use git_buf objects
instead.  The patch is pretty careful not to touch the public API
for libgit2, so there are a few places that still use GIT_PATH_MAX.

This extends and changes some details of the git_buf implementation
to add a couple of extra functions and to make error handling easier.

This includes serious alterations to all the path.c functions, and
several of the fileops.c ones, too.  Also, there are a number of new
functions that parallel existing ones except that use a git_buf
instead of a stack-based buffer (such as git_config_find_global_r
that exists alongsize git_config_find_global).

This also modifies the win32 version of p_realpath to allocate whatever
buffer size is needed to accommodate the realpath instead of hardcoding
a GIT_PATH_MAX limit, but that change needs to be tested still.
2011-12-07 23:08:15 -08:00

96 lines
1.7 KiB
C

/*
* Copyright (C) 2009-2011 the libgit2 contributors
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "common.h"
#include "posix.h"
#include "path.h"
#include <stdio.h>
#include <ctype.h>
#ifndef GIT_WIN32
int p_open(const char *path, int flags)
{
return open(path, flags | O_BINARY);
}
int p_creat(const char *path, mode_t mode)
{
return open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
}
int p_getcwd(char *buffer_out, size_t size)
{
char *cwd_buffer;
assert(buffer_out && size > 0);
cwd_buffer = getcwd(buffer_out, size);
if (cwd_buffer == NULL)
return git__throw(GIT_EOSERR, "Failed to retrieve current working directory");
git_path_mkposix(buffer_out);
git_path_string_to_dir(buffer_out, size); //Ensure the path ends with a trailing slash
return GIT_SUCCESS;
}
int p_rename(const char *from, const char *to)
{
if (!link(from, to)) {
p_unlink(from);
return GIT_SUCCESS;
}
if (!rename(from, to))
return GIT_SUCCESS;
return GIT_ERROR;
}
#endif
int p_read(git_file fd, void *buf, size_t cnt)
{
char *b = buf;
while (cnt) {
ssize_t r = read(fd, b, cnt);
if (r < 0) {
if (errno == EINTR || errno == EAGAIN)
continue;
return GIT_EOSERR;
}
if (!r)
break;
cnt -= r;
b += r;
}
return (int)(b - (char *)buf);
}
int p_write(git_file fd, const void *buf, size_t cnt)
{
const char *b = buf;
while (cnt) {
ssize_t r = write(fd, b, cnt);
if (r < 0) {
if (errno == EINTR || errno == EAGAIN)
continue;
return GIT_EOSERR;
}
if (!r) {
errno = EPIPE;
return GIT_EOSERR;
}
cnt -= r;
b += r;
}
return GIT_SUCCESS;
}