Prevent overwriting existing file in :write <explicit filename>
Add a -force (equivalent to w!) switch that enables overwriting.
This commit is contained in:
parent
4d99434ddd
commit
40e3614cf4
|
@ -58,13 +58,17 @@ of the file onto the filesystem
|
||||||
Otherwise, does nothing.
|
Otherwise, does nothing.
|
||||||
|
|
||||||
|
|
||||||
*write[!]* [-sync] [-method <writemethod>] [<filename>]::
|
*write[!]* [-force] [-sync] [-method <writemethod>] [<filename>]::
|
||||||
*alias* w +
|
*alias* w +
|
||||||
write buffer to <filename> or use its name if filename is not
|
write buffer to <filename> or use its name if filename is not
|
||||||
given. If the file is write-protected, its permissions are temporarily
|
given. If the file is write-protected, its permissions are temporarily
|
||||||
changed to allow saving the buffer and restored afterwards when
|
changed to allow saving the buffer and restored afterwards when
|
||||||
the write! command is used.
|
the write! command is used.
|
||||||
|
|
||||||
|
*-force*:::
|
||||||
|
Equivalent to `!`, allow overwiting existing files if `<filename>`
|
||||||
|
is given and set permissions temporarily if necessary.
|
||||||
|
|
||||||
*-sync*:::
|
*-sync*:::
|
||||||
Synchronise the filesystem after the write
|
Synchronise the filesystem after the write
|
||||||
|
|
||||||
|
|
|
@ -460,6 +460,7 @@ const ParameterDesc write_params{
|
||||||
{
|
{
|
||||||
{ "sync", { false, "force the synchronization of the file onto the filesystem" } },
|
{ "sync", { false, "force the synchronization of the file onto the filesystem" } },
|
||||||
{ "method", { true, "explicit writemethod (replace|overwrite)" } },
|
{ "method", { true, "explicit writemethod (replace|overwrite)" } },
|
||||||
|
{ "force", { false, "Allow overwriting existing file with explicit filename" } },
|
||||||
},
|
},
|
||||||
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
|
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
|
||||||
};
|
};
|
||||||
|
@ -488,7 +489,12 @@ void do_write_buffer(Context& context, Optional<String> filename, WriteFlags fla
|
||||||
(not filename or real_path(*filename) == buffer.name()))
|
(not filename or real_path(*filename) == buffer.name()))
|
||||||
throw runtime_error("cannot overwrite the buffer when in readonly mode");
|
throw runtime_error("cannot overwrite the buffer when in readonly mode");
|
||||||
|
|
||||||
auto effective_filename = not filename ? buffer.name() : parse_filename(*filename);
|
auto effective_filename = filename ? parse_filename(*filename) : buffer.name();
|
||||||
|
if (filename and not (flags & WriteFlags::Force) and
|
||||||
|
real_path(effective_filename) != buffer.name() and
|
||||||
|
regular_file_exists(effective_filename))
|
||||||
|
throw runtime_error("cannot overwrite existing file without -force");
|
||||||
|
|
||||||
auto method = write_method.value_or_compute([&] { return context.options()["writemethod"].get<WriteMethod>(); });
|
auto method = write_method.value_or_compute([&] { return context.options()["writemethod"].get<WriteMethod>(); });
|
||||||
|
|
||||||
context.hooks().run_hook(Hook::BufWritePre, effective_filename, context);
|
context.hooks().run_hook(Hook::BufWritePre, effective_filename, context);
|
||||||
|
@ -502,7 +508,7 @@ void write_buffer(const ParametersParser& parser, Context& context, const ShellC
|
||||||
return do_write_buffer(context,
|
return do_write_buffer(context,
|
||||||
parser.positional_count() > 0 ? parser[0] : Optional<String>{},
|
parser.positional_count() > 0 ? parser[0] : Optional<String>{},
|
||||||
(parser.get_switch("sync") ? WriteFlags::Sync : WriteFlags::None) |
|
(parser.get_switch("sync") ? WriteFlags::Sync : WriteFlags::None) |
|
||||||
(force ? WriteFlags::Force : WriteFlags::None),
|
(parser.get_switch("force") or force ? WriteFlags::Force : WriteFlags::None),
|
||||||
parser.get_switch("method").map(parse_write_method));
|
parser.get_switch("method").map(parse_write_method));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -247,6 +247,13 @@ bool file_exists(StringView filename)
|
||||||
return stat(filename.zstr(), &st) == 0;
|
return stat(filename.zstr(), &st) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool regular_file_exists(StringView filename)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
return stat(filename.zstr(), &st) == 0 and
|
||||||
|
(st.st_mode & S_IFMT) == S_IFREG;
|
||||||
|
}
|
||||||
|
|
||||||
void write(int fd, StringView data)
|
void write(int fd, StringView data)
|
||||||
{
|
{
|
||||||
const char* ptr = data.data();
|
const char* ptr = data.data();
|
||||||
|
|
|
@ -81,6 +81,7 @@ void write_buffer_to_backup_file(Buffer& buffer);
|
||||||
|
|
||||||
String find_file(StringView filename, StringView buf_dir, ConstArrayView<String> paths);
|
String find_file(StringView filename, StringView buf_dir, ConstArrayView<String> paths);
|
||||||
bool file_exists(StringView filename);
|
bool file_exists(StringView filename);
|
||||||
|
bool regular_file_exists(StringView filename);
|
||||||
|
|
||||||
Vector<String> list_files(StringView directory);
|
Vector<String> list_files(StringView directory);
|
||||||
|
|
||||||
|
|
6
test/run
6
test/run
|
@ -16,7 +16,7 @@ main() {
|
||||||
try %{ source rc }
|
try %{ source rc }
|
||||||
hook global RuntimeError .+ %{
|
hook global RuntimeError .+ %{
|
||||||
echo -debug -- error: %val{hook_param}
|
echo -debug -- error: %val{hook_param}
|
||||||
eval -buffer *debug* write debug
|
eval -buffer *debug* write -force debug
|
||||||
quit!
|
quit!
|
||||||
}
|
}
|
||||||
try %{ exec -with-maps -with-hooks "%sh{cat cmd}" }
|
try %{ exec -with-maps -with-hooks "%sh{cat cmd}" }
|
||||||
|
@ -151,14 +151,14 @@ show_diff() {
|
||||||
|
|
||||||
finished_commands() {
|
finished_commands() {
|
||||||
printf %s 'eval -client client0 %{
|
printf %s 'eval -client client0 %{
|
||||||
eval -buffer *debug* write debug
|
eval -buffer *debug* write -force debug
|
||||||
nop %sh{
|
nop %sh{
|
||||||
'
|
'
|
||||||
for env_var in $env_vars; do
|
for env_var in $env_vars; do
|
||||||
printf 'printf %%s\\\\n "$%s" >%s\n' "$env_var" "$env_var"
|
printf 'printf %%s\\\\n "$%s" >%s\n' "$env_var" "$env_var"
|
||||||
done
|
done
|
||||||
printf %s ' }
|
printf %s ' }
|
||||||
write out
|
write -force out
|
||||||
quit!
|
quit!
|
||||||
}
|
}
|
||||||
'
|
'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user