1 Star 0 Fork 0

小笼包/git

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
.github
Documentation
block-sha1
builtin
ci
compat
contrib
ewah
git-gui
gitk-git
gitweb
mergetools
negotiator
perl
po
ppc
refs
sha1dc
sha256
t
templates
trace2
xdiff
.cirrus.yml
.clang-format
.editorconfig
.gitattributes
.gitignore
.gitmodules
.mailmap
.travis.yml
.tsan-suppressions
CODE_OF_CONDUCT.md
CONTRIBUTING.md
COPYING
GIT-VERSION-GEN
INSTALL
LGPL-2.1
Makefile
README.md
RelNotes
SECURITY.md
abspath.c
aclocal.m4
add-interactive.c
add-interactive.h
add-patch.c
advice.c
advice.h
alias.c
alias.h
alloc.c
alloc.h
apply.c
apply.h
archive-tar.c
archive-zip.c
archive.c
archive.h
attr.c
attr.h
banned.h
base85.c
bisect.c
bisect.h
blame.c
blame.h
blob.c
blob.h
bloom.c
bloom.h
branch.c
branch.h
builtin.h
bulk-checkin.c
bulk-checkin.h
bundle.c
bundle.h
cache-tree.c
cache-tree.h
cache.h
cbtree.c
cbtree.h
chdir-notify.c
chdir-notify.h
check-builtins.sh
check_bindir
checkout.c
checkout.h
chunk-format.c
chunk-format.h
color.c
color.h
column.c
column.h
combine-diff.c
command-list.txt
commit-graph.c
commit-graph.h
commit-reach.c
commit-reach.h
commit-slab-decl.h
commit-slab-impl.h
commit-slab.h
commit.c
commit.h
common-main.c
config.c
config.h
config.mak.dev
config.mak.in
config.mak.uname
configure.ac
connect.c
connect.h
connected.c
connected.h
convert.c
convert.h
copy.c
credential.c
credential.h
csum-file.c
csum-file.h
ctype.c
daemon.c
date.c
decorate.c
decorate.h
delta-islands.c
delta-islands.h
delta.h
detect-compiler
diff-delta.c
diff-lib.c
diff-merges.c
diff-merges.h
diff-no-index.c
diff.c
diff.h
diffcore-break.c
diffcore-delta.c
diffcore-order.c
diffcore-pickaxe.c
diffcore-rename.c
diffcore-rotate.c
diffcore.h
dir-iterator.c
dir-iterator.h
dir.c
dir.h
editor.c
entry.c
entry.h
environment.c
environment.h
exec-cmd.c
exec-cmd.h
fetch-negotiator.c
fetch-negotiator.h
fetch-pack.c
fetch-pack.h
fmt-merge-msg.c
fmt-merge-msg.h
fsck.c
fsck.h
fsmonitor--daemon.h
fsmonitor-ipc.c
fsmonitor-ipc.h
fsmonitor-settings.c
fsmonitor-settings.h
fsmonitor.c
fsmonitor.h
fuzz-commit-graph.c
fuzz-pack-headers.c
fuzz-pack-idx.c
generate-cmdlist.sh
generate-configlist.sh
gettext.c
gettext.h
git-add--interactive.perl
git-archimport.perl
git-bisect.sh
git-compat-util.h
git-cvsexportcommit.perl
git-cvsimport.perl
git-cvsserver.perl
git-difftool--helper.sh
git-filter-branch.sh
git-instaweb.sh
git-merge-octopus.sh
git-merge-one-file.sh
git-merge-resolve.sh
git-mergetool--lib.sh
git-mergetool.sh
git-p4.py
git-quiltimport.sh
git-rebase--preserve-merges.sh
git-request-pull.sh
git-send-email.perl
git-sh-i18n.sh
git-sh-setup.sh
git-submodule.sh
git-svn.perl
git-web--browse.sh
git.c
git.rc
gpg-interface.c
gpg-interface.h
graph.c
graph.h
grep.c
grep.h
hash-lookup.c
hash-lookup.h
hash.h
hashmap.c
hashmap.h
help.c
help.h
hex.c
http-backend.c
http-fetch.c
http-push.c
http-walker.c
http.c
http.h
ident.c
imap-send.c
iterator.h
json-writer.c
json-writer.h
khash.h
kwset.c
kwset.h
levenshtein.c
levenshtein.h
line-log.c
line-log.h
line-range.c
line-range.h
linear-assignment.c
linear-assignment.h
list-objects-filter-options.c
list-objects-filter-options.h
list-objects-filter.c
list-objects-filter.h
list-objects.c
list-objects.h
list.h
ll-merge.c
ll-merge.h
lockfile.c
lockfile.h
log-tree.c
log-tree.h
ls-refs.c
ls-refs.h
mailinfo.c
mailinfo.h
mailmap.c
mailmap.h
match-trees.c
mem-pool.c
mem-pool.h
merge-blobs.c
merge-blobs.h
merge-ort-wrappers.c
merge-ort-wrappers.h
merge-ort.c
merge-ort.h
merge-recursive.c
merge-recursive.h
merge.c
mergesort.c
mergesort.h
midx.c
midx.h
name-hash.c
notes-cache.c
notes-cache.h
notes-merge.c
notes-merge.h
notes-utils.c
notes-utils.h
notes.c
notes.h
object-file.c
object-name.c
object-store.h
object.c
object.h
oid-array.c
oid-array.h
oidmap.c
oidmap.h
oidset.c
oidset.h
oidtree.c
oidtree.h
pack-bitmap-write.c
pack-bitmap.c
pack-bitmap.h
pack-check.c
pack-objects.c
pack-objects.h
pack-revindex.c
pack-revindex.h
pack-write.c
pack.h
packfile.c
packfile.h
pager.c
parallel-checkout.c
parallel-checkout.h
parse-options-cb.c
parse-options.c
parse-options.h
patch-delta.c
patch-ids.c
patch-ids.h
path.c
path.h
pathspec.c
pathspec.h
pkt-line.c
pkt-line.h
preload-index.c
pretty.c
pretty.h
prio-queue.c
prio-queue.h
progress.c
progress.h
promisor-remote.c
promisor-remote.h
prompt.c
prompt.h
protocol-caps.c
protocol-caps.h
protocol.c
protocol.h
prune-packed.c
prune-packed.h
quote.c
quote.h
range-diff.c
range-diff.h
reachable.c
reachable.h
read-cache.c
rebase-interactive.c
rebase-interactive.h
rebase.c
rebase.h
ref-filter.c
ref-filter.h
reflog-walk.c
reflog-walk.h
refs.c
refs.h
refspec.c
refspec.h
remote-curl.c
remote.c
remote.h
replace-object.c
replace-object.h
repo-settings.c
repository.c
repository.h
rerere.c
rerere.h
reset.c
reset.h
resolve-undo.c
resolve-undo.h
revision.c
revision.h
run-command.c
run-command.h
send-pack.c
send-pack.h
sequencer.c
sequencer.h
serve.c
serve.h
server-info.c
setup.c
sh-i18n--envsubst.c
sha1dc_git.c
sha1dc_git.h
shallow.c
shallow.h
shell.c
shortlog.h
sideband.c
sideband.h
sigchain.c
sigchain.h
simple-ipc.h
sparse-index.c
sparse-index.h
split-index.c
split-index.h
stable-qsort.c
strbuf.c
strbuf.h
streaming.c
streaming.h
string-list.c
string-list.h
strmap.c
strmap.h
strvec.c
strvec.h
sub-process.c
sub-process.h
submodule-config.c
submodule-config.h
submodule.c
submodule.h
symlinks.c
tag.c
tag.h
tar.h
tempfile.c
tempfile.h
thread-utils.c
thread-utils.h
tmp-objdir.c
tmp-objdir.h
trace.c
trace.h
trace2.c
trace2.h
trailer.c
trailer.h
transport-helper.c
transport-internal.h
transport.c
transport.h
tree-diff.c
tree-walk.c
tree-walk.h
tree.c
tree.h
unicode-width.h
unimplemented.sh
unix-socket.c
unix-socket.h
unix-stream-server.c
unix-stream-server.h
unpack-trees.c
unpack-trees.h
upload-pack.c
upload-pack.h
url.c
url.h
urlmatch.c
urlmatch.h
usage.c
userdiff.c
userdiff.h
utf8.c
utf8.h
varint.c
varint.h
version.c
version.h
versioncmp.c
walker.c
walker.h
wildmatch.c
wildmatch.h
worktree.c
worktree.h
wrap-for-bin.sh
wrapper.c
write-or-die.c
ws.c
wt-status.c
wt-status.h
xdiff-interface.c
xdiff-interface.h
zlib.c
克隆/下载
lockfile.h 11.31 KB
一键复制 编辑 原始数据 按行查看 历史
#ifndef LOCKFILE_H
#define LOCKFILE_H
/*
* File write-locks as used by Git.
*
* The lockfile API serves two purposes:
*
* * Mutual exclusion and atomic file updates. When we want to change
* a file, we create a lockfile `<filename>.lock`, write the new
* file contents into it, and then rename the lockfile to its final
* destination `<filename>`. We create the `<filename>.lock` file
* with `O_CREAT|O_EXCL` so that we can notice and fail if somebody
* else has already locked the file, then atomically rename the
* lockfile to its final destination to commit the changes and
* unlock the file.
*
* * Automatic cruft removal. If the program exits after we lock a
* file but before the changes have been committed, we want to make
* sure that we remove the lockfile. This is done by remembering the
* lockfiles we have created in a linked list and setting up an
* `atexit(3)` handler and a signal handler that clean up the
* lockfiles. This mechanism ensures that outstanding lockfiles are
* cleaned up if the program exits (including when `die()` is
* called) or if the program is terminated by a signal.
*
* Please note that lockfiles only block other writers. Readers do not
* block, but they are guaranteed to see either the old contents of
* the file or the new contents of the file (assuming that the
* filesystem implements `rename(2)` atomically).
*
* Most of the heavy lifting is done by the tempfile module (see
* "tempfile.h").
*
* Calling sequence
* ----------------
*
* The caller:
*
* * Allocates a `struct lock_file` with whatever storage duration you
* desire. The struct does not have to be initialized before being
* used, but it is good practice to do so using by setting it to
* all-zeros (or using the LOCK_INIT macro). This puts the object in a
* consistent state that allows you to call rollback_lock_file() even
* if the lock was never taken (in which case it is a noop).
*
* * Attempts to create a lockfile by calling `hold_lock_file_for_update()`.
*
* * Writes new content for the destination file by either:
*
* * writing to the file descriptor returned by the
* `hold_lock_file_for_*()` functions (also available via
* `lock->fd`).
*
* * calling `fdopen_lock_file()` to get a `FILE` pointer for the
* open file and writing to the file using stdio.
*
* Note that the file descriptor returned by hold_lock_file_for_update()
* is marked O_CLOEXEC, so the new contents must be written by the
* current process, not a spawned one.
*
* When finished writing, the caller can:
*
* * Close the file descriptor and rename the lockfile to its final
* destination by calling `commit_lock_file()` or
* `commit_lock_file_to()`.
*
* * Close the file descriptor and remove the lockfile by calling
* `rollback_lock_file()`.
*
* * Close the file descriptor without removing or renaming the
* lockfile by calling `close_lock_file_gently()`, and later call
* `commit_lock_file()`, `commit_lock_file_to()`,
* `rollback_lock_file()`, or `reopen_lock_file()`.
*
* After the lockfile is committed or rolled back, the `lock_file`
* object can be discarded or reused.
*
* If the program exits before `commit_lock_file()`,
* `commit_lock_file_to()`, or `rollback_lock_file()` is called, the
* tempfile module will close and remove the lockfile, thereby rolling
* back any uncommitted changes.
*
* If you need to close the file descriptor you obtained from a
* `hold_lock_file_for_*()` function yourself, do so by calling
* `close_lock_file_gently()`. See "tempfile.h" for more information.
*
*
* Under the covers, a lockfile is just a tempfile with a few helper
* functions. In particular, the state diagram and the cleanup
* machinery are all implemented in the tempfile module.
*
* Permission bits
* ---------------
*
* If you call either `hold_lock_file_for_update_mode` or
* `hold_lock_file_for_update_timeout_mode`, you can specify a suggested
* mode for the underlying temporary file. Note that the file isn't
* guaranteed to have this exact mode, since it may be limited by either
* the umask, 'core.sharedRepository', or both. See `adjust_shared_perm`
* for more.
*
* Error handling
* --------------
*
* The `hold_lock_file_for_*()` functions return a file descriptor on
* success or -1 on failure (unless `LOCK_DIE_ON_ERROR` is used; see
* "flags" below). On errors, `errno` describes the reason for
* failure. Errors can be reported by passing `errno` to
* `unable_to_lock_message()` or `unable_to_lock_die()`.
*
* Similarly, `commit_lock_file`, `commit_lock_file_to`, and
* `close_lock_file` return 0 on success. On failure they set `errno`
* appropriately and return -1. The `commit` variants (but not `close`)
* do their best to delete the temporary file before returning.
*/
#include "tempfile.h"
struct lock_file {
struct tempfile *tempfile;
};
#define LOCK_INIT { NULL }
/* String appended to a filename to derive the lockfile name: */
#define LOCK_SUFFIX ".lock"
#define LOCK_SUFFIX_LEN 5
/*
* Flags
* -----
*
* The following flags can be passed to `hold_lock_file_for_update()`.
*/
/*
* If a lock is already taken for the file, `die()` with an error
* message. If this flag is not specified, trying to lock a file that
* is already locked silently returns -1 to the caller, or ...
*/
#define LOCK_DIE_ON_ERROR 1
/*
* ... this flag can be passed instead to return -1 and give the usual
* error message upon an error.
*/
#define LOCK_REPORT_ON_ERROR 4
/*
* Usually symbolic links in the destination path are resolved. This
* means that (1) the lockfile is created by adding ".lock" to the
* resolved path, and (2) upon commit, the resolved path is
* overwritten. However, if `LOCK_NO_DEREF` is set, then the lockfile
* is created by adding ".lock" to the path argument itself. This
* option is used, for example, when detaching a symbolic reference,
* which for backwards-compatibility reasons, can be a symbolic link
* containing the name of the referred-to-reference.
*/
#define LOCK_NO_DEREF 2
/*
* Attempt to create a lockfile for the file at `path` and return a
* file descriptor for writing to it, or -1 on error. If the file is
* currently locked, retry with quadratic backoff for at least
* timeout_ms milliseconds. If timeout_ms is 0, try exactly once; if
* timeout_ms is -1, retry indefinitely. The flags argument, error
* handling, and mode are described above.
*/
int hold_lock_file_for_update_timeout_mode(
struct lock_file *lk, const char *path,
int flags, long timeout_ms, int mode);
static inline int hold_lock_file_for_update_timeout(
struct lock_file *lk, const char *path,
int flags, long timeout_ms)
{
return hold_lock_file_for_update_timeout_mode(lk, path, flags,
timeout_ms, 0666);
}
/*
* Attempt to create a lockfile for the file at `path` and return a
* file descriptor for writing to it, or -1 on error. The flags
* argument and error handling are described above.
*/
static inline int hold_lock_file_for_update(
struct lock_file *lk, const char *path,
int flags)
{
return hold_lock_file_for_update_timeout(lk, path, flags, 0);
}
static inline int hold_lock_file_for_update_mode(
struct lock_file *lk, const char *path,
int flags, int mode)
{
return hold_lock_file_for_update_timeout_mode(lk, path, flags, 0, mode);
}
/*
* Return a nonzero value iff `lk` is currently locked.
*/
static inline int is_lock_file_locked(struct lock_file *lk)
{
return is_tempfile_active(lk->tempfile);
}
/*
* Append an appropriate error message to `buf` following the failure
* of `hold_lock_file_for_update()` to lock `path`. `err` should be the
* `errno` set by the failing call.
*/
void unable_to_lock_message(const char *path, int err,
struct strbuf *buf);
/*
* Emit an appropriate error message and `die()` following the failure
* of `hold_lock_file_for_update()` to lock `path`. `err` should be the
* `errno` set by the failing
* call.
*/
NORETURN void unable_to_lock_die(const char *path, int err);
/*
* Associate a stdio stream with the lockfile (which must still be
* open). Return `NULL` (*without* rolling back the lockfile) on
* error. The stream is closed automatically when
* `close_lock_file_gently()` is called or when the file is committed or
* rolled back.
*/
static inline FILE *fdopen_lock_file(struct lock_file *lk, const char *mode)
{
return fdopen_tempfile(lk->tempfile, mode);
}
/*
* Return the path of the lockfile. The return value is a pointer to a
* field within the lock_file object and should not be freed.
*/
static inline const char *get_lock_file_path(struct lock_file *lk)
{
return get_tempfile_path(lk->tempfile);
}
static inline int get_lock_file_fd(struct lock_file *lk)
{
return get_tempfile_fd(lk->tempfile);
}
static inline FILE *get_lock_file_fp(struct lock_file *lk)
{
return get_tempfile_fp(lk->tempfile);
}
/*
* Return the path of the file that is locked by the specified
* lock_file object. The caller must free the memory.
*/
char *get_locked_file_path(struct lock_file *lk);
/*
* If the lockfile is still open, close it (and the file pointer if it
* has been opened using `fdopen_lock_file()`) without renaming the
* lockfile over the file being locked. Return 0 upon success. On
* failure to `close(2)`, return a negative value (the lockfile is not
* rolled back). Usually `commit_lock_file()`, `commit_lock_file_to()`,
* or `rollback_lock_file()` should eventually be called.
*/
static inline int close_lock_file_gently(struct lock_file *lk)
{
return close_tempfile_gently(lk->tempfile);
}
/*
* Re-open a lockfile that has been closed using `close_lock_file_gently()`
* but not yet committed or rolled back. This can be used to implement
* a sequence of operations like the following:
*
* * Lock file.
*
* * Write new contents to lockfile, then `close_lock_file_gently()` to
* cause the contents to be written to disk.
*
* * Pass the name of the lockfile to another program to allow it (and
* nobody else) to inspect the contents you wrote, while still
* holding the lock yourself.
*
* * `reopen_lock_file()` to reopen the lockfile, truncating the existing
* contents. Write out the new contents.
*
* * `commit_lock_file()` to make the final version permanent.
*/
static inline int reopen_lock_file(struct lock_file *lk)
{
return reopen_tempfile(lk->tempfile);
}
/*
* Commit the change represented by `lk`: close the file descriptor
* and/or file pointer if they are still open and rename the lockfile
* to its final destination. Return 0 upon success. On failure, roll
* back the lock file and return -1, with `errno` set to the value
* from the failing call to `close(2)` or `rename(2)`. It is a bug to
* call `commit_lock_file()` for a `lock_file` object that is not
* currently locked.
*/
int commit_lock_file(struct lock_file *lk);
/*
* Like `commit_lock_file()`, but rename the lockfile to the provided
* `path`. `path` must be on the same filesystem as the lock file.
*/
static inline int commit_lock_file_to(struct lock_file *lk, const char *path)
{
return rename_tempfile(&lk->tempfile, path);
}
/*
* Roll back `lk`: close the file descriptor and/or file pointer and
* remove the lockfile. It is a NOOP to call `rollback_lock_file()`
* for a `lock_file` object that has already been committed or rolled
* back.
*/
static inline void rollback_lock_file(struct lock_file *lk)
{
delete_tempfile(&lk->tempfile);
}
#endif /* LOCKFILE_H */
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/xiaobaola/git.git
git@gitee.com:xiaobaola/git.git
xiaobaola
git
git
main

搜索帮助