mirror of
https://github.com/git/git.git
synced 2026-03-13 10:23:30 +01:00
Merge branch 'js/reflog' into next
* js/reflog:
Sanitize for_each_reflog_ent()
merge-base: do not leak commit list
Auto-quote config values in config.c:store_write_pair()
Ignore git-init and git-remote
rm git-rerere.perl -- it is now a built-in.
cvsserver: fix revision number during file adds
cvsserver: detect early of we are up to date and avoid costly rev-list
Documentation: add git-remote man page
short i/o: fix config updates to use write_in_full
short i/o: fix calls to write to use xwrite or write_in_full
short i/o: fix calls to read to use xread or read_in_full
short i/o: clean up the naming for the write_{in,or}_xxx family
--prune is now default for 'pack-refs'
--utf8 is now default for 'git-am'
git-commit: do not fail to print the diffstat even if there is a file named HEAD
ssh-upload: prevent buffer overrun
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -50,6 +50,7 @@ git-http-fetch
|
||||
git-http-push
|
||||
git-imap-send
|
||||
git-index-pack
|
||||
git-init
|
||||
git-init-db
|
||||
git-instaweb
|
||||
git-local-fetch
|
||||
@@ -92,6 +93,7 @@ git-rebase
|
||||
git-receive-pack
|
||||
git-reflog
|
||||
git-relink
|
||||
git-remote
|
||||
git-repack
|
||||
git-repo-config
|
||||
git-request-pull
|
||||
|
||||
@@ -9,7 +9,7 @@ git-am - Apply a series of patches in a mailbox
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git-am' [--signoff] [--dotest=<dir>] [--utf8] [--binary] [--3way]
|
||||
'git-am' [--signoff] [--dotest=<dir>] [--utf8 | --no-utf8] [--binary] [--3way]
|
||||
[--interactive] [--whitespace=<option>] <mbox>...
|
||||
'git-am' [--skip | --resolved]
|
||||
|
||||
@@ -29,8 +29,21 @@ OPTIONS
|
||||
Instead of `.dotest` directory, use <dir> as a working
|
||||
area to store extracted patches.
|
||||
|
||||
--utf8, --keep::
|
||||
Pass `-u` and `-k` flags to `git-mailinfo` (see
|
||||
--keep::
|
||||
Pass `-k` flag to `git-mailinfo` (see gitlink:git-mailinfo[1]).
|
||||
|
||||
--utf8::
|
||||
Pass `-u` flag to `git-mailinfo` (see gitlink:git-mailinfo[1]).
|
||||
The proposed commit log message taken from the e-mail
|
||||
are re-coded into UTF-8 encoding (configuration variable
|
||||
`i18n.commitencoding` can be used to specify project's
|
||||
preferred encoding if it is not UTF-8).
|
||||
+
|
||||
This was optional in prior versions of git, but now it is the
|
||||
default. You could use `--no-utf8` to override this.
|
||||
|
||||
--no-utf8::
|
||||
Do not pass `-u` flag to `git-mailinfo` (see
|
||||
gitlink:git-mailinfo[1]).
|
||||
|
||||
--binary::
|
||||
|
||||
@@ -7,7 +7,7 @@ git-pack-refs - Pack heads and tags for efficient repository access
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-pack-refs' [--all] [--prune]
|
||||
'git-pack-refs' [--all] [--no-prune]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -40,10 +40,11 @@ developed and packing their tips does not help performance.
|
||||
This option causes branch tips to be packed as well. Useful for
|
||||
a repository with many branches of historical interests.
|
||||
|
||||
\--prune::
|
||||
\--no-prune::
|
||||
|
||||
The command usually removes loose refs under `$GIT_DIR/refs`
|
||||
hierarchy after packing them. This option tells it not to.
|
||||
|
||||
After packing the refs, remove loose refs under `$GIT_DIR/refs`
|
||||
hierarchy. This should probably become default.
|
||||
|
||||
Author
|
||||
------
|
||||
|
||||
76
Documentation/git-remote.txt
Normal file
76
Documentation/git-remote.txt
Normal file
@@ -0,0 +1,76 @@
|
||||
git-remote(1)
|
||||
============
|
||||
|
||||
NAME
|
||||
----
|
||||
git-remote - manage set of tracked repositories
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git-remote'
|
||||
'git-remote' add <name> <url>
|
||||
'git-remote' show <name>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
Manage the set of repositories ("remotes") whose branches you track.
|
||||
|
||||
With no arguments, shows a list of existing remotes.
|
||||
|
||||
In the second form, adds a remote named <name> for the repository at
|
||||
<url>. The command `git fetch <name>` can then be used to create and
|
||||
update remote-tracking branches <name>/<branch>.
|
||||
|
||||
In the third form, gives some information about the remote <name>.
|
||||
|
||||
The remote configuration is achieved using the `remote.origin.url` and
|
||||
`remote.origin.fetch` configuration variables. (See
|
||||
gitlink:git-repo-config[1]).
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Add a new remote, fetch, and check out a branch from it:
|
||||
|
||||
------------
|
||||
$ git remote
|
||||
origin
|
||||
$ git branch -r
|
||||
origin/master
|
||||
$ git remote add linux-nfs git://linux-nfs.org/pub/nfs-2.6.git
|
||||
$ git remote
|
||||
linux-nfs
|
||||
origin
|
||||
$ git fetch
|
||||
* refs/remotes/linux-nfs/master: storing branch 'master' ...
|
||||
commit: bf81b46
|
||||
$ git branch -r
|
||||
origin/master
|
||||
linux-nfs/master
|
||||
$ git checkout -b nfs linux-nfs/master
|
||||
...
|
||||
------------
|
||||
|
||||
See Also
|
||||
--------
|
||||
gitlink:git-fetch[1]
|
||||
gitlink:git-branch[1]
|
||||
gitlink:git-repo-config[1]
|
||||
|
||||
Author
|
||||
------
|
||||
Written by Junio Hamano
|
||||
|
||||
|
||||
Documentation
|
||||
--------------
|
||||
Documentation by J. Bruce Fields and the git-list <git@vger.kernel.org>.
|
||||
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the gitlink:git[7] suite
|
||||
|
||||
@@ -136,7 +136,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)
|
||||
if (i < 0)
|
||||
goto err_ret;
|
||||
data = xmalloc(st.st_size + 1);
|
||||
if (st.st_size != xread(i, data, st.st_size)) {
|
||||
if (st.st_size != read_in_full(i, data, st.st_size)) {
|
||||
error("'%s': short read %s", filename, strerror(errno));
|
||||
close(i);
|
||||
free(data);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "tag.h"
|
||||
|
||||
static const char builtin_pack_refs_usage[] =
|
||||
"git-pack-refs [--all] [--prune]";
|
||||
"git-pack-refs [--all] [--prune | --no-prune]";
|
||||
|
||||
struct ref_to_prune {
|
||||
struct ref_to_prune *next;
|
||||
@@ -90,10 +90,15 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
|
||||
|
||||
memset(&cbdata, 0, sizeof(cbdata));
|
||||
|
||||
cbdata.prune = 1;
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (!strcmp(arg, "--prune")) {
|
||||
cbdata.prune = 1;
|
||||
cbdata.prune = 1; /* now the default */
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--no-prune")) {
|
||||
cbdata.prune = 0;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--all")) {
|
||||
|
||||
@@ -195,19 +195,12 @@ static int keep_entry(struct commit **it, unsigned char *sha1)
|
||||
}
|
||||
|
||||
static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
|
||||
char *data, void *cb_data)
|
||||
const char *email, unsigned long timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
{
|
||||
struct expire_reflog_cb *cb = cb_data;
|
||||
unsigned long timestamp;
|
||||
char *cp, *ep;
|
||||
struct commit *old, *new;
|
||||
|
||||
cp = strchr(data, '>');
|
||||
if (!cp || *++cp != ' ')
|
||||
goto prune;
|
||||
timestamp = strtoul(cp, &ep, 10);
|
||||
if (*ep != ' ')
|
||||
goto prune;
|
||||
if (timestamp < cb->cmd->expire_total)
|
||||
goto prune;
|
||||
|
||||
@@ -221,15 +214,20 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
|
||||
(new && !in_merge_bases(new, cb->ref_commit))))
|
||||
goto prune;
|
||||
|
||||
if (cb->newlog)
|
||||
fprintf(cb->newlog, "%s %s %s",
|
||||
sha1_to_hex(osha1), sha1_to_hex(nsha1), data);
|
||||
if (cb->newlog) {
|
||||
char sign = (tz < 0) ? '-' : '+';
|
||||
int zone = (tz < 0) ? (-tz) : tz;
|
||||
fprintf(cb->newlog, "%s %s %s %lu %c%04d\t%s",
|
||||
sha1_to_hex(osha1), sha1_to_hex(nsha1),
|
||||
email, timestamp, sign, zone,
|
||||
message);
|
||||
}
|
||||
if (cb->cmd->verbose)
|
||||
printf("keep %s", data);
|
||||
printf("keep %s", message);
|
||||
return 0;
|
||||
prune:
|
||||
if (!cb->newlog || cb->cmd->verbose)
|
||||
printf("%sprune %s", cb->newlog ? "" : "would ", data);
|
||||
printf("%sprune %s", cb->newlog ? "" : "would ", message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,9 +51,11 @@ static int write_rr(struct path_list *rr, int out_fd)
|
||||
int i;
|
||||
for (i = 0; i < rr->nr; i++) {
|
||||
const char *path = rr->items[i].path;
|
||||
write(out_fd, rr->items[i].util, 40);
|
||||
write(out_fd, "\t", 1);
|
||||
write(out_fd, path, strlen(path) + 1);
|
||||
int length = strlen(path) + 1;
|
||||
if (write_in_full(out_fd, rr->items[i].util, 40) != 40 ||
|
||||
write_in_full(out_fd, "\t", 1) != 1 ||
|
||||
write_in_full(out_fd, path, length) != length)
|
||||
die("unable to write rerere record");
|
||||
}
|
||||
close(out_fd);
|
||||
return commit_lock_file(&write_lock);
|
||||
@@ -244,7 +246,8 @@ static int outf(void *dummy, mmbuffer_t *ptr, int nbuf)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nbuf; i++)
|
||||
write(1, ptr[i].ptr, ptr[i].size);
|
||||
if (write_in_full(1, ptr[i].ptr, ptr[i].size) != ptr[i].size)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
|
||||
char *content = buffer + RECORDSIZE;
|
||||
ssize_t n;
|
||||
|
||||
n = xread(0, buffer, HEADERSIZE);
|
||||
n = read_in_full(0, buffer, HEADERSIZE);
|
||||
if (n < HEADERSIZE)
|
||||
die("git-get-tar-commit-id: read error");
|
||||
if (header->typeflag[0] != 'g')
|
||||
@@ -82,7 +82,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
|
||||
if (memcmp(content, "52 comment=", 11))
|
||||
return 1;
|
||||
|
||||
n = xwrite(1, content + 11, 41);
|
||||
n = write_in_full(1, content + 11, 41);
|
||||
if (n < 41)
|
||||
die("git-get-tar-commit-id: write error");
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ static void process_input(int child_fd, int band)
|
||||
char buf[16384];
|
||||
ssize_t sz = read(child_fd, buf, sizeof(buf));
|
||||
if (sz < 0) {
|
||||
if (errno != EINTR)
|
||||
if (errno != EAGAIN && errno != EINTR)
|
||||
error_clnt("read error: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
4
cache.h
4
cache.h
@@ -433,10 +433,12 @@ extern char *git_commit_encoding;
|
||||
extern char *git_log_output_encoding;
|
||||
|
||||
extern int copy_fd(int ifd, int ofd);
|
||||
extern int read_in_full(int fd, void *buf, size_t count);
|
||||
extern void read_or_die(int fd, void *buf, size_t count);
|
||||
extern int write_in_full(int fd, const void *buf, size_t count, const char *);
|
||||
extern int write_in_full(int fd, const void *buf, size_t count);
|
||||
extern void write_or_die(int fd, const void *buf, size_t count);
|
||||
extern int write_or_whine(int fd, const void *buf, size_t count, const char *msg);
|
||||
extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg);
|
||||
|
||||
/* pager.c */
|
||||
extern void setup_pager(void);
|
||||
|
||||
12
commit.c
12
commit.c
@@ -249,8 +249,10 @@ int write_shallow_commits(int fd, int use_pack_protocol)
|
||||
if (use_pack_protocol)
|
||||
packet_write(fd, "shallow %s", hex);
|
||||
else {
|
||||
write(fd, hex, 40);
|
||||
write(fd, "\n", 1);
|
||||
if (write_in_full(fd, hex, 40) != 40)
|
||||
break;
|
||||
if (write_in_full(fd, "\n", 1) != 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
@@ -1010,7 +1012,7 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
|
||||
free(nodes);
|
||||
}
|
||||
|
||||
/* merge-rebase stuff */
|
||||
/* merge-base stuff */
|
||||
|
||||
/* bits #0..15 in revision.h */
|
||||
#define PARENT1 (1u<<16)
|
||||
@@ -1018,6 +1020,8 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
|
||||
#define STALE (1u<<18)
|
||||
#define RESULT (1u<<19)
|
||||
|
||||
static const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT);
|
||||
|
||||
static struct commit *interesting(struct commit_list *list)
|
||||
{
|
||||
while (list) {
|
||||
@@ -1082,6 +1086,7 @@ static struct commit_list *merge_bases(struct commit *one, struct commit *two)
|
||||
}
|
||||
|
||||
/* Clean up the result to remove stale ones */
|
||||
free_commit_list(list);
|
||||
list = result; result = NULL;
|
||||
while (list) {
|
||||
struct commit_list *n = list->next;
|
||||
@@ -1097,7 +1102,6 @@ struct commit_list *get_merge_bases(struct commit *one,
|
||||
struct commit *two,
|
||||
int cleanup)
|
||||
{
|
||||
const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT);
|
||||
struct commit_list *list;
|
||||
struct commit **rslt;
|
||||
struct commit_list *result;
|
||||
|
||||
120
config.c
120
config.c
@@ -469,7 +469,15 @@ static int store_aux(const char* key, const char* value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void store_write_section(int fd, const char* key)
|
||||
static int write_error()
|
||||
{
|
||||
fprintf(stderr, "Failed to write new configuration file\n");
|
||||
|
||||
/* Same error code as "failed to rename". */
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int store_write_section(int fd, const char* key)
|
||||
{
|
||||
const char *dot = strchr(key, '.');
|
||||
int len1 = store.baselen, len2 = -1;
|
||||
@@ -483,37 +491,74 @@ static void store_write_section(int fd, const char* key)
|
||||
}
|
||||
}
|
||||
|
||||
write(fd, "[", 1);
|
||||
write(fd, key, len1);
|
||||
if (write_in_full(fd, "[", 1) != 1 ||
|
||||
write_in_full(fd, key, len1) != len1)
|
||||
return 0;
|
||||
if (len2 >= 0) {
|
||||
write(fd, " \"", 2);
|
||||
if (write_in_full(fd, " \"", 2) != 2)
|
||||
return 0;
|
||||
while (--len2 >= 0) {
|
||||
unsigned char c = *++dot;
|
||||
if (c == '"')
|
||||
write(fd, "\\", 1);
|
||||
write(fd, &c, 1);
|
||||
if (write_in_full(fd, "\\", 1) != 1)
|
||||
return 0;
|
||||
if (write_in_full(fd, &c, 1) != 1)
|
||||
return 0;
|
||||
}
|
||||
write(fd, "\"", 1);
|
||||
if (write_in_full(fd, "\"", 1) != 1)
|
||||
return 0;
|
||||
}
|
||||
write(fd, "]\n", 2);
|
||||
if (write_in_full(fd, "]\n", 2) != 2)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void store_write_pair(int fd, const char* key, const char* value)
|
||||
static int store_write_pair(int fd, const char* key, const char* value)
|
||||
{
|
||||
int i;
|
||||
int length = strlen(key+store.baselen+1);
|
||||
int quote = 0;
|
||||
|
||||
write(fd, "\t", 1);
|
||||
write(fd, key+store.baselen+1,
|
||||
strlen(key+store.baselen+1));
|
||||
write(fd, " = ", 3);
|
||||
/* Check to see if the value needs to be quoted. */
|
||||
if (value[0] == ' ')
|
||||
quote = 1;
|
||||
for (i = 0; value[i]; i++)
|
||||
if (value[i] == ';' || value[i] == '#')
|
||||
quote = 1;
|
||||
if (value[i-1] == ' ')
|
||||
quote = 1;
|
||||
|
||||
if (write_in_full(fd, "\t", 1) != 1 ||
|
||||
write_in_full(fd, key+store.baselen+1, length) != length ||
|
||||
write_in_full(fd, " = ", 3) != 3)
|
||||
return 0;
|
||||
if (quote && write_in_full(fd, "\"", 1) != 1)
|
||||
return 0;
|
||||
for (i = 0; value[i]; i++)
|
||||
switch (value[i]) {
|
||||
case '\n': write(fd, "\\n", 2); break;
|
||||
case '\t': write(fd, "\\t", 2); break;
|
||||
case '"': case '\\': write(fd, "\\", 1);
|
||||
default: write(fd, value+i, 1);
|
||||
}
|
||||
write(fd, "\n", 1);
|
||||
case '\n':
|
||||
if (write_in_full(fd, "\\n", 2) != 2)
|
||||
return 0;
|
||||
break;
|
||||
case '\t':
|
||||
if (write_in_full(fd, "\\t", 2) != 2)
|
||||
return 0;
|
||||
break;
|
||||
case '"':
|
||||
case '\\':
|
||||
if (write_in_full(fd, "\\", 1) != 1)
|
||||
return 0;
|
||||
default:
|
||||
if (write_in_full(fd, value+i, 1) != 1)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if (quote && write_in_full(fd, "\"", 1) != 1)
|
||||
return 0;
|
||||
if (write_in_full(fd, "\n", 1) != 1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int find_beginning_of_line(const char* contents, int size,
|
||||
@@ -653,8 +698,11 @@ int git_config_set_multivar(const char* key, const char* value,
|
||||
}
|
||||
|
||||
store.key = (char*)key;
|
||||
store_write_section(fd, key);
|
||||
store_write_pair(fd, key, value);
|
||||
if (!store_write_section(fd, key) ||
|
||||
!store_write_pair(fd, key, value)) {
|
||||
ret = write_error();
|
||||
goto out_free;
|
||||
}
|
||||
} else{
|
||||
struct stat st;
|
||||
char* contents;
|
||||
@@ -734,10 +782,10 @@ int git_config_set_multivar(const char* key, const char* value,
|
||||
|
||||
/* write the first part of the config */
|
||||
if (copy_end > copy_begin) {
|
||||
write(fd, contents + copy_begin,
|
||||
write_in_full(fd, contents + copy_begin,
|
||||
copy_end - copy_begin);
|
||||
if (new_line)
|
||||
write(fd, "\n", 1);
|
||||
write_in_full(fd, "\n", 1);
|
||||
}
|
||||
copy_begin = store.offset[i];
|
||||
}
|
||||
@@ -745,13 +793,19 @@ int git_config_set_multivar(const char* key, const char* value,
|
||||
/* write the pair (value == NULL means unset) */
|
||||
if (value != NULL) {
|
||||
if (store.state == START)
|
||||
store_write_section(fd, key);
|
||||
store_write_pair(fd, key, value);
|
||||
if (!store_write_section(fd, key)) {
|
||||
ret = write_error();
|
||||
goto out_free;
|
||||
}
|
||||
if (!store_write_pair(fd, key, value)) {
|
||||
ret = write_error();
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
|
||||
/* write the rest of the config */
|
||||
if (copy_begin < st.st_size)
|
||||
write(fd, contents + copy_begin,
|
||||
write_in_full(fd, contents + copy_begin,
|
||||
st.st_size - copy_begin);
|
||||
|
||||
munmap(contents, st.st_size);
|
||||
@@ -805,6 +859,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)
|
||||
|
||||
while (fgets(buf, sizeof(buf), config_file)) {
|
||||
int i;
|
||||
int length;
|
||||
for (i = 0; buf[i] && isspace(buf[i]); i++)
|
||||
; /* do nothing */
|
||||
if (buf[i] == '[') {
|
||||
@@ -835,15 +890,22 @@ int git_config_rename_section(const char *old_name, const char *new_name)
|
||||
/* old_name matches */
|
||||
ret++;
|
||||
store.baselen = strlen(new_name);
|
||||
store_write_section(out_fd, new_name);
|
||||
if (!store_write_section(out_fd, new_name)) {
|
||||
ret = write_error();
|
||||
goto out;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
write(out_fd, buf, strlen(buf));
|
||||
length = strlen(buf);
|
||||
if (write_in_full(out_fd, buf, length) != length) {
|
||||
ret = write_error();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
fclose(config_file);
|
||||
if (close(out_fd) || commit_lock_file(lock) < 0)
|
||||
ret = error("Cannot commit config file!");
|
||||
ret = error("Cannot commit config file!");
|
||||
out:
|
||||
free(config_filename);
|
||||
return ret;
|
||||
|
||||
2
daemon.c
2
daemon.c
@@ -102,7 +102,7 @@ static void logreport(int priority, const char *err, va_list params)
|
||||
buf[buflen++] = '\n';
|
||||
buf[buflen] = '\0';
|
||||
|
||||
write(2, buf, buflen);
|
||||
write_in_full(2, buf, buflen);
|
||||
}
|
||||
|
||||
static void logerror(const char *err, ...)
|
||||
|
||||
2
diff.c
2
diff.c
@@ -1403,7 +1403,7 @@ static void prep_temp_blob(struct diff_tempfile *temp,
|
||||
fd = git_mkstemp(temp->tmp_path, TEMPFILE_PATH_LEN, ".diff_XXXXXX");
|
||||
if (fd < 0)
|
||||
die("unable to create temp-file");
|
||||
if (write(fd, blob, size) != size)
|
||||
if (write_in_full(fd, blob, size) != size)
|
||||
die("unable to write temp-file");
|
||||
close(fd);
|
||||
temp->name = temp->tmp_path;
|
||||
|
||||
2
dir.c
2
dir.c
@@ -142,7 +142,7 @@ static int add_excludes_from_file_1(const char *fname,
|
||||
return 0;
|
||||
}
|
||||
buf = xmalloc(size+1);
|
||||
if (read(fd, buf, size) != size)
|
||||
if (read_in_full(fd, buf, size) != size)
|
||||
goto err;
|
||||
close(fd);
|
||||
|
||||
|
||||
4
entry.c
4
entry.c
@@ -89,7 +89,7 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat
|
||||
return error("git-checkout-index: unable to create file %s (%s)",
|
||||
path, strerror(errno));
|
||||
}
|
||||
wrote = write(fd, new, size);
|
||||
wrote = write_in_full(fd, new, size);
|
||||
close(fd);
|
||||
free(new);
|
||||
if (wrote != size)
|
||||
@@ -104,7 +104,7 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat
|
||||
return error("git-checkout-index: unable to create "
|
||||
"file %s (%s)", path, strerror(errno));
|
||||
}
|
||||
wrote = write(fd, new, size);
|
||||
wrote = write_in_full(fd, new, size);
|
||||
close(fd);
|
||||
free(new);
|
||||
if (wrote != size)
|
||||
|
||||
@@ -399,7 +399,9 @@ static void fsck_dir(int i, char *path)
|
||||
|
||||
static int default_refs;
|
||||
|
||||
static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1, char *datail, void *cb_data)
|
||||
static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
|
||||
const char *email, unsigned long timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
{
|
||||
struct object *obj;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2006 Junio C Hamano
|
||||
|
||||
USAGE='[--signoff] [--dotest=<dir>] [--utf8] [--binary] [--3way]
|
||||
USAGE='[--signoff] [--dotest=<dir>] [--utf8 | --no-utf8] [--binary] [--3way]
|
||||
[--interactive] [--whitespace=<option>] <mbox>...
|
||||
or, when resuming [--skip | --resolved]'
|
||||
. git-sh-setup
|
||||
@@ -105,7 +105,7 @@ It does not apply to blobs recorded in its index."
|
||||
}
|
||||
|
||||
prec=4
|
||||
dotest=.dotest sign= utf8= keep= skip= interactive= resolved= binary= ws= resolvemsg=
|
||||
dotest=.dotest sign= utf8=t keep= skip= interactive= resolved= binary= ws= resolvemsg=
|
||||
|
||||
while case "$#" in 0) break;; esac
|
||||
do
|
||||
@@ -128,7 +128,9 @@ do
|
||||
-s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
|
||||
sign=t; shift ;;
|
||||
-u|--u|--ut|--utf|--utf8)
|
||||
utf8=t; shift ;;
|
||||
shift ;; # this is now default
|
||||
--no-u|--no-ut|--no-utf|--no-utf8)
|
||||
utf8=; shift ;;
|
||||
-k|--k|--ke|--kee|--keep)
|
||||
keep=t; shift ;;
|
||||
|
||||
|
||||
@@ -628,7 +628,7 @@ then
|
||||
if test -z "$quiet"
|
||||
then
|
||||
echo "Created${initial_commit:+ initial} commit $commit"
|
||||
git-diff-tree --shortstat --summary --root --no-commit-id HEAD
|
||||
git-diff-tree --shortstat --summary --root --no-commit-id HEAD --
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -1181,12 +1181,15 @@ sub req_ci
|
||||
$filename = filecleanup($filename);
|
||||
|
||||
my $meta = $updater->getmeta($filename);
|
||||
unless (defined $meta->{revision}) {
|
||||
$meta->{revision} = 1;
|
||||
}
|
||||
|
||||
my ( $filepart, $dirpart ) = filenamesplit($filename, 1);
|
||||
|
||||
$log->debug("Checked-in $dirpart : $filename");
|
||||
|
||||
if ( $meta->{filehash} eq "deleted" )
|
||||
if ( defined $meta->{filehash} && $meta->{filehash} eq "deleted" )
|
||||
{
|
||||
print "Remove-entry $dirpart\n";
|
||||
print "$filename\n";
|
||||
@@ -2184,7 +2187,10 @@ sub update
|
||||
# first lets get the commit list
|
||||
$ENV{GIT_DIR} = $self->{git_path};
|
||||
|
||||
my $commitinfo = `git-cat-file commit $self->{module} 2>&1`;
|
||||
my $commitsha1 = `git rev-parse $self->{module}`;
|
||||
chomp $commitsha1;
|
||||
|
||||
my $commitinfo = `git cat-file commit $self->{module} 2>&1`;
|
||||
unless ( $commitinfo =~ /tree\s+[a-zA-Z0-9]{40}/ )
|
||||
{
|
||||
die("Invalid module '$self->{module}'");
|
||||
@@ -2194,6 +2200,10 @@ sub update
|
||||
my $git_log;
|
||||
my $lastcommit = $self->_get_prop("last_commit");
|
||||
|
||||
if (defined $lastcommit && $lastcommit eq $commitsha1) { # up-to-date
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Start exclusive lock here...
|
||||
$self->{dbh}->begin_work() or die "Cannot lock database for BEGIN";
|
||||
|
||||
|
||||
284
git-rerere.perl
284
git-rerere.perl
@@ -1,284 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# REuse REcorded REsolve. This tool records a conflicted automerge
|
||||
# result and its hand resolution, and helps to resolve future
|
||||
# automerge that results in the same conflict.
|
||||
#
|
||||
# To enable this feature, create a directory 'rr-cache' under your
|
||||
# .git/ directory.
|
||||
|
||||
use Digest;
|
||||
use File::Path;
|
||||
use File::Copy;
|
||||
|
||||
my $git_dir = $::ENV{GIT_DIR} || ".git";
|
||||
my $rr_dir = "$git_dir/rr-cache";
|
||||
my $merge_rr = "$git_dir/rr-cache/MERGE_RR";
|
||||
|
||||
my %merge_rr = ();
|
||||
|
||||
sub read_rr {
|
||||
if (!-f $merge_rr) {
|
||||
%merge_rr = ();
|
||||
return;
|
||||
}
|
||||
my $in;
|
||||
local $/ = "\0";
|
||||
open $in, "<$merge_rr" or die "$!: $merge_rr";
|
||||
while (<$in>) {
|
||||
chomp;
|
||||
my ($name, $path) = /^([0-9a-f]{40})\t(.*)$/s;
|
||||
$merge_rr{$path} = $name;
|
||||
}
|
||||
close $in;
|
||||
}
|
||||
|
||||
sub write_rr {
|
||||
my $out;
|
||||
open $out, ">$merge_rr" or die "$!: $merge_rr";
|
||||
for my $path (sort keys %merge_rr) {
|
||||
my $name = $merge_rr{$path};
|
||||
print $out "$name\t$path\0";
|
||||
}
|
||||
close $out;
|
||||
}
|
||||
|
||||
sub compute_conflict_name {
|
||||
my ($path) = @_;
|
||||
my @side = ();
|
||||
my $in;
|
||||
open $in, "<$path" or die "$!: $path";
|
||||
|
||||
my $sha1 = Digest->new("SHA-1");
|
||||
my $hunk = 0;
|
||||
while (<$in>) {
|
||||
if (/^<<<<<<< .*/) {
|
||||
$hunk++;
|
||||
@side = ([], undef);
|
||||
}
|
||||
elsif (/^=======$/) {
|
||||
$side[1] = [];
|
||||
}
|
||||
elsif (/^>>>>>>> .*/) {
|
||||
my ($one, $two);
|
||||
$one = join('', @{$side[0]});
|
||||
$two = join('', @{$side[1]});
|
||||
if ($two le $one) {
|
||||
($one, $two) = ($two, $one);
|
||||
}
|
||||
$sha1->add($one);
|
||||
$sha1->add("\0");
|
||||
$sha1->add($two);
|
||||
$sha1->add("\0");
|
||||
@side = ();
|
||||
}
|
||||
elsif (@side == 0) {
|
||||
next;
|
||||
}
|
||||
elsif (defined $side[1]) {
|
||||
push @{$side[1]}, $_;
|
||||
}
|
||||
else {
|
||||
push @{$side[0]}, $_;
|
||||
}
|
||||
}
|
||||
close $in;
|
||||
return ($sha1->hexdigest, $hunk);
|
||||
}
|
||||
|
||||
sub record_preimage {
|
||||
my ($path, $name) = @_;
|
||||
my @side = ();
|
||||
my ($in, $out);
|
||||
open $in, "<$path" or die "$!: $path";
|
||||
open $out, ">$name" or die "$!: $name";
|
||||
|
||||
while (<$in>) {
|
||||
if (/^<<<<<<< .*/) {
|
||||
@side = ([], undef);
|
||||
}
|
||||
elsif (/^=======$/) {
|
||||
$side[1] = [];
|
||||
}
|
||||
elsif (/^>>>>>>> .*/) {
|
||||
my ($one, $two);
|
||||
$one = join('', @{$side[0]});
|
||||
$two = join('', @{$side[1]});
|
||||
if ($two le $one) {
|
||||
($one, $two) = ($two, $one);
|
||||
}
|
||||
print $out "<<<<<<<\n";
|
||||
print $out $one;
|
||||
print $out "=======\n";
|
||||
print $out $two;
|
||||
print $out ">>>>>>>\n";
|
||||
@side = ();
|
||||
}
|
||||
elsif (@side == 0) {
|
||||
print $out $_;
|
||||
}
|
||||
elsif (defined $side[1]) {
|
||||
push @{$side[1]}, $_;
|
||||
}
|
||||
else {
|
||||
push @{$side[0]}, $_;
|
||||
}
|
||||
}
|
||||
close $out;
|
||||
close $in;
|
||||
}
|
||||
|
||||
sub find_conflict {
|
||||
my $in;
|
||||
local $/ = "\0";
|
||||
my $pid = open($in, '-|');
|
||||
die "$!" unless defined $pid;
|
||||
if (!$pid) {
|
||||
exec(qw(git ls-files -z -u)) or die "$!: ls-files";
|
||||
}
|
||||
my %path = ();
|
||||
my @path = ();
|
||||
while (<$in>) {
|
||||
chomp;
|
||||
my ($mode, $sha1, $stage, $path) =
|
||||
/^([0-7]+) ([0-9a-f]{40}) ([123])\t(.*)$/s;
|
||||
$path{$path} |= (1 << $stage);
|
||||
}
|
||||
close $in;
|
||||
while (my ($path, $status) = each %path) {
|
||||
if ($status == 14) { push @path, $path; }
|
||||
}
|
||||
return @path;
|
||||
}
|
||||
|
||||
sub merge {
|
||||
my ($name, $path) = @_;
|
||||
record_preimage($path, "$rr_dir/$name/thisimage");
|
||||
unless (system('git', 'merge-file', map { "$rr_dir/$name/${_}image" }
|
||||
qw(this pre post))) {
|
||||
my $in;
|
||||
open $in, "<$rr_dir/$name/thisimage" or
|
||||
die "$!: $name/thisimage";
|
||||
my $out;
|
||||
open $out, ">$path" or die "$!: $path";
|
||||
while (<$in>) { print $out $_; }
|
||||
close $in;
|
||||
close $out;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub garbage_collect_rerere {
|
||||
# We should allow specifying these from the command line and
|
||||
# that is why the caller gives @ARGV to us, but I am lazy.
|
||||
|
||||
my $cutoff_noresolve = 15; # two weeks
|
||||
my $cutoff_resolve = 60; # two months
|
||||
my @to_remove;
|
||||
while (<$rr_dir/*/preimage>) {
|
||||
my ($dir) = /^(.*)\/preimage$/;
|
||||
my $cutoff = ((-f "$dir/postimage")
|
||||
? $cutoff_resolve
|
||||
: $cutoff_noresolve);
|
||||
my $age = -M "$_";
|
||||
if ($cutoff <= $age) {
|
||||
push @to_remove, $dir;
|
||||
}
|
||||
}
|
||||
if (@to_remove) {
|
||||
rmtree(\@to_remove);
|
||||
}
|
||||
}
|
||||
|
||||
-d "$rr_dir" || exit(0);
|
||||
|
||||
read_rr();
|
||||
|
||||
if (@ARGV) {
|
||||
my $arg = shift @ARGV;
|
||||
if ($arg eq 'clear') {
|
||||
for my $path (keys %merge_rr) {
|
||||
my $name = $merge_rr{$path};
|
||||
if (-d "$rr_dir/$name" &&
|
||||
! -f "$rr_dir/$name/postimage") {
|
||||
rmtree(["$rr_dir/$name"]);
|
||||
}
|
||||
}
|
||||
unlink $merge_rr;
|
||||
}
|
||||
elsif ($arg eq 'status') {
|
||||
for my $path (keys %merge_rr) {
|
||||
print $path, "\n";
|
||||
}
|
||||
}
|
||||
elsif ($arg eq 'diff') {
|
||||
for my $path (keys %merge_rr) {
|
||||
my $name = $merge_rr{$path};
|
||||
system('diff', ((@ARGV == 0) ? ('-u') : @ARGV),
|
||||
'-L', "a/$path", '-L', "b/$path",
|
||||
"$rr_dir/$name/preimage", $path);
|
||||
}
|
||||
}
|
||||
elsif ($arg eq 'gc') {
|
||||
garbage_collect_rerere(@ARGV);
|
||||
}
|
||||
else {
|
||||
die "$0 unknown command: $arg\n";
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my %conflict = map { $_ => 1 } find_conflict();
|
||||
|
||||
# MERGE_RR records paths with conflicts immediately after merge
|
||||
# failed. Some of the conflicted paths might have been hand resolved
|
||||
# in the working tree since then, but the initial run would catch all
|
||||
# and register their preimages.
|
||||
|
||||
for my $path (keys %conflict) {
|
||||
# This path has conflict. If it is not recorded yet,
|
||||
# record the pre-image.
|
||||
if (!exists $merge_rr{$path}) {
|
||||
my ($name, $hunk) = compute_conflict_name($path);
|
||||
next unless ($hunk);
|
||||
$merge_rr{$path} = $name;
|
||||
if (! -d "$rr_dir/$name") {
|
||||
mkpath("$rr_dir/$name", 0, 0777);
|
||||
print STDERR "Recorded preimage for '$path'\n";
|
||||
record_preimage($path, "$rr_dir/$name/preimage");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Now some of the paths that had conflicts earlier might have been
|
||||
# hand resolved. Others may be similar to a conflict already that
|
||||
# was resolved before.
|
||||
|
||||
for my $path (keys %merge_rr) {
|
||||
my $name = $merge_rr{$path};
|
||||
|
||||
# We could resolve this automatically if we have images.
|
||||
if (-f "$rr_dir/$name/preimage" &&
|
||||
-f "$rr_dir/$name/postimage") {
|
||||
if (merge($name, $path)) {
|
||||
print STDERR "Resolved '$path' using previous resolution.\n";
|
||||
# Then we do not have to worry about this path
|
||||
# anymore.
|
||||
delete $merge_rr{$path};
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
# Let's see if we have resolved it.
|
||||
(undef, my $hunk) = compute_conflict_name($path);
|
||||
next if ($hunk);
|
||||
|
||||
print STDERR "Recorded resolution for '$path'.\n";
|
||||
copy($path, "$rr_dir/$name/postimage");
|
||||
# And we do not have to worry about this path anymore.
|
||||
delete $merge_rr{$path};
|
||||
}
|
||||
|
||||
# Write out the rest.
|
||||
write_rr();
|
||||
@@ -71,7 +71,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
|
||||
int posn = 0;
|
||||
struct object_request *obj_req = (struct object_request *)data;
|
||||
do {
|
||||
ssize_t retval = write(obj_req->local,
|
||||
ssize_t retval = xwrite(obj_req->local,
|
||||
(char *) ptr + posn, size - posn);
|
||||
if (retval < 0)
|
||||
return posn;
|
||||
@@ -175,7 +175,7 @@ static void start_object_request(struct object_request *obj_req)
|
||||
prevlocal = open(prevfile, O_RDONLY);
|
||||
if (prevlocal != -1) {
|
||||
do {
|
||||
prev_read = read(prevlocal, prev_buf, PREV_BUF_SIZE);
|
||||
prev_read = xread(prevlocal, prev_buf, PREV_BUF_SIZE);
|
||||
if (prev_read>0) {
|
||||
if (fwrite_sha1_file(prev_buf,
|
||||
1,
|
||||
|
||||
@@ -195,7 +195,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
|
||||
int posn = 0;
|
||||
struct transfer_request *request = (struct transfer_request *)data;
|
||||
do {
|
||||
ssize_t retval = write(request->local_fileno,
|
||||
ssize_t retval = xwrite(request->local_fileno,
|
||||
(char *) ptr + posn, size - posn);
|
||||
if (retval < 0)
|
||||
return posn;
|
||||
@@ -288,7 +288,7 @@ static void start_fetch_loose(struct transfer_request *request)
|
||||
prevlocal = open(prevfile, O_RDONLY);
|
||||
if (prevlocal != -1) {
|
||||
do {
|
||||
prev_read = read(prevlocal, prev_buf, PREV_BUF_SIZE);
|
||||
prev_read = xread(prevlocal, prev_buf, PREV_BUF_SIZE);
|
||||
if (prev_read>0) {
|
||||
if (fwrite_sha1_file(prev_buf,
|
||||
1,
|
||||
|
||||
@@ -224,7 +224,7 @@ socket_perror( const char *func, Socket_t *sock, int ret )
|
||||
static int
|
||||
socket_read( Socket_t *sock, char *buf, int len )
|
||||
{
|
||||
int n = read( sock->fd, buf, len );
|
||||
int n = xread( sock->fd, buf, len );
|
||||
if (n <= 0) {
|
||||
socket_perror( "read", sock, n );
|
||||
close( sock->fd );
|
||||
@@ -236,7 +236,7 @@ socket_read( Socket_t *sock, char *buf, int len )
|
||||
static int
|
||||
socket_write( Socket_t *sock, const char *buf, int len )
|
||||
{
|
||||
int n = write( sock->fd, buf, len );
|
||||
int n = write_in_full( sock->fd, buf, len );
|
||||
if (n != len) {
|
||||
socket_perror( "write", sock, n );
|
||||
close( sock->fd );
|
||||
@@ -390,7 +390,7 @@ arc4_init( void )
|
||||
fprintf( stderr, "Fatal: no random number source available.\n" );
|
||||
exit( 3 );
|
||||
}
|
||||
if (read( fd, dat, 128 ) != 128) {
|
||||
if (read_in_full( fd, dat, 128 ) != 128) {
|
||||
fprintf( stderr, "Fatal: cannot read random number source.\n" );
|
||||
exit( 3 );
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@ static void readjust_pack_header_and_sha1(unsigned char *sha1)
|
||||
/* Rewrite pack header with updated object number */
|
||||
if (lseek(output_fd, 0, SEEK_SET) != 0)
|
||||
die("cannot seek back: %s", strerror(errno));
|
||||
if (xread(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
|
||||
if (read_in_full(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
|
||||
die("cannot read pack header back: %s", strerror(errno));
|
||||
hdr.hdr_entries = htonl(nr_objects);
|
||||
if (lseek(output_fd, 0, SEEK_SET) != 0)
|
||||
@@ -814,7 +814,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
char buf[48];
|
||||
int len = snprintf(buf, sizeof(buf), "%s\t%s\n",
|
||||
report, sha1_to_hex(sha1));
|
||||
xwrite(1, buf, len);
|
||||
write_in_full(1, buf, len);
|
||||
|
||||
/*
|
||||
* Let's just mimic git-unpack-objects here and write
|
||||
|
||||
@@ -184,7 +184,7 @@ int fetch_ref(char *ref, unsigned char *sha1)
|
||||
fprintf(stderr, "cannot open %s\n", filename);
|
||||
return -1;
|
||||
}
|
||||
if (read(ifd, hex, 40) != 40 || get_sha1_hex(hex, sha1)) {
|
||||
if (read_in_full(ifd, hex, 40) != 40 || get_sha1_hex(hex, sha1)) {
|
||||
close(ifd);
|
||||
fprintf(stderr, "cannot read from %s\n", filename);
|
||||
return -1;
|
||||
|
||||
@@ -517,7 +517,7 @@ static int mkdir_p(const char *path, unsigned long mode)
|
||||
static void flush_buffer(int fd, const char *buf, unsigned long size)
|
||||
{
|
||||
while (size > 0) {
|
||||
long ret = xwrite(fd, buf, size);
|
||||
long ret = write_in_full(fd, buf, size);
|
||||
if (ret < 0) {
|
||||
/* Ignore epipe */
|
||||
if (errno == EPIPE)
|
||||
|
||||
2
path.c
2
path.c
@@ -114,7 +114,7 @@ int validate_headref(const char *path)
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
len = read(fd, buffer, sizeof(buffer)-1);
|
||||
len = read_in_full(fd, buffer, sizeof(buffer)-1);
|
||||
close(fd);
|
||||
|
||||
/*
|
||||
|
||||
@@ -104,7 +104,9 @@ static void walk_commit_list(struct rev_info *revs)
|
||||
}
|
||||
}
|
||||
|
||||
static int add_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1, char *datail, void *cb_data)
|
||||
static int add_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
|
||||
const char *email, unsigned long timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
{
|
||||
struct object *object;
|
||||
struct rev_info *revs = (struct rev_info *)cb_data;
|
||||
|
||||
@@ -870,7 +870,7 @@ static int ce_write_flush(SHA_CTX *context, int fd)
|
||||
unsigned int buffered = write_buffer_len;
|
||||
if (buffered) {
|
||||
SHA1_Update(context, write_buffer, buffered);
|
||||
if (write(fd, write_buffer, buffered) != buffered)
|
||||
if (write_in_full(fd, write_buffer, buffered) != buffered)
|
||||
return -1;
|
||||
write_buffer_len = 0;
|
||||
}
|
||||
@@ -919,7 +919,7 @@ static int ce_flush(SHA_CTX *context, int fd)
|
||||
|
||||
/* Flush first if not enough space for SHA1 signature */
|
||||
if (left + 20 > WRITE_BUFFER_SIZE) {
|
||||
if (write(fd, write_buffer, left) != left)
|
||||
if (write_in_full(fd, write_buffer, left) != left)
|
||||
return -1;
|
||||
left = 0;
|
||||
}
|
||||
@@ -927,7 +927,7 @@ static int ce_flush(SHA_CTX *context, int fd)
|
||||
/* Append the SHA1 signature at the end */
|
||||
SHA1_Final(write_buffer + left, context);
|
||||
left += 20;
|
||||
return (write(fd, write_buffer, left) != left) ? -1 : 0;
|
||||
return (write_in_full(fd, write_buffer, left) != left) ? -1 : 0;
|
||||
}
|
||||
|
||||
static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
|
||||
|
||||
36
refs.c
36
refs.c
@@ -284,7 +284,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
len = read(fd, buffer, sizeof(buffer)-1);
|
||||
len = read_in_full(fd, buffer, sizeof(buffer)-1);
|
||||
close(fd);
|
||||
|
||||
/*
|
||||
@@ -332,7 +332,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master)
|
||||
}
|
||||
lockpath = mkpath("%s.lock", git_HEAD);
|
||||
fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666);
|
||||
written = write(fd, ref, len);
|
||||
written = write_in_full(fd, ref, len);
|
||||
close(fd);
|
||||
if (written != len) {
|
||||
unlink(lockpath);
|
||||
@@ -971,7 +971,7 @@ static int log_ref_write(struct ref_lock *lock,
|
||||
sha1_to_hex(sha1),
|
||||
committer);
|
||||
}
|
||||
written = len <= maxlen ? write(logfd, logrec, len) : -1;
|
||||
written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
|
||||
free(logrec);
|
||||
close(logfd);
|
||||
if (written != len)
|
||||
@@ -990,8 +990,8 @@ int write_ref_sha1(struct ref_lock *lock,
|
||||
unlock_ref(lock);
|
||||
return 0;
|
||||
}
|
||||
if (write(lock->lock_fd, sha1_to_hex(sha1), 40) != 40 ||
|
||||
write(lock->lock_fd, &term, 1) != 1
|
||||
if (write_in_full(lock->lock_fd, sha1_to_hex(sha1), 40) != 40 ||
|
||||
write_in_full(lock->lock_fd, &term, 1) != 1
|
||||
|| close(lock->lock_fd) < 0) {
|
||||
error("Couldn't write %s", lock->lk->filename);
|
||||
unlock_ref(lock);
|
||||
@@ -1100,7 +1100,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
return 0;
|
||||
}
|
||||
|
||||
void for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
|
||||
int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
|
||||
{
|
||||
const char *logfile;
|
||||
FILE *logfp;
|
||||
@@ -1109,19 +1109,35 @@ void for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
|
||||
logfile = git_path("logs/%s", ref);
|
||||
logfp = fopen(logfile, "r");
|
||||
if (!logfp)
|
||||
return;
|
||||
return -1;
|
||||
while (fgets(buf, sizeof(buf), logfp)) {
|
||||
unsigned char osha1[20], nsha1[20];
|
||||
int len;
|
||||
char *email_end, *message;
|
||||
unsigned long timestamp;
|
||||
int len, ret, tz;
|
||||
|
||||
/* old SP new SP name <email> SP time TAB msg LF */
|
||||
len = strlen(buf);
|
||||
if (len < 83 || buf[len-1] != '\n' ||
|
||||
get_sha1_hex(buf, osha1) || buf[40] != ' ' ||
|
||||
get_sha1_hex(buf + 41, nsha1) || buf[81] != ' ')
|
||||
get_sha1_hex(buf + 41, nsha1) || buf[81] != ' ' ||
|
||||
!(email_end = strchr(buf + 82, '>')) ||
|
||||
email_end[1] != ' ' ||
|
||||
!(timestamp = strtoul(email_end + 2, &message, 10)) ||
|
||||
!message || message[0] != ' ' ||
|
||||
(message[1] != '+' && message[1] != '-') ||
|
||||
!isdigit(message[2]) || !isdigit(message[3]) ||
|
||||
!isdigit(message[4]) || !isdigit(message[5]) ||
|
||||
message[6] != '\t')
|
||||
continue; /* corrupt? */
|
||||
fn(osha1, nsha1, buf+82, cb_data);
|
||||
email_end[1] = '\0';
|
||||
tz = strtol(message + 1, NULL, 10);
|
||||
message += 7;
|
||||
ret = fn(osha1, nsha1, buf+82, timestamp, tz, message, cb_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
fclose(logfp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
4
refs.h
4
refs.h
@@ -45,8 +45,8 @@ extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, cons
|
||||
extern int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1);
|
||||
|
||||
/* iterate over reflog entries */
|
||||
typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, char *, void *);
|
||||
void for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data);
|
||||
typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, const char *, unsigned long, int, const char *, void *);
|
||||
int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data);
|
||||
|
||||
/** Returns 0 if target has the right format for a ref. **/
|
||||
extern int check_ref_format(const char *target);
|
||||
|
||||
@@ -505,7 +505,9 @@ static void handle_one_reflog_commit(unsigned char *sha1, void *cb_data)
|
||||
}
|
||||
}
|
||||
|
||||
static int handle_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1, char *detail, void *cb_data)
|
||||
static int handle_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
|
||||
const char *email, unsigned long timestamp, int tz,
|
||||
const char *message, void *cb_data)
|
||||
{
|
||||
handle_one_reflog_commit(osha1, cb_data);
|
||||
handle_one_reflog_commit(nsha1, cb_data);
|
||||
|
||||
@@ -65,14 +65,14 @@ static int pack_objects(int fd, struct ref *refs)
|
||||
memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40);
|
||||
buf[0] = '^';
|
||||
buf[41] = '\n';
|
||||
if (!write_in_full(pipe_fd[1], buf, 42,
|
||||
if (!write_or_whine(pipe_fd[1], buf, 42,
|
||||
"send-pack: send refs"))
|
||||
break;
|
||||
}
|
||||
if (!is_null_sha1(refs->new_sha1)) {
|
||||
memcpy(buf, sha1_to_hex(refs->new_sha1), 40);
|
||||
buf[40] = '\n';
|
||||
if (!write_in_full(pipe_fd[1], buf, 41,
|
||||
if (!write_or_whine(pipe_fd[1], buf, 41,
|
||||
"send-pack: send refs"))
|
||||
break;
|
||||
}
|
||||
|
||||
21
sha1_file.c
21
sha1_file.c
@@ -1611,20 +1611,13 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
|
||||
|
||||
static int write_buffer(int fd, const void *buf, size_t len)
|
||||
{
|
||||
while (len) {
|
||||
ssize_t size;
|
||||
ssize_t size;
|
||||
|
||||
size = write(fd, buf, len);
|
||||
if (!size)
|
||||
return error("file write: disk full");
|
||||
if (size < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
return error("file write error (%s)", strerror(errno));
|
||||
}
|
||||
len -= size;
|
||||
buf = (char *) buf + size;
|
||||
}
|
||||
size = write_in_full(fd, buf, len);
|
||||
if (!size)
|
||||
return error("file write: disk full");
|
||||
if (size < 0)
|
||||
return error("file write error (%s)", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1869,7 +1862,7 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
|
||||
if (ret != Z_OK)
|
||||
break;
|
||||
}
|
||||
size = read(fd, buffer + *bufposn, bufsize - *bufposn);
|
||||
size = xread(fd, buffer + *bufposn, bufsize - *bufposn);
|
||||
if (size <= 0) {
|
||||
close(local);
|
||||
unlink(tmpfile);
|
||||
|
||||
44
ssh-fetch.c
44
ssh-fetch.c
@@ -20,22 +20,6 @@ static int fd_out;
|
||||
static unsigned char remote_version;
|
||||
static unsigned char local_version = 1;
|
||||
|
||||
static ssize_t force_write(int fd, void *buffer, size_t length)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
while (ret < length) {
|
||||
ssize_t size = write(fd, (char *) buffer + ret, length - ret);
|
||||
if (size < 0) {
|
||||
return size;
|
||||
}
|
||||
if (size == 0) {
|
||||
return ret;
|
||||
}
|
||||
ret += size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int prefetches;
|
||||
|
||||
static struct object_list *in_transit;
|
||||
@@ -53,8 +37,9 @@ void prefetch(unsigned char *sha1)
|
||||
node->item = lookup_unknown_object(sha1);
|
||||
*end_of_transit = node;
|
||||
end_of_transit = &node->next;
|
||||
force_write(fd_out, &type, 1);
|
||||
force_write(fd_out, sha1, 20);
|
||||
/* XXX: what if these writes fail? */
|
||||
write_in_full(fd_out, &type, 1);
|
||||
write_in_full(fd_out, sha1, 20);
|
||||
prefetches++;
|
||||
}
|
||||
|
||||
@@ -82,7 +67,7 @@ int fetch(unsigned char *sha1)
|
||||
remote = conn_buf[0];
|
||||
memmove(conn_buf, conn_buf + 1, --conn_buf_posn);
|
||||
} else {
|
||||
if (read(fd_in, &remote, 1) < 1)
|
||||
if (xread(fd_in, &remote, 1) < 1)
|
||||
return -1;
|
||||
}
|
||||
/* fprintf(stderr, "Got %d\n", remote); */
|
||||
@@ -97,9 +82,11 @@ int fetch(unsigned char *sha1)
|
||||
static int get_version(void)
|
||||
{
|
||||
char type = 'v';
|
||||
write(fd_out, &type, 1);
|
||||
write(fd_out, &local_version, 1);
|
||||
if (read(fd_in, &remote_version, 1) < 1) {
|
||||
if (write_in_full(fd_out, &type, 1) != 1 ||
|
||||
write_in_full(fd_out, &local_version, 1)) {
|
||||
return error("Couldn't request version from remote end");
|
||||
}
|
||||
if (xread(fd_in, &remote_version, 1) < 1) {
|
||||
return error("Couldn't read version from remote end");
|
||||
}
|
||||
return 0;
|
||||
@@ -109,12 +96,17 @@ int fetch_ref(char *ref, unsigned char *sha1)
|
||||
{
|
||||
signed char remote;
|
||||
char type = 'r';
|
||||
write(fd_out, &type, 1);
|
||||
write(fd_out, ref, strlen(ref) + 1);
|
||||
read(fd_in, &remote, 1);
|
||||
int length = strlen(ref) + 1;
|
||||
if (write_in_full(fd_out, &type, 1) != 1 ||
|
||||
write_in_full(fd_out, ref, length) != length)
|
||||
return -1;
|
||||
|
||||
if (read_in_full(fd_in, &remote, 1) != 1)
|
||||
return -1;
|
||||
if (remote < 0)
|
||||
return remote;
|
||||
read(fd_in, sha1, 20);
|
||||
if (read_in_full(fd_in, sha1, 20) != 20)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
35
ssh-upload.c
35
ssh-upload.c
@@ -21,17 +21,14 @@ static int serve_object(int fd_in, int fd_out) {
|
||||
ssize_t size;
|
||||
unsigned char sha1[20];
|
||||
signed char remote;
|
||||
int posn = 0;
|
||||
do {
|
||||
size = read(fd_in, sha1 + posn, 20 - posn);
|
||||
if (size < 0) {
|
||||
perror("git-ssh-upload: read ");
|
||||
return -1;
|
||||
}
|
||||
if (!size)
|
||||
return -1;
|
||||
posn += size;
|
||||
} while (posn < 20);
|
||||
|
||||
size = read_in_full(fd_in, sha1, 20);
|
||||
if (size < 0) {
|
||||
perror("git-ssh-upload: read ");
|
||||
return -1;
|
||||
}
|
||||
if (!size)
|
||||
return -1;
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1));
|
||||
@@ -44,7 +41,8 @@ static int serve_object(int fd_in, int fd_out) {
|
||||
remote = -1;
|
||||
}
|
||||
|
||||
write(fd_out, &remote, 1);
|
||||
if (write_in_full(fd_out, &remote, 1) != 1)
|
||||
return 0;
|
||||
|
||||
if (remote < 0)
|
||||
return 0;
|
||||
@@ -54,9 +52,9 @@ static int serve_object(int fd_in, int fd_out) {
|
||||
|
||||
static int serve_version(int fd_in, int fd_out)
|
||||
{
|
||||
if (read(fd_in, &remote_version, 1) < 1)
|
||||
if (xread(fd_in, &remote_version, 1) < 1)
|
||||
return -1;
|
||||
write(fd_out, &local_version, 1);
|
||||
write_in_full(fd_out, &local_version, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -67,7 +65,7 @@ static int serve_ref(int fd_in, int fd_out)
|
||||
int posn = 0;
|
||||
signed char remote = 0;
|
||||
do {
|
||||
if (read(fd_in, ref + posn, 1) < 1)
|
||||
if (posn >= PATH_MAX || xread(fd_in, ref + posn, 1) < 1)
|
||||
return -1;
|
||||
posn++;
|
||||
} while (ref[posn - 1]);
|
||||
@@ -77,10 +75,11 @@ static int serve_ref(int fd_in, int fd_out)
|
||||
|
||||
if (get_ref_sha1(ref, sha1))
|
||||
remote = -1;
|
||||
write(fd_out, &remote, 1);
|
||||
if (write_in_full(fd_out, &remote, 1) != 1)
|
||||
return 0;
|
||||
if (remote)
|
||||
return 0;
|
||||
write(fd_out, sha1, 20);
|
||||
write_in_full(fd_out, sha1, 20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -89,7 +88,7 @@ static void service(int fd_in, int fd_out) {
|
||||
char type;
|
||||
int retval;
|
||||
do {
|
||||
retval = read(fd_in, &type, 1);
|
||||
retval = xread(fd_in, &type, 1);
|
||||
if (retval < 1) {
|
||||
if (retval < 0)
|
||||
perror("git-ssh-upload: read ");
|
||||
|
||||
@@ -401,5 +401,22 @@ test_expect_success numbers '
|
||||
test z1048576 = "z$m"
|
||||
'
|
||||
|
||||
rm .git/config
|
||||
|
||||
git-repo-config quote.leading " test"
|
||||
git-repo-config quote.ending "test "
|
||||
git-repo-config quote.semicolon "test;test"
|
||||
git-repo-config quote.hash "test#test"
|
||||
|
||||
cat > expect << EOF
|
||||
[quote]
|
||||
leading = " test"
|
||||
ending = "test "
|
||||
semicolon = "test;test"
|
||||
hash = "test#test"
|
||||
EOF
|
||||
|
||||
test_expect_success 'quoting' 'cmp .git/config expect'
|
||||
|
||||
test_done
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ test_expect_success \
|
||||
'see if a branch still exists when packed' \
|
||||
'git-branch b &&
|
||||
git-pack-refs --all &&
|
||||
rm .git/refs/heads/b &&
|
||||
rm -f .git/refs/heads/b &&
|
||||
echo "$SHA1 refs/heads/b" >expect &&
|
||||
git-show-ref b >result &&
|
||||
diff expect result'
|
||||
|
||||
@@ -68,7 +68,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
fd = open (argv[4], O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
||||
if (fd < 0 || write(fd, out_buf, out_size) != out_size) {
|
||||
if (fd < 0 || write_in_full(fd, out_buf, out_size) != out_size) {
|
||||
perror(argv[4]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
4
trace.c
4
trace.c
@@ -101,7 +101,7 @@ void trace_printf(const char *format, ...)
|
||||
nfvasprintf(&trace_str, format, rest);
|
||||
va_end(rest);
|
||||
|
||||
write_or_whine(fd, trace_str, strlen(trace_str), err_msg);
|
||||
write_or_whine_pipe(fd, trace_str, strlen(trace_str), err_msg);
|
||||
|
||||
free(trace_str);
|
||||
|
||||
@@ -139,7 +139,7 @@ void trace_argv_printf(const char **argv, int count, const char *format, ...)
|
||||
strncpy(trace_str + format_len, argv_str, argv_len);
|
||||
strcpy(trace_str + trace_len - 1, "\n");
|
||||
|
||||
write_or_whine(fd, trace_str, trace_len, err_msg);
|
||||
write_or_whine_pipe(fd, trace_str, trace_len, err_msg);
|
||||
|
||||
free(argv_str);
|
||||
free(format_str);
|
||||
|
||||
@@ -17,7 +17,7 @@ static char *create_temp_file(unsigned char *sha1)
|
||||
fd = mkstemp(path);
|
||||
if (fd < 0)
|
||||
die("unable to create temp-file");
|
||||
if (write(fd, buf, size) != size)
|
||||
if (write_in_full(fd, buf, size) != size)
|
||||
die("unable to write temp-file");
|
||||
close(fd);
|
||||
return path;
|
||||
|
||||
@@ -55,6 +55,7 @@ static ssize_t send_client_data(int fd, const char *data, ssize_t sz)
|
||||
/* emergency quit */
|
||||
fd = 2;
|
||||
if (fd == 2) {
|
||||
/* XXX: are we happy to lose stuff here? */
|
||||
xwrite(fd, data, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -242,7 +243,7 @@ static void create_pack_file(void)
|
||||
*cp++ = buffered;
|
||||
outsz++;
|
||||
}
|
||||
sz = read(pu_pipe[0], cp,
|
||||
sz = xread(pu_pipe[0], cp,
|
||||
sizeof(data) - outsz);
|
||||
if (0 < sz)
|
||||
;
|
||||
@@ -267,7 +268,7 @@ static void create_pack_file(void)
|
||||
/* Status ready; we ship that in the side-band
|
||||
* or dump to the standard error.
|
||||
*/
|
||||
sz = read(pe_pipe[0], progress,
|
||||
sz = xread(pe_pipe[0], progress,
|
||||
sizeof(progress));
|
||||
if (0 < sz)
|
||||
send_client_data(2, progress, sz);
|
||||
|
||||
138
write_or_die.c
138
write_or_die.c
@@ -1,83 +1,107 @@
|
||||
#include "cache.h"
|
||||
|
||||
void read_or_die(int fd, void *buf, size_t count)
|
||||
int read_in_full(int fd, void *buf, size_t count)
|
||||
{
|
||||
char *p = buf;
|
||||
ssize_t loaded;
|
||||
ssize_t total = 0;
|
||||
ssize_t loaded = 0;
|
||||
|
||||
while (count > 0) {
|
||||
loaded = xread(fd, p, count);
|
||||
if (loaded == 0)
|
||||
die("unexpected end of file");
|
||||
else if (loaded < 0)
|
||||
die("read error (%s)", strerror(errno));
|
||||
if (loaded <= 0) {
|
||||
if (total)
|
||||
return total;
|
||||
else
|
||||
return loaded;
|
||||
}
|
||||
count -= loaded;
|
||||
p += loaded;
|
||||
total += loaded;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void read_or_die(int fd, void *buf, size_t count)
|
||||
{
|
||||
ssize_t loaded;
|
||||
|
||||
loaded = read_in_full(fd, buf, count);
|
||||
if (loaded == 0)
|
||||
die("unexpected end of file");
|
||||
else if (loaded < 0)
|
||||
die("read error (%s)", strerror(errno));
|
||||
}
|
||||
|
||||
int write_in_full(int fd, const void *buf, size_t count)
|
||||
{
|
||||
const char *p = buf;
|
||||
ssize_t total = 0;
|
||||
ssize_t written = 0;
|
||||
|
||||
while (count > 0) {
|
||||
written = xwrite(fd, p, count);
|
||||
if (written <= 0) {
|
||||
if (total)
|
||||
return total;
|
||||
else
|
||||
return written;
|
||||
}
|
||||
count -= written;
|
||||
p += written;
|
||||
total += written;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void write_or_die(int fd, const void *buf, size_t count)
|
||||
{
|
||||
const char *p = buf;
|
||||
ssize_t written;
|
||||
|
||||
while (count > 0) {
|
||||
written = xwrite(fd, p, count);
|
||||
if (written == 0)
|
||||
die("disk full?");
|
||||
else if (written < 0) {
|
||||
if (errno == EPIPE)
|
||||
exit(0);
|
||||
die("write error (%s)", strerror(errno));
|
||||
}
|
||||
count -= written;
|
||||
p += written;
|
||||
written = write_in_full(fd, buf, count);
|
||||
if (written == 0)
|
||||
die("disk full?");
|
||||
else if (written < 0) {
|
||||
if (errno == EPIPE)
|
||||
exit(0);
|
||||
die("write error (%s)", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg)
|
||||
{
|
||||
ssize_t written;
|
||||
|
||||
written = write_in_full(fd, buf, count);
|
||||
if (written == 0) {
|
||||
fprintf(stderr, "%s: disk full?\n", msg);
|
||||
return 0;
|
||||
}
|
||||
else if (written < 0) {
|
||||
if (errno == EPIPE)
|
||||
exit(0);
|
||||
fprintf(stderr, "%s: write error (%s)\n",
|
||||
msg, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int write_or_whine(int fd, const void *buf, size_t count, const char *msg)
|
||||
{
|
||||
const char *p = buf;
|
||||
ssize_t written;
|
||||
|
||||
while (count > 0) {
|
||||
written = xwrite(fd, p, count);
|
||||
if (written == 0) {
|
||||
fprintf(stderr, "%s: disk full?\n", msg);
|
||||
return 0;
|
||||
}
|
||||
else if (written < 0) {
|
||||
if (errno == EPIPE)
|
||||
exit(0);
|
||||
fprintf(stderr, "%s: write error (%s)\n",
|
||||
msg, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
count -= written;
|
||||
p += written;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int write_in_full(int fd, const void *buf, size_t count, const char *msg)
|
||||
{
|
||||
const char *p = buf;
|
||||
ssize_t written;
|
||||
|
||||
while (count > 0) {
|
||||
written = xwrite(fd, p, count);
|
||||
if (written == 0) {
|
||||
fprintf(stderr, "%s: disk full?\n", msg);
|
||||
return 0;
|
||||
}
|
||||
else if (written < 0) {
|
||||
fprintf(stderr, "%s: write error (%s)\n",
|
||||
msg, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
count -= written;
|
||||
p += written;
|
||||
written = write_in_full(fd, buf, count);
|
||||
if (written == 0) {
|
||||
fprintf(stderr, "%s: disk full?\n", msg);
|
||||
return 0;
|
||||
}
|
||||
else if (written < 0) {
|
||||
fprintf(stderr, "%s: write error (%s)\n",
|
||||
msg, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user