Switch file_io_t to store a wcstring

We no longer use file_io_t after fork(). We don't need to use a malloc'd
string any more. Use a wcstring.
This commit is contained in:
ridiculousfish 2019-06-09 17:43:25 -07:00
parent 0f9f00b54b
commit 6ce85aebc6
6 changed files with 27 additions and 19 deletions

View file

@ -52,7 +52,7 @@
#define WRITE_ERROR _(L"An error occurred while writing output")
/// File redirection error message.
#define FILE_ERROR _(L"An error occurred while redirecting file '%s'")
#define FILE_ERROR _(L"An error occurred while redirecting file '%ls'")
/// Base open mode to pass to calls to open.
#define OPEN_MASK 0666
@ -81,8 +81,8 @@ static bool redirection_is_to_real_file(const shared_ptr<io_data_t> &io) {
bool result = false;
if (io && io->io_mode == io_mode_t::file) {
// It's a file redirection. Compare the path to /dev/null.
const char *path = static_cast<const io_file_t *>(io.get())->filename_cstr;
if (std::strcmp(path, "/dev/null") != 0) {
const wcstring &path = static_cast<const io_file_t *>(io.get())->filename;
if (path != L"/dev/null") {
// It's not /dev/null.
result = true;
}
@ -223,9 +223,9 @@ static bool resolve_file_redirections_to_fds(const io_chain_t &in_chain, io_chai
case io_mode_t::file: {
// We have a path-based redireciton. Resolve it to a file.
io_file_t *in_file = static_cast<io_file_t *>(in.get());
int fd = open(in_file->filename_cstr, in_file->flags, OPEN_MASK);
int fd = wopen(in_file->filename, in_file->flags, OPEN_MASK);
if (fd < 0) {
debug(1, FILE_ERROR, in_file->filename_cstr);
debug(1, FILE_ERROR, in_file->filename.c_str());
wperror(L"open");
success = false;
break;
@ -510,9 +510,9 @@ static bool exec_internal_builtin_proc(parser_t &parser, const std::shared_ptr<j
case io_mode_t::file: {
const io_file_t *in_file = static_cast<const io_file_t *>(in.get());
locally_opened_stdin =
autoclose_fd_t{open(in_file->filename_cstr, in_file->flags, OPEN_MASK)};
autoclose_fd_t{wopen(in_file->filename, in_file->flags, OPEN_MASK)};
if (!locally_opened_stdin.valid()) {
debug(1, FILE_ERROR, in_file->filename_cstr);
debug(1, FILE_ERROR, in_file->filename.c_str());
wperror(L"open");
}
local_builtin_stdin = locally_opened_stdin.fd();

View file

@ -22,7 +22,7 @@ void io_close_t::print() const { std::fwprintf(stderr, L"close %d\n", fd); }
void io_fd_t::print() const { std::fwprintf(stderr, L"FD map %d -> %d\n", old_fd, fd); }
void io_file_t::print() const { std::fwprintf(stderr, L"file (%s)\n", filename_cstr); }
void io_file_t::print() const { std::fwprintf(stderr, L"file (%ls)\n", filename.c_str()); }
void io_pipe_t::print() const {
std::fwprintf(stderr, L"pipe {%d} (input: %s)\n", pipe_fd(), is_input_ ? "yes" : "no");

View file

@ -191,17 +191,17 @@ class io_fd_t : public io_data_t {
class io_file_t : public io_data_t {
public:
/// Filename, malloc'd. This needs to be used after fork, so don't use wcstring here.
const char *const filename_cstr;
/// The filename.
wcstring filename;
/// file creation flags to send to open.
const int flags;
void print() const override;
io_file_t(int f, const wcstring &fname, int fl = 0)
: io_data_t(io_mode_t::file, f), filename_cstr(wcs2str(fname)), flags(fl) {}
io_file_t(int f, wcstring fname, int fl = 0)
: io_data_t(io_mode_t::file, f), filename(std::move(fname)), flags(fl) {}
~io_file_t() override { free((void *)filename_cstr); }
~io_file_t() override = default;
};
/// Represents (one end) of a pipe.

View file

@ -8,9 +8,9 @@
/// File descriptor redirection error message.
#define FD_ERROR "An error occurred while redirecting file descriptor %s"
#define NOCLOB_ERROR _(L"The file '%s' already exists")
#define NOCLOB_ERROR _(L"The file '%ls' already exists")
#define FILE_ERROR _(L"An error occurred while redirecting file '%s'")
#define FILE_ERROR _(L"An error occurred while redirecting file '%ls'")
/// Base open mode to pass to calls to open.
#define OPEN_MASK 0666
@ -26,12 +26,12 @@ maybe_t<dup2_list_t> dup2_list_t::resolve_chain(const io_chain_t &io_chain) {
// Here we definitely do not want to set CLO_EXEC because our child needs access.
// Open the file.
const io_file_t *io_file = static_cast<const io_file_t *>(io_ref.get());
int file_fd = open(io_file->filename_cstr, io_file->flags, OPEN_MASK);
int file_fd = wopen(io_file->filename, io_file->flags, OPEN_MASK);
if (file_fd < 0) {
if ((io_file->flags & O_EXCL) && (errno == EEXIST)) {
debug(1, NOCLOB_ERROR, io_file->filename_cstr);
debug(1, NOCLOB_ERROR, io_file->filename.c_str());
} else {
debug(1, FILE_ERROR, io_file->filename_cstr);
debug(1, FILE_ERROR, io_file->filename.c_str());
if (should_debug(1)) wperror(L"open");
}
return none();
@ -43,7 +43,7 @@ maybe_t<dup2_list_t> dup2_list_t::resolve_chain(const io_chain_t &io_chain) {
if (file_fd != io_file->fd) {
file_fd = move_fd_to_unused(file_fd, io_chain, false /* cloexec */);
if (file_fd < 0) {
debug(1, FILE_ERROR, io_file->filename_cstr);
debug(1, FILE_ERROR, io_file->filename.c_str());
if (should_debug(1)) wperror(L"dup");
return none();
}

View file

@ -210,6 +210,11 @@ int open_cloexec(const std::string &cstring, int flags, mode_t mode, bool cloexe
return fd;
}
int wopen(const wcstring &pathname, int flags, mode_t mode) {
cstring tmp = wcs2string(pathname);
return open(tmp.c_str(), flags, mode);
}
int wopen_cloexec(const wcstring &pathname, int flags, mode_t mode) {
cstring tmp = wcs2string(pathname);
return open_cloexec(tmp, flags, mode, true);

View file

@ -24,6 +24,9 @@ FILE *wfopen(const wcstring &path, const char *mode);
/// Sets CLO_EXEC on a given fd.
bool set_cloexec(int fd);
/// Wide character version of open().
int wopen(const wcstring &pathname, int flags, mode_t mode = 0);
/// Wide character version of open() that also sets the close-on-exec flag (atomically when
/// possible).
int wopen_cloexec(const wcstring &pathname, int flags, mode_t mode = 0);