From eb630d493825d8838cfd76f7a7357639a2ae3205 Mon Sep 17 00:00:00 2001 From: julianuziemblo Date: Mon, 16 Mar 2026 17:31:12 +0100 Subject: [PATCH 1/2] unistd/file: add destroy_dev() destroy_dev() is a counterpart to create_dev() that allows for device removal without sending messages back to the calling port unlike remove()/unlink() functions YT: RTOS-1254 (cherry picked from commit 098f27bd4bc68ec849e2fff7eb64444cf3ea5f50) --- include/posix/utils.h | 3 ++ unistd/file.c | 105 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/include/posix/utils.h b/include/posix/utils.h index 8cecf557..f3188c66 100644 --- a/include/posix/utils.h +++ b/include/posix/utils.h @@ -25,6 +25,9 @@ extern "C" { extern int create_dev(oid_t *oid, const char *path); +extern int destroy_dev(const char *path); + + extern void splitname(char *path, char **base, char **dir); diff --git a/unistd/file.c b/unistd/file.c index 86e9107f..27c5544d 100644 --- a/unistd/file.c +++ b/unistd/file.c @@ -525,6 +525,111 @@ int create_dev(oid_t *oid, const char *path) } +int destroy_dev(const char *path) +{ + static int nodevfs = 0; + + oid_t oid, odev; + int retry = 0, err; + char *canonical_path, *dir, *sep; + + if (path == NULL) { + return -EINVAL; + } + + while (lookup("devfs", NULL, &odev) < 0) { + if (++retry < 3 || nodevfs != 0) { + nodevfs = 1; + + if (lookup("/dev", NULL, &odev) < 0) { + return -ENOSYS; + } + else { + break; + } + } + + usleep(100000); + } + + if (strncmp("/dev/", path, 5) == 0) { + canonical_path = strdup(path); + if (canonical_path == NULL) { + return -ENOMEM; + } + } + else { + size_t len = 5 + strlen(path) + 1; + canonical_path = malloc(len); + if (canonical_path == NULL) { + return -ENOMEM; + } + snprintf(canonical_path, len, "/dev/%s", path); + } + + if (lookup(canonical_path, NULL, &oid) < 0) { + free(canonical_path); + return -ENODEV; + } + + dir = canonical_path + 5; + + for (;;) { + sep = strchr(dir, '/'); + if (sep == NULL) { + break; + } + *sep = '\0'; + + msg_t msg = { + .type = mtLookup, + .oid = odev, + .i.size = strlen(dir) + 1, + .i.data = dir, + }; + + err = msgSend(odev.port, &msg); + if (err < 0) { + free(canonical_path); + return err; + } + + if (msg.o.err >= 0) { + odev = msg.o.lookup.dev; + } + else { + free(canonical_path); + return msg.o.err; + } + + do { + sep++; + } while (*sep == '/'); + dir = sep; + } + + path = dir; + + msg_t msg = { + .type = mtUnlink, + .oid = odev, + .i.ln.oid = oid, + .i.data = path, + .i.size = strlen(path) + 1, + }; + + err = msgSend(odev.port, &msg); + + free(canonical_path); + + if (err < 0) { + return err; + } + + return msg.o.err; +} + + extern int sys_fcntl(int fd, int cmd, unsigned val); From a57c212c2f04a0e562798500e436aa5309413e23 Mon Sep 17 00:00:00 2001 From: julianuziemblo Date: Wed, 6 May 2026 13:22:21 +0200 Subject: [PATCH 2/2] unistd/file: fix retry mechanism in destroy_dev() YT: NIL-1077 --- unistd/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unistd/file.c b/unistd/file.c index 27c5544d..72b7dafc 100644 --- a/unistd/file.c +++ b/unistd/file.c @@ -538,7 +538,7 @@ int destroy_dev(const char *path) } while (lookup("devfs", NULL, &odev) < 0) { - if (++retry < 3 || nodevfs != 0) { + if (++retry > 3 || nodevfs != 0) { nodevfs = 1; if (lookup("/dev", NULL, &odev) < 0) {