-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9024 from obsidiansystems/git-objects-prep
Shuffle `ParseSink` code in preparation for git hashing support
- Loading branch information
Showing
5 changed files
with
127 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#include <fcntl.h> | ||
|
||
#include "config.hh" | ||
#include "fs-sink.hh" | ||
|
||
namespace nix { | ||
|
||
struct RestoreSinkSettings : Config | ||
{ | ||
Setting<bool> preallocateContents{this, false, "preallocate-contents", | ||
"Whether to preallocate files when writing objects with known size."}; | ||
}; | ||
|
||
static RestoreSinkSettings restoreSinkSettings; | ||
|
||
static GlobalConfig::Register r1(&restoreSinkSettings); | ||
|
||
|
||
void RestoreSink::createDirectory(const Path & path) | ||
{ | ||
Path p = dstPath + path; | ||
if (mkdir(p.c_str(), 0777) == -1) | ||
throw SysError("creating directory '%1%'", p); | ||
}; | ||
|
||
void RestoreSink::createRegularFile(const Path & path) | ||
{ | ||
Path p = dstPath + path; | ||
fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666); | ||
if (!fd) throw SysError("creating file '%1%'", p); | ||
} | ||
|
||
void RestoreSink::closeRegularFile() | ||
{ | ||
/* Call close explicitly to make sure the error is checked */ | ||
fd.close(); | ||
} | ||
|
||
void RestoreSink::isExecutable() | ||
{ | ||
struct stat st; | ||
if (fstat(fd.get(), &st) == -1) | ||
throw SysError("fstat"); | ||
if (fchmod(fd.get(), st.st_mode | (S_IXUSR | S_IXGRP | S_IXOTH)) == -1) | ||
throw SysError("fchmod"); | ||
} | ||
|
||
void RestoreSink::preallocateContents(uint64_t len) | ||
{ | ||
if (!restoreSinkSettings.preallocateContents) | ||
return; | ||
|
||
#if HAVE_POSIX_FALLOCATE | ||
if (len) { | ||
errno = posix_fallocate(fd.get(), 0, len); | ||
/* Note that EINVAL may indicate that the underlying | ||
filesystem doesn't support preallocation (e.g. on | ||
OpenSolaris). Since preallocation is just an | ||
optimisation, ignore it. */ | ||
if (errno && errno != EINVAL && errno != EOPNOTSUPP && errno != ENOSYS) | ||
throw SysError("preallocating file of %1% bytes", len); | ||
} | ||
#endif | ||
} | ||
|
||
void RestoreSink::receiveContents(std::string_view data) | ||
{ | ||
writeFull(fd.get(), data); | ||
} | ||
|
||
void RestoreSink::createSymlink(const Path & path, const std::string & target) | ||
{ | ||
Path p = dstPath + path; | ||
nix::createSymlink(target, p); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#pragma once | ||
///@file | ||
|
||
#include "types.hh" | ||
#include "serialise.hh" | ||
|
||
namespace nix { | ||
|
||
/** | ||
* \todo Fix this API, it sucks. | ||
*/ | ||
struct ParseSink | ||
{ | ||
virtual void createDirectory(const Path & path) { }; | ||
|
||
virtual void createRegularFile(const Path & path) { }; | ||
virtual void closeRegularFile() { }; | ||
virtual void isExecutable() { }; | ||
virtual void preallocateContents(uint64_t size) { }; | ||
virtual void receiveContents(std::string_view data) { }; | ||
|
||
virtual void createSymlink(const Path & path, const std::string & target) { }; | ||
}; | ||
|
||
struct RestoreSink : ParseSink | ||
{ | ||
Path dstPath; | ||
AutoCloseFD fd; | ||
|
||
|
||
void createDirectory(const Path & path) override; | ||
|
||
void createRegularFile(const Path & path) override; | ||
void closeRegularFile() override; | ||
void isExecutable() override; | ||
void preallocateContents(uint64_t size) override; | ||
void receiveContents(std::string_view data) override; | ||
|
||
void createSymlink(const Path & path, const std::string & target) override; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters