Skip to content

Commit 38408af

Browse files
committed
refactor rename and use nftw function
1 parent 8ddc3aa commit 38408af

12 files changed

+130
-218
lines changed

src/run.c

Lines changed: 19 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <stdio.h>
44
#include <dirent.h>
55
#include <sys/stat.h>
6-
#include <unistd.h>
6+
#include <ftw.h>
77
#include "hvm.c"
88

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

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

740-
int delete_directory_recursive(const char* path) {
741-
DIR *d = opendir(path);
742-
size_t path_len = strlen(path);
743-
int r = -1;
744-
745-
if (d) {
746-
struct dirent *p;
747-
r = 0;
748-
749-
while (!r && (p = readdir(d))) {
750-
int r2 = -1;
751-
char *buf;
752-
size_t len;
753-
754-
if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) {
755-
continue;
756-
}
757-
758-
len = path_len + strlen(p->d_name) + 2;
759-
buf = malloc(len);
760-
761-
if (buf) {
762-
struct stat statbuf;
763-
snprintf(buf, len, "%s/%s", path, p->d_name);
764-
765-
if (!stat(buf, &statbuf)) {
766-
if (S_ISDIR(statbuf.st_mode)) {
767-
r2 = delete_directory_recursive(buf);
768-
} else {
769-
r2 = remove(buf);
770-
}
771-
}
772-
773-
free(buf);
774-
}
775-
776-
r = r2;
777-
}
740+
int remove_all_aux(const char* path, const struct stat* stat, int flags, struct FTW* ftw) {
741+
return remove(path);
742+
}
778743

779-
closedir(d);
744+
int remove_all(const char* path) {
745+
struct stat st;
746+
if (stat(path, &st) != 0) {
747+
return remove(path);
780748
}
781-
782-
if (!r) {
783-
r = rmdir(path);
749+
if (S_ISDIR(st.st_mode)) {
750+
return nftw(path, remove_all_aux, 32, FTW_DEPTH | FTW_PHYS);
751+
} else {
752+
return remove(path);
784753
}
785-
786-
return r;
787754
}
788755

789-
// Deletes a directory at the specified path. If recursive is True,
756+
// Removes any file or directory recursively at the specified path.
790757
// it will delete the directory and all its contents.
791758
// Returns Ok(None) if successful, or Err(reason) if an error occurs.
792759
// Note: For non-recursive deletion of an empty directory,
793760
// this function behaves the same as delete_file(path).
794761
// Returns: Result<*, IOError<i24>>
795-
Port io_delete_directory(Net* net, Book* book, Port argm) {
796-
Tup tup = readback_tup(net, book, argm, 2);
797-
if (2 != tup.elem_len) {
798-
return inject_io_err_type(net);
799-
}
800-
801-
Str path = readback_str(net, book, tup.elem_buf[0]);
802-
u32 rec = get_u24(get_val(tup.elem_buf[1]));
762+
Port io_remove_all(Net* net, Book* book, Port argm) {
763+
Str path = readback_str(net, book, argm);
803764

804-
int res;
805-
if (rec) {
806-
res = delete_directory_recursive(path.buf);
807-
} else {
808-
res = rmdir(path.buf);
809-
}
765+
int res = remove_all(path.buf);
810766
free(path.buf);
811767

812768
if (0 == res) {
@@ -848,8 +804,8 @@ void book_init(Book* book) {
848804
book->ffns_buf[book->ffns_len++] = (FFn){"DL_OPEN", io_dl_open};
849805
book->ffns_buf[book->ffns_len++] = (FFn){"DL_CALL", io_dl_call};
850806
book->ffns_buf[book->ffns_len++] = (FFn){"DL_CLOSE", io_dl_open};
851-
book->ffns_buf[book->ffns_len++] = (FFn){"DELETE_FILE", io_delete_file};
852-
book->ffns_buf[book->ffns_len++] = (FFn){"DELETE_DIRECTORY", io_delete_directory};
807+
book->ffns_buf[book->ffns_len++] = (FFn){"RM", io_remove};
808+
book->ffns_buf[book->ffns_len++] = (FFn){"RM_ALL", io_remove_all};
853809
book->ffns_buf[book->ffns_len++] = (FFn){"MKDIR", io_mkdir};
854810
}
855811

src/run.cu

Lines changed: 24 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <dirent.h>
55
#include <sys/stat.h>
66
#include <string.h>
7-
#include <unistd.h>
7+
#include <ftw.h>
88
#include "hvm.cu"
99

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

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

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

859-
int delete_directory_recursive(const char* path) {
860-
DIR* d = opendir(path);
861-
size_t path_len = strlen(path);
862-
int r = -1;
863-
864-
if (d) {
865-
struct dirent *p;
866-
r = 0;
867-
868-
while (!r && (p = readdir(d))) {
869-
int r2 = -1;
870-
char* buf;
871-
size_t len;
872-
873-
if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) {
874-
continue;
875-
}
876-
877-
len = path_len + strlen(p->d_name) + 2;
878-
buf = (char*) malloc(len);
879-
880-
if (buf) {
881-
struct stat statbuf;
882-
snprintf(buf, len, "%s/%s", path, p->d_name);
883-
884-
if (!stat(buf, &statbuf)) {
885-
if (S_ISDIR(statbuf.st_mode)) {
886-
r2 = delete_directory_recursive(buf);
887-
} else {
888-
r2 = remove(buf);
889-
}
890-
}
891-
892-
free(buf);
893-
}
894-
895-
r = r2;
896-
}
859+
int remove_all_aux(const char* path, const struct stat* stat, int flags, struct FTW* ftw) {
860+
return remove(path);
861+
}
897862

898-
closedir(d);
863+
int remove_all(const char* path) {
864+
struct stat st;
865+
if (stat(path, &st) != 0) {
866+
return remove(path);
899867
}
900-
901-
if (!r) {
902-
r = rmdir(path);
868+
if (S_ISDIR(st.st_mode)) {
869+
return nftw(path, remove_all_aux, 32, FTW_DEPTH | FTW_PHYS);
870+
} else {
871+
return remove(path);
903872
}
904-
905-
return r;
906873
}
907874

908-
// Deletes a directory at the specified path. If recursive is True,
875+
// Removes any file or directory recursively at the specified path.
909876
// it will delete the directory and all its contents.
910877
// Returns Ok(None) if successful, or Err(reason) if an error occurs.
911878
// Note: For non-recursive deletion of an empty directory,
912879
// this function behaves the same as delete_file(path).
913880
// Returns: Result<*, IOError<i24>>
914-
Port io_delete_directory(GNet* gnet, Port argm) {
915-
Tup tup = gnet_readback_tup(gnet, argm, 2);
916-
if (tup.elem_len != 2) {
917-
fprintf(stderr, "io_delete_directory: expected tuple\n");
918-
919-
return gnet_inject_io_err_type(gnet);
920-
}
921-
922-
Str path = gnet_readback_str(gnet, tup.elem_buf[0]);
923-
u32 rec = get_u24(get_val(tup.elem_buf[1]));
924-
int res;
925-
if (rec) {
926-
res = delete_directory_recursive(path.buf);
927-
} else {
928-
res = rmdir(path.buf);
929-
}
881+
Port io_remove_all(GNet* gnet, Port argm) {
882+
Str path = gnet_readback_str(gnet, argm);
883+
884+
int res = remove_all(path.buf);
930885
free(path.buf);
931886

932-
if (res == 0) {
887+
if (0 == res) {
933888
return gnet_inject_ok(gnet, new_port(ERA, 0));
934889
} else {
935890
return gnet_inject_io_err_inner(gnet, new_port(NUM, new_i24(errno)));
@@ -943,10 +898,10 @@ Port io_mkdir(GNet* gnet, Port argm) {
943898
Str name = gnet_readback_str(gnet, argm);
944899

945900
const mode_t mode = 0777;
946-
int result = mkdir(name.buf, mode);
901+
int status = mkdir(name.buf, mode);
947902
free(name.buf);
948903

949-
if (result) {
904+
if (status) {
950905
return gnet_inject_io_err_inner(gnet, new_port(NUM, new_i24(errno)));
951906
} else {
952907
return gnet_inject_ok(gnet, new_port(ERA, 0));
@@ -965,8 +920,8 @@ void book_init(Book* book) {
965920
book->ffns_buf[book->ffns_len++] = (FFn){"DL_OPEN", io_dl_open};
966921
book->ffns_buf[book->ffns_len++] = (FFn){"DL_CALL", io_dl_call};
967922
book->ffns_buf[book->ffns_len++] = (FFn){"DL_CLOSE", io_dl_open};
968-
book->ffns_buf[book->ffns_len++] = (FFn){"DELETE_FILE", io_delete_file};
969-
book->ffns_buf[book->ffns_len++] = (FFn){"DELETE_DIRECTORY", io_delete_directory};
923+
book->ffns_buf[book->ffns_len++] = (FFn){"RM", io_remove};
924+
book->ffns_buf[book->ffns_len++] = (FFn){"RM_ALL", io_remove_all};
970925
book->ffns_buf[book->ffns_len++] = (FFn){"MKDIR", io_mkdir};
971926

972927
cudaMemcpyToSymbol(BOOK, book, sizeof(Book));

tests/programs/io/create_directory.bend

Lines changed: 0 additions & 21 deletions
This file was deleted.

tests/programs/io/delete_dir_file.bend

Lines changed: 0 additions & 16 deletions
This file was deleted.

tests/programs/io/delete_empty_dir.bend

Lines changed: 0 additions & 18 deletions
This file was deleted.

tests/programs/io/delete_non_existing_file.bend

Lines changed: 0 additions & 15 deletions
This file was deleted.

tests/programs/io/mkdir.bend

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#{
2+
Creates the batata directory and then removes it.
3+
#}
4+
5+
test-io = 1
6+
7+
mkdir path =
8+
(call "MKDIR" path)
9+
10+
rm_all path =
11+
(call "RM_ALL" path)
12+
13+
main =
14+
let path = "./batata"
15+
with IO {
16+
ask * = (mkdir path)
17+
ask s = (rm_all path)
18+
(wrap s)
19+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#{
2+
Calls the rm_all function with a file path as argument.
3+
#}
4+
5+
test-io = 1
6+
7+
rm_all path =
8+
(call "RM_ALL" path)
9+
10+
main =
11+
let temp = "./temp.txt"
12+
with IO {
13+
ask * = (IO/FS/write_file temp (String/encode_utf8 "Contents"))
14+
ask s = (rm_all temp)
15+
(wrap s)
16+
}

0 commit comments

Comments
 (0)