| lockfile API | |
| ============ | |
| The lockfile API serves two purposes: | |
| * Mutual exclusion. When we write out a new index file, first | |
| we create a new file `$GIT_DIR/index.lock`, write the new | |
| contents into it, and rename it to the final destination | |
| `$GIT_DIR/index`. We try to create the `$GIT_DIR/index.lock` | |
| file with O_EXCL so that we can notice and fail when somebody | |
| else is already trying to update the index file. | |
| * Automatic cruft removal. After we create the "lock" file, we | |
| may decide to `die()`, and we would want to make sure that we | |
| remove the file that has not been committed to its final | |
| destination. This is done by remembering the lockfiles we | |
| created in a linked list and cleaning them up from an | |
| `atexit(3)` handler. Outstanding lockfiles are also removed | |
| when the program dies on a signal. | |
| The functions | |
| ------------- | |
| hold_lock_file_for_update:: | |
| Take a pointer to `struct lock_file`, the filename of | |
| the final destination (e.g. `$GIT_DIR/index`) and a flag | |
| `die_on_error`. Attempt to create a lockfile for the | |
| destination and return the file descriptor for writing | |
| to the file. If `die_on_error` flag is true, it dies if | |
| a lock is already taken for the file; otherwise it | |
| returns a negative integer to the caller on failure. | |
| commit_lock_file:: | |
| Take a pointer to the `struct lock_file` initialized | |
| with an earlier call to `hold_lock_file_for_update()`, | |
| close the file descriptor and rename the lockfile to its | |
| final destination. Returns 0 upon success, a negative | |
| value on failure to close(2) or rename(2). | |
| rollback_lock_file:: | |
| Take a pointer to the `struct lock_file` initialized | |
| with an earlier call to `hold_lock_file_for_update()`, | |
| close the file descriptor and remove the lockfile. | |
| close_lock_file:: | |
| Take a pointer to the `struct lock_file` initialized | |
| with an earlier call to `hold_lock_file_for_update()`, | |
| and close the file descriptor. Returns 0 upon success, | |
| a negative value on failure to close(2). | |
| Because the structure is used in an `atexit(3)` handler, its | |
| storage has to stay throughout the life of the program. It | |
| cannot be an auto variable allocated on the stack. | |
| Call `commit_lock_file()` or `rollback_lock_file()` when you are | |
| done writing to the file descriptor. If you do not call either | |
| and simply `exit(3)` from the program, an `atexit(3)` handler | |
| will close and remove the lockfile. | |
| If you need to close the file descriptor you obtained from | |
| `hold_lock_file_for_update` function yourself, do so by calling | |
| `close_lock_file()`. You should never call `close(2)` yourself! | |
| Otherwise the `struct | |
| lock_file` structure still remembers that the file descriptor | |
| needs to be closed, and a later call to `commit_lock_file()` or | |
| `rollback_lock_file()` will result in duplicate calls to | |
| `close(2)`. Worse yet, if you `close(2)`, open another file | |
| descriptor for completely different purpose, and then call | |
| `commit_lock_file()` or `rollback_lock_file()`, they may close | |
| that unrelated file descriptor. |