Skip to content

Commit

Permalink
Fix error return value for file.readLines (fixes #455)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghewgill committed May 31, 2024
1 parent 2fa3082 commit 78bf4f0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 47 deletions.
42 changes: 26 additions & 16 deletions lib/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,20 @@ namespace rtl {

namespace ne_file {

Cell error_result(int error, const utf8string &path)
Cell error_result(int choice, int type, int error, const utf8string &message, const utf8string &path)
{
return Cell(std::vector<Cell> {
Cell(number_from_uint32(choice)),
Cell(std::vector<Cell> {
/* type */ Cell(number_from_sint32(type)),
/* os_code */ Cell(number_from_sint32(error)),
/* message */ Cell(utf8string(message)),
/* path */ Cell(utf8string(path))
})
});
}

Cell errno_error_result(int choice, int error, const utf8string &path)
{
int type = ENUM_Error_other;
switch (error) {
Expand All @@ -27,23 +40,20 @@ Cell error_result(int error, const utf8string &path)
type = ENUM_Error_notFound;
break;
}
return Cell(std::vector<Cell> {
Cell(number_from_uint32(CHOICE_FileResult_error)),
Cell(std::vector<Cell> {
/* type */ Cell(number_from_sint32(type)),
/* os_code */ Cell(number_from_sint32(error)),
/* message */ Cell(utf8string(strerror(error))),
/* path */ Cell(utf8string(path))
})
});
return error_result(choice, type, error, utf8string(strerror(error)), path);
}

Cell file_error_result(int error, const utf8string &path)
{
return errno_error_result(CHOICE_FileResult_error, error, path);
}

Cell readBytes(const utf8string &filename)
{
std::vector<unsigned char> r;
std::ifstream f(filename.str(), std::ios::binary);
if (not f.is_open()) {
return error_result(errno, filename);
return file_error_result(errno, filename);
}
for (;;) {
char buf[16384];
Expand All @@ -62,7 +72,7 @@ Cell readLines(const utf8string &filename)
std::vector<Cell> r;
std::ifstream f(filename.str());
if (not f.is_open()) {
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_LinesResult_error)), Cell(filename) });
return file_error_result(errno, filename);
}
std::string s;
while (std::getline(f, s)) {
Expand All @@ -75,10 +85,10 @@ Cell writeBytes(const utf8string &filename, const std::vector<unsigned char> &da
{
std::ofstream f(filename.str(), std::ios::binary);
if (not f.is_open()) {
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_error)), Cell(filename) });
return file_error_result(errno, filename);
}
if (not f.write(reinterpret_cast<const char *>(data.data()), data.size())) {
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_error)), Cell(filename) });
return file_error_result(errno, filename);
}
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_ok)) });
}
Expand All @@ -87,13 +97,13 @@ Cell writeLines(const utf8string &filename, const std::vector<utf8string> &lines
{
std::ofstream f(filename.str(), std::ios::out | std::ios::trunc); // Truncate the file every time we open it to write lines to it.
if (not f.is_open()) {
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_error)), Cell(filename) });
return file_error_result(errno, filename);
}
for (auto s: lines) {
f << s.str() << "\n"; // Write line, and line-ending for each element in the array.
if (f.fail()) {
// If the write fails for any reason, consider that a FileException.Write exception.
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_error)), Cell(filename) });
return file_error_result(errno, filename);
}
}
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_ok)) });
Expand Down
46 changes: 23 additions & 23 deletions lib/file_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace rtl {

namespace ne_file {

extern Cell error_result(int error, const utf8string &path);
extern Cell file_error_result(int error, const utf8string &path);

utf8string _CONSTANT_Separator()
{
Expand All @@ -32,30 +32,30 @@ Cell copy(const utf8string &filename, const utf8string &destination)
int r = copyfile(filename.c_str(), destination.c_str(), NULL, COPYFILE_ALL|COPYFILE_EXCL);
if (r != 0) {
if (errno == EEXIST) {
return error_result(errno, destination);
return file_error_result(errno, destination);
}
return error_result(errno, filename);
return file_error_result(errno, filename);
}
#else
int sourcefd = open(filename.c_str(), O_RDONLY);
if (sourcefd < 0) {
return error_result(errno, filename);
return file_error_result(errno, filename);
}
struct stat statbuf;
int r = fstat(sourcefd, &statbuf);
if (r != 0) {
int error = errno;
close(sourcefd);
return error_result(error, filename);
return file_error_result(error, filename);
}
int destfd = open(destination.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, 0);
if (destfd < 0) {
int error = errno;
close(sourcefd);
if (error == EEXIST) {
return error_result(error, destination);
return file_error_result(error, destination);
}
return error_result(error, destination);
return file_error_result(error, destination);
}
char buf[BUFSIZ];
for (;;) {
Expand All @@ -65,7 +65,7 @@ Cell copy(const utf8string &filename, const utf8string &destination)
close(sourcefd);
close(destfd);
unlink(destination.c_str());
return error_result(error, filename);
return file_error_result(error, filename);
} else if (n == 0) {
break;
}
Expand All @@ -75,7 +75,7 @@ Cell copy(const utf8string &filename, const utf8string &destination)
close(sourcefd);
close(destfd);
unlink(destination.c_str());
return error_result(error, destination);
return file_error_result(error, destination);
}
}
close(sourcefd);
Expand All @@ -84,14 +84,14 @@ Cell copy(const utf8string &filename, const utf8string &destination)
close(sourcefd);
close(destfd);
unlink(destination.c_str());
return error_result(error, destination);
return file_error_result(error, destination);
}
if (fchown(destfd, statbuf.st_uid, statbuf.st_gid) != 0) {
int error = errno;
close(sourcefd);
close(destfd);
unlink(destination.c_str());
return error_result(error, destination);
return file_error_result(error, destination);
}
close(destfd);
struct utimbuf utimebuf;
Expand All @@ -107,25 +107,25 @@ Cell copyOverwriteIfExists(const utf8string &filename, const utf8string &destina
#ifdef __APPLE__
int r = copyfile(filename.c_str(), destination.c_str(), NULL, COPYFILE_ALL);
if (r != 0) {
return error_result(errno, filename);
return file_error_result(errno, filename);
}
#else
int sourcefd = open(filename.c_str(), O_RDONLY);
if (sourcefd < 0) {
return error_result(errno, filename);
return file_error_result(errno, filename);
}
struct stat statbuf;
int r = fstat(sourcefd, &statbuf);
if (r != 0) {
int error = errno;
close(sourcefd);
return error_result(error, filename);
return file_error_result(error, filename);
}
int destfd = open(destination.c_str(), O_CREAT|O_WRONLY|O_TRUNC, 0);
if (destfd < 0) {
int error = errno;
close(sourcefd);
return error_result(error, destination);
return file_error_result(error, destination);
}
char buf[BUFSIZ];
for (;;) {
Expand All @@ -135,7 +135,7 @@ Cell copyOverwriteIfExists(const utf8string &filename, const utf8string &destina
close(sourcefd);
close(destfd);
unlink(destination.c_str());
return error_result(error, filename);
return file_error_result(error, filename);
} else if (n == 0) {
break;
}
Expand All @@ -145,7 +145,7 @@ Cell copyOverwriteIfExists(const utf8string &filename, const utf8string &destina
close(sourcefd);
close(destfd);
unlink(destination.c_str());
return error_result(error, destination);
return file_error_result(error, destination);
}
}
close(sourcefd);
Expand All @@ -154,14 +154,14 @@ Cell copyOverwriteIfExists(const utf8string &filename, const utf8string &destina
close(sourcefd);
close(destfd);
unlink(destination.c_str());
return error_result(error, destination);
return file_error_result(error, destination);
}
if (fchown(destfd, statbuf.st_uid, statbuf.st_gid) != 0) {
int error = errno;
close(sourcefd);
close(destfd);
unlink(destination.c_str());
return error_result(error, destination);
return file_error_result(error, destination);
}
close(destfd);
struct utimbuf utimebuf;
Expand All @@ -177,7 +177,7 @@ Cell delete_(const utf8string &filename)
int r = unlink(filename.c_str());
if (r != 0) {
if (errno != ENOENT) {
return error_result(errno, filename);
return file_error_result(errno, filename);
}
}
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_ok))});
Expand Down Expand Up @@ -209,7 +209,7 @@ Cell getInfo(const utf8string &name)
{
struct stat st;
if (stat(name.c_str(), &st) != 0) {
return error_result(errno, name);
return file_error_result(errno, name);
}
std::vector<Cell> r;
r.push_back(Cell(name.str().rfind('/') != std::string::npos ? utf8string(name.str().substr(name.str().rfind('/')+1)) : name));
Expand Down Expand Up @@ -247,7 +247,7 @@ Cell removeEmptyDirectory(const utf8string &path)
{
int r = rmdir(path.c_str());
if (r != 0) {
return error_result(errno, path);
return file_error_result(errno, path);
}
return Cell(std::vector<Cell> {Cell(number_from_uint32(CHOICE_FileResult_ok))});
}
Expand All @@ -256,7 +256,7 @@ Cell rename(const utf8string &oldname, const utf8string &newname)
{
int r = ::rename(oldname.c_str(), newname.c_str());
if (r != 0) {
return error_result(errno, oldname);
return file_error_result(errno, oldname);
}
return Cell(std::vector<Cell> {Cell(number_from_uint32(CHOICE_FileResult_ok))});
}
Expand Down
16 changes: 8 additions & 8 deletions lib/file_win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace rtl {

namespace ne_file {

extern Cell error_result(int error, const utf8string &path);
extern Cell file_error_result(int error, const utf8string &path);

utf8string _CONSTANT_Separator()
{
Expand All @@ -29,7 +29,7 @@ Cell copy(const utf8string &filename, const utf8string &destination)
{
BOOL r = CopyFile(filename.c_str(), destination.c_str(), TRUE);
if (!r) {
return error_result(GetLastError(), destination);
return file_error_result(GetLastError(), destination);
}
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_ok))});
}
Expand All @@ -38,7 +38,7 @@ Cell copyOverwriteIfExists(const utf8string &filename, const utf8string &destina
{
BOOL r = CopyFile(filename.c_str(), destination.c_str(), FALSE);
if (!r) {
return error_result(GetLastError(), destination);
return file_error_result(GetLastError(), destination);
}
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_ok))});
}
Expand All @@ -48,7 +48,7 @@ Cell delete_(const utf8string &filename)
BOOL r = DeleteFile(filename.c_str());
if (!r) {
if (GetLastError() != ERROR_FILE_NOT_FOUND) {
return error_result(GetLastError(), filename);
return file_error_result(GetLastError(), filename);
}
}
return Cell(std::vector<Cell> { Cell(number_from_uint32(CHOICE_FileResult_ok))});
Expand Down Expand Up @@ -78,7 +78,7 @@ Cell getInfo(const utf8string &name)
WIN32_FIND_DATA fd;
HANDLE ff = FindFirstFile(name.c_str(), &fd);
if (ff == INVALID_HANDLE_VALUE) {
return error_result(GetLastError(), name);
return file_error_result(GetLastError(), name);
}
FindClose(ff);
std::vector<Cell> r;
Expand Down Expand Up @@ -110,7 +110,7 @@ Cell mkdir(const utf8string &path)
// TODO: Convert UTF-8 path to UCS-16 and call CreateDirectoryW.
BOOL r = CreateDirectoryA(path.c_str(), NULL);
if (!r) {
return error_result(GetLastError(), path);
return file_error_result(GetLastError(), path);
}
return Cell(std::vector<Cell> {Cell(number_from_uint32(CHOICE_FileResult_ok))});
}
Expand All @@ -119,7 +119,7 @@ Cell removeEmptyDirectory(const utf8string &path)
{
BOOL r = RemoveDirectory(path.c_str());
if (!r) {
return error_result(GetLastError(), path);
return file_error_result(GetLastError(), path);
}
return Cell(std::vector<Cell> {Cell(number_from_uint32(CHOICE_FileResult_ok))});
}
Expand All @@ -128,7 +128,7 @@ Cell rename(const utf8string &oldname, const utf8string &newname)
{
BOOL r = MoveFile(oldname.c_str(), newname.c_str());
if (!r) {
return error_result(GetLastError(), oldname);
return file_error_result(GetLastError(), oldname);
}
return Cell(std::vector<Cell> {Cell(number_from_uint32(CHOICE_FileResult_ok))});
}
Expand Down

0 comments on commit 78bf4f0

Please sign in to comment.