1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-25 09:47:17 +00:00

Merge pull request #319 from leahneukirchen/lstat

os/lstat and os/readlink
This commit is contained in:
Calvin Rose 2020-03-18 17:58:32 -05:00 committed by GitHub
commit eee8338064
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -32,6 +32,7 @@
#include <time.h> #include <time.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -746,6 +747,23 @@ static Janet os_remove(int32_t argc, Janet *argv) {
return janet_wrap_nil(); return janet_wrap_nil();
} }
static Janet os_readlink(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
#ifdef JANET_WINDOWS
(void) argc;
(void) argv;
janet_panic("os/readlink not supported on Windows");
return janet_wrap_nil();
#else
static char buffer[PATH_MAX];
const char *path = janet_getcstring(argv, 0);
ssize_t len = readlink(path, buffer, sizeof buffer);
if (len < 0 || (size_t)len >= sizeof buffer)
janet_panicf("%s: %s", strerror(errno), path);
return janet_stringv((const uint8_t *)buffer, len);
#endif
}
#ifdef JANET_WINDOWS #ifdef JANET_WINDOWS
static const uint8_t *janet_decode_permissions(unsigned short m) { static const uint8_t *janet_decode_permissions(unsigned short m) {
uint8_t flags[9] = {0}; uint8_t flags[9] = {0};
@ -920,7 +938,7 @@ static const struct OsStatGetter os_stat_getters[] = {
{NULL, NULL} {NULL, NULL}
}; };
static Janet os_stat(int32_t argc, Janet *argv) { static Janet os_stat_or_lstat(int do_lstat, int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2); janet_arity(argc, 1, 2);
const char *path = janet_getcstring(argv, 0); const char *path = janet_getcstring(argv, 0);
JanetTable *tab = NULL; JanetTable *tab = NULL;
@ -939,11 +957,17 @@ static Janet os_stat(int32_t argc, Janet *argv) {
/* Build result */ /* Build result */
#ifdef JANET_WINDOWS #ifdef JANET_WINDOWS
(void) do_lstat;
struct _stat st; struct _stat st;
int res = _stat(path, &st); int res = _stat(path, &st);
#else #else
struct stat st; struct stat st;
int res = stat(path, &st); int res;
if (do_lstat) {
res = lstat(path, &st);
} else {
res = stat(path, &st);
}
#endif #endif
if (-1 == res) { if (-1 == res) {
return janet_wrap_nil(); return janet_wrap_nil();
@ -966,6 +990,14 @@ static Janet os_stat(int32_t argc, Janet *argv) {
} }
} }
static Janet os_stat(int32_t argc, Janet *argv) {
return os_stat_or_lstat(0, argc, argv);
}
static Janet os_lstat(int32_t argc, Janet *argv) {
return os_stat_or_lstat(1, argc, argv);
}
static Janet os_chmod(int32_t argc, Janet *argv) { static Janet os_chmod(int32_t argc, Janet *argv) {
janet_fixarity(argc, 2); janet_fixarity(argc, 2);
const char *path = janet_getcstring(argv, 0); const char *path = janet_getcstring(argv, 0);
@ -1094,6 +1126,11 @@ static const JanetReg os_cfuns[] = {
"\t:changed - timestamp when file last chnaged (permissions changed)\n" "\t:changed - timestamp when file last chnaged (permissions changed)\n"
"\t:modified - timestamp when file last modified (content changed)\n") "\t:modified - timestamp when file last modified (content changed)\n")
}, },
{
"os/lstat", os_lstat,
JDOC("(os/lstat path &opt tab|key)\n\n"
"Like os/stat, but don't follow symlinks.\n")
},
{ {
"os/chmod", os_chmod, "os/chmod", os_chmod,
JDOC("(os/chmod path mode)\n\n" JDOC("(os/chmod path mode)\n\n"
@ -1135,6 +1172,11 @@ static const JanetReg os_cfuns[] = {
"Create a symlink from oldpath to newpath. The 3 optional paramater " "Create a symlink from oldpath to newpath. The 3 optional paramater "
"enables a hard link over a soft link. Does not work on Windows.") "enables a hard link over a soft link. Does not work on Windows.")
}, },
{
"os/readlink", os_readlink,
JDOC("(os/readlink path)\n\n"
"Read the contents of a symbolic link. Does not work on Windows.\n")
},
{ {
"os/execute", os_execute, "os/execute", os_execute,
JDOC("(os/execute args &opts flags env)\n\n" JDOC("(os/execute args &opts flags env)\n\n"