Merge branch 'master' of git://repo.or.cz/alt-git

This commit is contained in:
Johannes Sixt
2008-07-22 08:58:39 +02:00
22 changed files with 361 additions and 131 deletions

View File

@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]
[--update | -u] [--refresh] [--ignore-errors] [--]
[--all | [--update | -u]] [--refresh] [--ignore-errors] [--]
<filepattern>...
DESCRIPTION
@@ -86,6 +86,12 @@ OPTIONS
command line. If no paths are specified, all tracked files in the
current directory and its subdirectories are updated.
-A::
--all::
Update files that git already knows about (same as '\--update')
and add all untracked files that are not ignored by '.gitignore'
mechanism.
--refresh::
Don't add the file(s), but only refresh their stat()
information in the index.

View File

@@ -13,7 +13,7 @@ SYNOPSIS
[--3way] [--interactive] [--binary]
[--whitespace=<option>] [-C<n>] [-p<n>]
[<mbox> | <Maildir>...]
'git am' (--skip | --resolved)
'git am' (--skip | --resolved | --abort)
DESCRIPTION
-----------
@@ -99,6 +99,9 @@ default. You could use `--no-utf8` to override this.
or `--skip` to handle the failure. This is solely
for internal use between 'git-rebase' and 'git-am'.
--abort::
Restore the original branch and abort the patching operation.
DISCUSSION
----------

View File

@@ -324,6 +324,7 @@ endif
export PERL_PATH
LIB_FILE=libgit.a
COMPAT_LIB = compat/lib.a
XDIFF_LIB=xdiff/lib.a
LIB_H += archive.h
@@ -1204,8 +1205,11 @@ git-http-push$X: revision.o http.o http-push.o $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
git-shell$X: compat/strlcpy.o abspath.o ctype.o exec_cmd.o quote.o strbuf.o usage.o wrapper.o shell.o
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^)
$(COMPAT_LIB): $(COMPAT_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(COMPAT_OBJS)
git-shell$X: abspath.o ctype.o exec_cmd.o quote.o strbuf.o usage.o wrapper.o shell.o $(COMPAT_LIB)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(COMPAT_LIB)
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
@@ -1403,7 +1407,7 @@ distclean: clean
clean:
$(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \
$(LIB_FILE) $(XDIFF_LIB)
$(LIB_FILE) $(XDIFF_LIB) $(COMPAT_LIB)
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
$(RM) $(TEST_PROGRAMS)
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*

View File

@@ -140,9 +140,8 @@ static void refresh(int verbose, const char **pathspec)
for (specs = 0; pathspec[specs]; specs++)
/* nothing */;
seen = xcalloc(specs, 1);
if (read_cache() < 0)
die("index file corrupt");
refresh_index(&the_index, verbose ? 0 : REFRESH_QUIET, pathspec, seen);
refresh_index(&the_index, verbose ? REFRESH_SAY_CHANGED : REFRESH_QUIET,
pathspec, seen);
for (i = 0; i < specs; i++) {
if (!seen[i])
die("pathspec '%s' did not match any files", pathspec[i]);
@@ -192,7 +191,7 @@ static const char ignore_error[] =
"The following paths are ignored by one of your .gitignore files:\n";
static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
static int ignore_add_errors;
static int ignore_add_errors, addremove;
static struct option builtin_add_options[] = {
OPT__DRY_RUN(&show_only),
@@ -202,6 +201,7 @@ static struct option builtin_add_options[] = {
OPT_BOOLEAN('p', "patch", &patch_interactive, "interactive patching"),
OPT_BOOLEAN('f', "force", &ignored_too, "allow adding otherwise ignored files"),
OPT_BOOLEAN('u', "update", &take_worktree_changes, "update tracked files"),
OPT_BOOLEAN('A', "all", &addremove, "add all, noticing removal of tracked files"),
OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"),
OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, "just skip files which cannot be added because of errors"),
OPT_END(),
@@ -216,13 +216,36 @@ static int add_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb);
}
static int add_files(struct dir_struct *dir, int flags)
{
int i, exit_status = 0;
if (dir->ignored_nr) {
fprintf(stderr, ignore_error);
for (i = 0; i < dir->ignored_nr; i++)
fprintf(stderr, "%s\n", dir->ignored[i]->name);
fprintf(stderr, "Use -f if you really want to add them.\n");
die("no files added");
}
for (i = 0; i < dir->nr; i++)
if (add_file_to_cache(dir->entries[i]->name, flags)) {
if (!ignore_add_errors)
die("adding files failed");
exit_status = 1;
}
return exit_status;
}
int cmd_add(int argc, const char **argv, const char *prefix)
{
int exit_status = 0;
int i, newfd;
int newfd;
const char **pathspec;
struct dir_struct dir;
int flags;
int add_new_files;
int require_pathspec;
argc = parse_options(argc, argv, builtin_add_options,
builtin_add_usage, 0);
@@ -233,53 +256,51 @@ int cmd_add(int argc, const char **argv, const char *prefix)
git_config(add_config, NULL);
if (addremove && take_worktree_changes)
die("-A and -u are mutually incompatible");
if (addremove && !argc) {
static const char *here[2] = { ".", NULL };
argc = 1;
argv = here;
}
add_new_files = !take_worktree_changes && !refresh_only;
require_pathspec = !take_worktree_changes;
newfd = hold_locked_index(&lock_file, 1);
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
(show_only ? ADD_CACHE_PRETEND : 0) |
(ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0));
if (take_worktree_changes) {
const char **pathspec;
if (read_cache() < 0)
die("index file corrupt");
pathspec = get_pathspec(prefix, argv);
exit_status = add_files_to_cache(prefix, pathspec, flags);
goto finish;
}
if (argc == 0) {
if (require_pathspec && argc == 0) {
fprintf(stderr, "Nothing specified, nothing added.\n");
fprintf(stderr, "Maybe you wanted to say 'git add .'?\n");
return 0;
}
pathspec = get_pathspec(prefix, argv);
/*
* If we are adding new files, we need to scan the working
* tree to find the ones that match pathspecs; this needs
* to be done before we read the index.
*/
if (add_new_files)
fill_directory(&dir, pathspec, ignored_too);
if (read_cache() < 0)
die("index file corrupt");
if (refresh_only) {
refresh(verbose, pathspec);
goto finish;
}
fill_directory(&dir, pathspec, ignored_too);
if (take_worktree_changes || addremove)
exit_status |= add_files_to_cache(prefix, pathspec, flags);
if (read_cache() < 0)
die("index file corrupt");
if (dir.ignored_nr) {
fprintf(stderr, ignore_error);
for (i = 0; i < dir.ignored_nr; i++) {
fprintf(stderr, "%s\n", dir.ignored[i]->name);
}
fprintf(stderr, "Use -f if you really want to add them.\n");
die("no files added");
}
for (i = 0; i < dir.nr; i++)
if (add_file_to_cache(dir.entries[i]->name, flags)) {
if (!ignore_add_errors)
die("adding files failed");
exit_status = 1;
}
if (add_new_files)
exit_status |= add_files(&dir, flags);
finish:
if (active_cache_changed) {

View File

@@ -498,7 +498,7 @@ static int grep_object(struct grep_opt *opt, const char **paths,
}
static const char builtin_grep_usage[] =
"git grep <option>* <rev>* [-e] <pattern> [<path>...]";
"git grep <option>* [-e] <pattern> <rev>* [[--] <path>...]";
static const char emsg_invalid_context_len[] =
"%s: invalid context length argument";

View File

@@ -50,11 +50,9 @@ static size_t use_strategies_nr, use_strategies_alloc;
static const char *branch;
static struct strategy all_strategy[] = {
{ "recur", NO_TRIVIAL },
{ "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL },
{ "octopus", DEFAULT_OCTOPUS },
{ "resolve", 0 },
{ "stupid", 0 },
{ "ours", NO_FAST_FORWARD | NO_TRIVIAL },
{ "subtree", NO_FAST_FORWARD | NO_TRIVIAL },
};
@@ -68,10 +66,11 @@ static int option_parse_message(const struct option *opt,
if (unset)
strbuf_setlen(buf, 0);
else {
else if (arg) {
strbuf_addf(buf, "%s\n\n", arg);
have_message = 1;
}
} else
return error("switch `m' requires a value");
return 0;
}

View File

@@ -14,7 +14,7 @@ static const char * const push_usage[] = {
NULL,
};
static int thin, verbose;
static int thin;
static const char *receivepack;
static const char **refspec;
@@ -84,7 +84,7 @@ static int do_push(const char *repo, int flags)
if (thin)
transport_set_option(transport, TRANS_OPT_THIN, "yes");
if (verbose)
if (flags & TRANSPORT_PUSH_VERBOSE)
fprintf(stderr, "Pushing to %s\n", remote->url[i]);
err = transport_push(transport, refspec_nr, refspec, flags);
err |= transport_disconnect(transport);
@@ -101,22 +101,19 @@ static int do_push(const char *repo, int flags)
int cmd_push(int argc, const char **argv, const char *prefix)
{
int flags = 0;
int all = 0;
int mirror = 0;
int dry_run = 0;
int force = 0;
int tags = 0;
int rc;
const char *repo = NULL; /* default repository */
struct option options[] = {
OPT__VERBOSE(&verbose),
OPT_BIT('v', "verbose", &flags, "be verbose", TRANSPORT_PUSH_VERBOSE),
OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
OPT_BOOLEAN( 0 , "all", &all, "push all refs"),
OPT_BOOLEAN( 0 , "mirror", &mirror, "mirror all refs"),
OPT_BIT( 0 , "all", &flags, "push all refs", TRANSPORT_PUSH_ALL),
OPT_BIT( 0 , "mirror", &flags, "mirror all refs",
(TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
OPT_BOOLEAN( 0 , "dry-run", &dry_run, "dry run"),
OPT_BOOLEAN('f', "force", &force, "force updates"),
OPT_BIT( 0 , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
@@ -125,18 +122,8 @@ int cmd_push(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, options, push_usage, 0);
if (force)
flags |= TRANSPORT_PUSH_FORCE;
if (dry_run)
flags |= TRANSPORT_PUSH_DRY_RUN;
if (verbose)
flags |= TRANSPORT_PUSH_VERBOSE;
if (tags)
add_refspec("refs/tags/*");
if (all)
flags |= TRANSPORT_PUSH_ALL;
if (mirror)
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
if (argc > 0) {
repo = argv[0];

View File

@@ -96,7 +96,7 @@ static int update_index_refresh(int fd, struct lock_file *index_lock)
if (read_cache() < 0)
return error("Could not read index");
result = refresh_cache(0) ? 1 : 0;
result = refresh_cache(REFRESH_SAY_CHANGED) ? 1 : 0;
if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(index_lock))
return error ("Could not refresh index");

View File

@@ -397,7 +397,8 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
#define REFRESH_UNMERGED 0x0002 /* allow unmerged */
#define REFRESH_QUIET 0x0004 /* be quiet about it */
#define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */
#define REFRESH_IGNORE_SUBMODULES 0x0008 /* ignore submodules */
#define REFRESH_IGNORE_SUBMODULES 0x0010 /* ignore submodules */
#define REFRESH_SAY_CHANGED 0x0020 /* say "changed" not "needs update" */
extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen);
struct lock_file {

View File

@@ -22,6 +22,7 @@ p= pass it through git-apply
resolvemsg= override error message when patch failure occurs
r,resolved to be used after a patch failure
skip skip the current patch
abort restore the original branch and abort the patching operation.
rebasing (internal use for git-rebase)"
. git-sh-setup
@@ -54,6 +55,7 @@ stop_here_user_resolve () {
fi
echo "When you have resolved this problem run \"$cmdline --resolved\"."
echo "If you would prefer to skip this patch, instead run \"$cmdline --skip\"."
echo "To restore the original branch and stop patching run \"$cmdline --abort\"."
stop_here $1
}
@@ -120,7 +122,7 @@ It does not apply to blobs recorded in its index."
prec=4
dotest="$GIT_DIR/rebase"
sign= utf8=t keep= skip= interactive= resolved= binary= rebasing=
sign= utf8=t keep= skip= interactive= resolved= binary= rebasing= abort=
resolvemsg= resume=
git_apply_opt=
@@ -145,6 +147,8 @@ do
resolved=t ;;
--skip)
skip=t ;;
--abort)
abort=t ;;
--rebasing)
rebasing=t threeway=t keep=t binary=t ;;
-d|--dotest)
@@ -177,7 +181,7 @@ fi
if test -d "$dotest"
then
case "$#,$skip$resolved" in
case "$#,$skip$resolved$abort" in
0,*t*)
# Explicit resume command and we do not have file, so
# we are happy.
@@ -197,9 +201,18 @@ then
esac ||
die "previous rebase directory $dotest still exists but mbox given."
resume=yes
case "$abort" in
t)
git rerere clear
git read-tree --reset -u HEAD ORIG_HEAD
git reset ORIG_HEAD
rm -fr "$dotest"
exit ;;
esac
else
# Make sure we are not given --skip nor --resolved
test ",$skip,$resolved," = ,,, ||
# Make sure we are not given --skip, --resolved, nor --abort
test "$skip$resolved$abort" = "" ||
die "Resolve operation not in progress, we are not resuming."
# Start afresh.

View File

@@ -1226,7 +1226,7 @@ sub linearize_history {
sub find_file_type_and_diff_status {
my ($path) = @_;
return ('dir', '') if $path eq '.';
return ('dir', '') if $path eq '';
my $diff_output =
command_oneline(qw(diff --cached --name-status --), $path) || "";

View File

@@ -980,7 +980,10 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
int ignore_submodules = (flags & REFRESH_IGNORE_SUBMODULES) != 0;
unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
const char *needs_update_message;
needs_update_message = ((flags & REFRESH_SAY_CHANGED)
? "locally modified" : "needs update");
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce, *new;
int cache_errno = 0;
@@ -1019,7 +1022,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
}
if (quiet)
continue;
printf("%s: needs update\n", ce->name);
printf("%s: %s\n", ce->name, needs_update_message);
has_errors = 1;
continue;
}

View File

@@ -1308,34 +1308,28 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
int format_tracking_info(struct branch *branch, struct strbuf *sb)
{
int num_ours, num_theirs;
const char *base, *remote_msg;
const char *base;
if (!stat_tracking_info(branch, &num_ours, &num_theirs))
return 0;
base = branch->merge[0]->dst;
if (!prefixcmp(base, "refs/remotes/")) {
remote_msg = " remote";
base += strlen("refs/remotes/");
} else {
remote_msg = "";
}
if (!num_theirs)
strbuf_addf(sb, "Your branch is ahead of the tracked%s branch '%s' "
strbuf_addf(sb, "Your branch is ahead of '%s' "
"by %d commit%s.\n",
remote_msg, base,
num_ours, (num_ours == 1) ? "" : "s");
base, num_ours, (num_ours == 1) ? "" : "s");
else if (!num_ours)
strbuf_addf(sb, "Your branch is behind the tracked%s branch '%s' "
"by %d commit%s,\n"
strbuf_addf(sb, "Your branch is behind '%s' "
"by %d commit%s, "
"and can be fast-forwarded.\n",
remote_msg, base,
num_theirs, (num_theirs == 1) ? "" : "s");
base, num_theirs, (num_theirs == 1) ? "" : "s");
else
strbuf_addf(sb, "Your branch and the tracked%s branch '%s' "
"have diverged,\nand respectively "
"have %d and %d different commit(s) each.\n",
remote_msg, base,
num_ours, num_theirs);
strbuf_addf(sb, "Your branch and '%s' have diverged,\n"
"and have %d and %d different commit(s) each, "
"respectively.\n",
base, num_ours, num_theirs);
return 1;
}

View File

@@ -278,10 +278,13 @@ static int do_plain_rerere(struct path_list *rr, int fd)
if (has_resolution(name)) {
if (!merge(name, path)) {
fprintf(stderr, "Resolved '%s' using "
"previous resolution.\n", path);
if (rerere_autoupdate)
path_list_insert(path, &update);
fprintf(stderr,
"%s '%s' using previous resolution.\n",
rerere_autoupdate
? "Staged" : "Resolved",
path);
goto mark_resolved;
}
}

View File

@@ -0,0 +1,89 @@
#!/bin/sh
test_description='update-index with options'
. ./test-lib.sh
test_expect_success basics '
>one &&
>two &&
>three &&
# need --add when adding
test_must_fail git update-index one &&
test -z "$(git ls-files)" &&
git update-index --add one &&
test zone = "z$(git ls-files)" &&
# update-index is atomic
echo 1 >one &&
test_must_fail git update-index one two &&
echo "M one" >expect &&
git diff-files --name-status >actual &&
test_cmp expect actual &&
git update-index --add one two three &&
for i in one three two; do echo $i; done >expect &&
git ls-files >actual &&
test_cmp expect actual &&
test_tick &&
(
test_create_repo xyzzy &&
cd xyzzy &&
>file &&
git add file
git commit -m "sub initial"
) &&
git add xyzzy &&
test_tick &&
git commit -m initial &&
git tag initial
'
test_expect_success '--ignore-missing --refresh' '
git reset --hard initial &&
echo 2 >one &&
test_must_fail git update-index --refresh &&
echo 1 >one &&
git update-index --refresh &&
rm -f two &&
test_must_fail git update-index --refresh &&
git update-index --ignore-missing --refresh
'
test_expect_success '--unmerged --refresh' '
git reset --hard initial &&
info=$(git ls-files -s one | sed -e "s/ 0 / 1 /") &&
git rm --cached one &&
echo "$info" | git update-index --index-info &&
test_must_fail git update-index --refresh &&
git update-index --unmerged --refresh &&
echo 2 >two &&
test_must_fail git update-index --unmerged --refresh >actual &&
grep two actual &&
! grep one actual &&
! grep three actual
'
test_expect_success '--ignore-submodules --refresh (1)' '
git reset --hard initial &&
rm -f two &&
test_must_fail git update-index --ignore-submodules --refresh
'
test_expect_success '--ignore-submodules --refresh (2)' '
git reset --hard initial &&
test_tick &&
(
cd xyzzy &&
git commit -m "sub second" --allow-empty
) &&
test_must_fail git update-index --refresh &&
test_must_fail git update-index --ignore-missing --refresh &&
git update-index --ignore-submodules --refresh
'
test_done

44
t/t2202-add-addremove.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/sh
test_description='git add --all'
. ./test-lib.sh
test_expect_success setup '
(
echo .gitignore
echo will-remove
) >expect &&
(
echo actual
echo expect
echo ignored
) >.gitignore &&
>will-remove &&
git add --all &&
test_tick &&
git commit -m initial &&
git ls-files >actual &&
test_cmp expect actual
'
test_expect_success 'git add --all' '
(
echo .gitignore
echo not-ignored
echo "M .gitignore"
echo "A not-ignored"
echo "D will-remove"
) >expect &&
>ignored &&
>not-ignored &&
echo modification >>.gitignore &&
rm -f will-remove &&
git add --all &&
git update-index --refresh &&
git ls-files >actual &&
git diff-index --name-status --cached HEAD >>actual &&
test_cmp expect actual
'
test_done

56
t/t4151-am-abort.sh Executable file
View File

@@ -0,0 +1,56 @@
#!/bin/sh
test_description='am --abort'
. ./test-lib.sh
test_expect_success setup '
for i in a b c d e f g
do
echo $i
done >file-1 &&
cp file-1 file-2 &&
test_tick &&
git add file-1 file-2 &&
git commit -m initial &&
git tag initial &&
for i in 2 3 4 5
do
echo $i >>file-1 &&
test_tick &&
git commit -a -m $i || break
done &&
git format-patch initial &&
git checkout -b side initial &&
echo local change >file-2-expect
'
for with3 in '' ' -3'
do
test_expect_success "am$with3 stops at a patch that does not apply" '
git reset --hard initial &&
cp file-2-expect file-2 &&
test_must_fail git am$with3 000[124]-*.patch &&
git log --pretty=tformat:%s >actual &&
for i in 3 2 initial
do
echo $i
done >expect &&
test_cmp expect actual
'
test_expect_success "am --abort goes back after failed am$with3" '
git-am --abort &&
git rev-parse HEAD >actual &&
git rev-parse initial >expect &&
test_cmp expect actual &&
test_cmp file-2-expect file-2 &&
git diff-index --exit-code --cached HEAD &&
test ! -f .git/rr-cache/MERGE_RR
'
done
test_done

View File

@@ -419,7 +419,7 @@ test_expect_success 'resetting an unmodified path is a no-op' '
'
cat > expect << EOF
file2: needs update
file2: locally modified
EOF
test_expect_success '--mixed refreshes the index' '

View File

@@ -221,7 +221,7 @@ test_expect_success 'setup' '
test_debug 'gitk --all'
test_expect_failure 'test option parsing' '
test_expect_success 'test option parsing' '
test_must_fail git merge -$ c1 &&
test_must_fail git merge --no-such c1 &&
test_must_fail git merge -s foobar c1 &&

View File

@@ -438,6 +438,13 @@ test_expect_success 'cvs update (-p)' '
test -z "$(cat failures)"
'
cd "$WORKDIR"
test_expect_success 'cvs update (module list supports packed refs)' '
GIT_DIR="$SERVERDIR" git pack-refs --all &&
GIT_CONFIG="$git_config" cvs -n up -d 2> out &&
grep "cvs update: New directory \`master'\''" < out
'
#------------
# CVS STATUS
#------------

View File

@@ -133,6 +133,44 @@ ssize_t xwrite(int fd, const void *buf, size_t len)
}
}
ssize_t read_in_full(int fd, void *buf, size_t count)
{
char *p = buf;
ssize_t total = 0;
while (count > 0) {
ssize_t loaded = xread(fd, p, count);
if (loaded <= 0)
return total ? total : loaded;
count -= loaded;
p += loaded;
total += loaded;
}
return total;
}
ssize_t write_in_full(int fd, const void *buf, size_t count)
{
const char *p = buf;
ssize_t total = 0;
while (count > 0) {
ssize_t written = xwrite(fd, p, count);
if (written < 0)
return -1;
if (!written) {
errno = ENOSPC;
return -1;
}
count -= written;
p += written;
total += written;
}
return total;
}
int xdup(int fd)
{
int ret = dup(fd);

View File

@@ -45,44 +45,6 @@ void maybe_flush_or_die(FILE *f, const char *desc)
}
}
ssize_t read_in_full(int fd, void *buf, size_t count)
{
char *p = buf;
ssize_t total = 0;
while (count > 0) {
ssize_t loaded = xread(fd, p, count);
if (loaded <= 0)
return total ? total : loaded;
count -= loaded;
p += loaded;
total += loaded;
}
return total;
}
ssize_t write_in_full(int fd, const void *buf, size_t count)
{
const char *p = buf;
ssize_t total = 0;
while (count > 0) {
ssize_t written = xwrite(fd, p, count);
if (written < 0)
return -1;
if (!written) {
errno = ENOSPC;
return -1;
}
count -= written;
p += written;
total += written;
}
return total;
}
void fsync_or_die(int fd, const char *msg)
{
if (fsync(fd) < 0) {