|
31 | 31 | #include <stdio.h> |
32 | 32 | #include <string.h> |
33 | 33 | #include <time.h> |
| 34 | +#include <unistd.h> |
| 35 | +#include <limits.h> |
34 | 36 |
|
35 | 37 | #include "atom_table.h" |
36 | 38 | #include "avm_version.h" |
@@ -99,6 +101,7 @@ static term nif_binary_part_3(Context *ctx, int argc, term argv[]); |
99 | 101 | static term nif_binary_split(Context *ctx, int argc, term argv[]); |
100 | 102 | static term nif_binary_replace(Context *ctx, int argc, term argv[]); |
101 | 103 | static term nif_binary_match(Context *ctx, int argc, term argv[]); |
| 104 | +static term nif_prim_file_get_cwd_0(Context *ctx, int argc, term argv[]); |
102 | 105 | static term nif_calendar_system_time_to_universal_time_2(Context *ctx, int argc, term argv[]); |
103 | 106 | static term nif_erlang_delete_element_2(Context *ctx, int argc, term argv[]); |
104 | 107 | static term nif_erlang_atom_to_binary(Context *ctx, int argc, term argv[]); |
@@ -277,6 +280,12 @@ static const struct Nif binary_match_nif = |
277 | 280 | .nif_ptr = nif_binary_match |
278 | 281 | }; |
279 | 282 |
|
| 283 | +static const struct Nif prim_file_get_cwd_nif = |
| 284 | +{ |
| 285 | + .base.type = NIFFunctionType, |
| 286 | + .nif_ptr = nif_prim_file_get_cwd_0 |
| 287 | +}; |
| 288 | + |
280 | 289 | static const struct Nif make_ref_nif = |
281 | 290 | { |
282 | 291 | .base.type = NIFFunctionType, |
@@ -5842,6 +5851,53 @@ static term nif_erlang_lists_subtract(Context *ctx, int argc, term argv[]) |
5842 | 5851 | return result; |
5843 | 5852 | } |
5844 | 5853 |
|
| 5854 | + |
| 5855 | +static term nif_prim_file_get_cwd_0(Context *ctx, int argc, term argv[]) |
| 5856 | +{ |
| 5857 | + UNUSED(argc) |
| 5858 | + UNUSED(argv) |
| 5859 | + char cwd[PATH_MAX]; |
| 5860 | + if (UNLIKELY(IS_NULL_PTR(cwd))) { |
| 5861 | + RAISE_ERROR(OUT_OF_MEMORY_ATOM); |
| 5862 | + } |
| 5863 | + |
| 5864 | + if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2)) != MEMORY_GC_OK)) { |
| 5865 | + RAISE_ERROR(OUT_OF_MEMORY_ATOM); |
| 5866 | + } |
| 5867 | + term result_tuple = term_alloc_tuple(2, &ctx->heap); |
| 5868 | + |
| 5869 | + if (UNLIKELY(IS_NULL_PTR(getcwd(cwd, PATH_MAX)))) { |
| 5870 | + term reason = UNDEFINED_ATOM; |
| 5871 | + switch (errno) { |
| 5872 | + case EACCES: |
| 5873 | + reason = globalcontext_make_atom(ctx->global, ATOM_STR("\x11", "permission_denied")); |
| 5874 | + break; |
| 5875 | + case EINVAL: |
| 5876 | + reason = globalcontext_make_atom(ctx->global, ATOM_STR("\xD", "negative_size")); |
| 5877 | + break; |
| 5878 | + case ERANGE: |
| 5879 | + reason = globalcontext_make_atom(ctx->global, ATOM_STR("\x10", "buffer_too_small")); |
| 5880 | + break; |
| 5881 | + default: |
| 5882 | + reason = globalcontext_make_atom(ctx->global, ATOM_STR("\xD", "unknown_error")); |
| 5883 | + break; |
| 5884 | + } |
| 5885 | + term_put_tuple_element(result_tuple, 0, ERROR_ATOM); |
| 5886 | + term_put_tuple_element(result_tuple, 1, reason); |
| 5887 | + return result_tuple; |
| 5888 | + } |
| 5889 | + |
| 5890 | + size_t cwd_length = strlen(cwd); |
| 5891 | + if (UNLIKELY(memory_ensure_free_with_roots(ctx, term_binary_heap_size(cwd_length), 1, &result_tuple, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { |
| 5892 | + RAISE_ERROR(OUT_OF_MEMORY_ATOM); |
| 5893 | + } |
| 5894 | + term result = term_from_literal_binary(cwd, cwd_length, &ctx->heap, ctx->global); |
| 5895 | + |
| 5896 | + term_put_tuple_element(result_tuple, 0, OK_ATOM); |
| 5897 | + term_put_tuple_element(result_tuple, 1, result); |
| 5898 | + return result_tuple; |
| 5899 | +} |
| 5900 | + |
5845 | 5901 | #ifdef WITH_ZLIB |
5846 | 5902 | static term nif_zlib_compress_1(Context *ctx, int argc, term argv[]) |
5847 | 5903 | { |
|
0 commit comments