Skip to content

Commit

Permalink
refactor rename and use nftw function
Browse files Browse the repository at this point in the history
  • Loading branch information
imaqtkatt committed Aug 30, 2024
1 parent 8ddc3aa commit 38408af
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 218 deletions.
82 changes: 19 additions & 63 deletions src/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ftw.h>
#include "hvm.c"

// Readback: λ-Encoded Ctr
Expand Down Expand Up @@ -724,7 +724,7 @@ Port io_dl_close(Net* net, Book* book, Port argm) {
// This function attempts to remove both files and empty directories without
// first checking the type of the path.
// Returns: Result<*, IOError<i24>>
Port io_delete_file(Net* net, Book* book, Port argm) {
Port io_remove(Net* net, Book* book, Port argm) {
Str path = readback_str(net, book, argm);

int result = remove(path.buf);
Expand All @@ -737,76 +737,32 @@ Port io_delete_file(Net* net, Book* book, Port argm) {
}
}

int delete_directory_recursive(const char* path) {
DIR *d = opendir(path);
size_t path_len = strlen(path);
int r = -1;

if (d) {
struct dirent *p;
r = 0;

while (!r && (p = readdir(d))) {
int r2 = -1;
char *buf;
size_t len;

if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) {
continue;
}

len = path_len + strlen(p->d_name) + 2;
buf = malloc(len);

if (buf) {
struct stat statbuf;
snprintf(buf, len, "%s/%s", path, p->d_name);

if (!stat(buf, &statbuf)) {
if (S_ISDIR(statbuf.st_mode)) {
r2 = delete_directory_recursive(buf);
} else {
r2 = remove(buf);
}
}

free(buf);
}

r = r2;
}
int remove_all_aux(const char* path, const struct stat* stat, int flags, struct FTW* ftw) {
return remove(path);
}

closedir(d);
int remove_all(const char* path) {
struct stat st;
if (stat(path, &st) != 0) {
return remove(path);
}

if (!r) {
r = rmdir(path);
if (S_ISDIR(st.st_mode)) {
return nftw(path, remove_all_aux, 32, FTW_DEPTH | FTW_PHYS);
} else {
return remove(path);
}

return r;
}

// Deletes a directory at the specified path. If recursive is True,
// Removes any file or directory recursively at the specified path.
// it will delete the directory and all its contents.
// Returns Ok(None) if successful, or Err(reason) if an error occurs.
// Note: For non-recursive deletion of an empty directory,
// this function behaves the same as delete_file(path).
// Returns: Result<*, IOError<i24>>
Port io_delete_directory(Net* net, Book* book, Port argm) {
Tup tup = readback_tup(net, book, argm, 2);
if (2 != tup.elem_len) {
return inject_io_err_type(net);
}

Str path = readback_str(net, book, tup.elem_buf[0]);
u32 rec = get_u24(get_val(tup.elem_buf[1]));
Port io_remove_all(Net* net, Book* book, Port argm) {
Str path = readback_str(net, book, argm);

int res;
if (rec) {
res = delete_directory_recursive(path.buf);
} else {
res = rmdir(path.buf);
}
int res = remove_all(path.buf);
free(path.buf);

if (0 == res) {
Expand Down Expand Up @@ -848,8 +804,8 @@ void book_init(Book* book) {
book->ffns_buf[book->ffns_len++] = (FFn){"DL_OPEN", io_dl_open};
book->ffns_buf[book->ffns_len++] = (FFn){"DL_CALL", io_dl_call};
book->ffns_buf[book->ffns_len++] = (FFn){"DL_CLOSE", io_dl_open};
book->ffns_buf[book->ffns_len++] = (FFn){"DELETE_FILE", io_delete_file};
book->ffns_buf[book->ffns_len++] = (FFn){"DELETE_DIRECTORY", io_delete_directory};
book->ffns_buf[book->ffns_len++] = (FFn){"RM", io_remove};
book->ffns_buf[book->ffns_len++] = (FFn){"RM_ALL", io_remove_all};
book->ffns_buf[book->ffns_len++] = (FFn){"MKDIR", io_mkdir};
}

Expand Down
93 changes: 24 additions & 69 deletions src/run.cu
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <ftw.h>
#include "hvm.cu"

// Readback: λ-Encoded Ctr
Expand Down Expand Up @@ -838,12 +838,12 @@ Port io_dl_close(GNet* gnet, Book* book, Port argm) {
return gnet_inject_ok(gnet, new_port(ERA, 0));
}

// Deletes a single file or an empty directory at the specified path.
// Removes a single file or an empty directory at the specified path.
// Returns Ok(None) if successful, or Err(reason) if an error occurs.
// This function attempts to remove both files and empty directories without
// first checking the type of the path.
// Returns: Result<*, IOError<i24>>
Port io_delete_file(GNet* gnet, Port argm) {
Port io_remove(GNet* gnet, Port argm) {
Str s = gnet_readback_str(gnet, argm);

int result = remove(s.buf);
Expand All @@ -856,80 +856,35 @@ Port io_delete_file(GNet* gnet, Port argm) {
}
}

int delete_directory_recursive(const char* path) {
DIR* d = opendir(path);
size_t path_len = strlen(path);
int r = -1;

if (d) {
struct dirent *p;
r = 0;

while (!r && (p = readdir(d))) {
int r2 = -1;
char* buf;
size_t len;

if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) {
continue;
}

len = path_len + strlen(p->d_name) + 2;
buf = (char*) malloc(len);

if (buf) {
struct stat statbuf;
snprintf(buf, len, "%s/%s", path, p->d_name);

if (!stat(buf, &statbuf)) {
if (S_ISDIR(statbuf.st_mode)) {
r2 = delete_directory_recursive(buf);
} else {
r2 = remove(buf);
}
}

free(buf);
}

r = r2;
}
int remove_all_aux(const char* path, const struct stat* stat, int flags, struct FTW* ftw) {
return remove(path);
}

closedir(d);
int remove_all(const char* path) {
struct stat st;
if (stat(path, &st) != 0) {
return remove(path);
}

if (!r) {
r = rmdir(path);
if (S_ISDIR(st.st_mode)) {
return nftw(path, remove_all_aux, 32, FTW_DEPTH | FTW_PHYS);
} else {
return remove(path);
}

return r;
}

// Deletes a directory at the specified path. If recursive is True,
// Removes any file or directory recursively at the specified path.
// it will delete the directory and all its contents.
// Returns Ok(None) if successful, or Err(reason) if an error occurs.
// Note: For non-recursive deletion of an empty directory,
// this function behaves the same as delete_file(path).
// Returns: Result<*, IOError<i24>>
Port io_delete_directory(GNet* gnet, Port argm) {
Tup tup = gnet_readback_tup(gnet, argm, 2);
if (tup.elem_len != 2) {
fprintf(stderr, "io_delete_directory: expected tuple\n");

return gnet_inject_io_err_type(gnet);
}

Str path = gnet_readback_str(gnet, tup.elem_buf[0]);
u32 rec = get_u24(get_val(tup.elem_buf[1]));
int res;
if (rec) {
res = delete_directory_recursive(path.buf);
} else {
res = rmdir(path.buf);
}
Port io_remove_all(GNet* gnet, Port argm) {
Str path = gnet_readback_str(gnet, argm);

int res = remove_all(path.buf);
free(path.buf);

if (res == 0) {
if (0 == res) {
return gnet_inject_ok(gnet, new_port(ERA, 0));
} else {
return gnet_inject_io_err_inner(gnet, new_port(NUM, new_i24(errno)));
Expand All @@ -943,10 +898,10 @@ Port io_mkdir(GNet* gnet, Port argm) {
Str name = gnet_readback_str(gnet, argm);

const mode_t mode = 0777;
int result = mkdir(name.buf, mode);
int status = mkdir(name.buf, mode);
free(name.buf);

if (result) {
if (status) {
return gnet_inject_io_err_inner(gnet, new_port(NUM, new_i24(errno)));
} else {
return gnet_inject_ok(gnet, new_port(ERA, 0));
Expand All @@ -965,8 +920,8 @@ void book_init(Book* book) {
book->ffns_buf[book->ffns_len++] = (FFn){"DL_OPEN", io_dl_open};
book->ffns_buf[book->ffns_len++] = (FFn){"DL_CALL", io_dl_call};
book->ffns_buf[book->ffns_len++] = (FFn){"DL_CLOSE", io_dl_open};
book->ffns_buf[book->ffns_len++] = (FFn){"DELETE_FILE", io_delete_file};
book->ffns_buf[book->ffns_len++] = (FFn){"DELETE_DIRECTORY", io_delete_directory};
book->ffns_buf[book->ffns_len++] = (FFn){"RM", io_remove};
book->ffns_buf[book->ffns_len++] = (FFn){"RM_ALL", io_remove_all};
book->ffns_buf[book->ffns_len++] = (FFn){"MKDIR", io_mkdir};

cudaMemcpyToSymbol(BOOK, book, sizeof(Book));
Expand Down
21 changes: 0 additions & 21 deletions tests/programs/io/create_directory.bend

This file was deleted.

16 changes: 0 additions & 16 deletions tests/programs/io/delete_dir_file.bend

This file was deleted.

18 changes: 0 additions & 18 deletions tests/programs/io/delete_empty_dir.bend

This file was deleted.

15 changes: 0 additions & 15 deletions tests/programs/io/delete_non_existing_file.bend

This file was deleted.

19 changes: 19 additions & 0 deletions tests/programs/io/mkdir.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#{
Creates the batata directory and then removes it.
#}

test-io = 1

mkdir path =
(call "MKDIR" path)

rm_all path =
(call "RM_ALL" path)

main =
let path = "./batata"
with IO {
ask * = (mkdir path)
ask s = (rm_all path)
(wrap s)
}
16 changes: 16 additions & 0 deletions tests/programs/io/remove_all_file.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#{
Calls the rm_all function with a file path as argument.
#}

test-io = 1

rm_all path =
(call "RM_ALL" path)

main =
let temp = "./temp.txt"
with IO {
ask * = (IO/FS/write_file temp (String/encode_utf8 "Contents"))
ask s = (rm_all temp)
(wrap s)
}
Loading

0 comments on commit 38408af

Please sign in to comment.