All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala-native.dirent.c Maven / Gradle / Ivy

There is a newer version: 0.5.5
Show newest version
#if defined(SCALANATIVE_COMPILE_ALWAYS) || defined(__SCALANATIVE_POSIX_DIRENT)
#if defined(__unix__) || defined(__unix) || defined(unix) ||                   \
    (defined(__APPLE__) && defined(__MACH__))
#include 
#include 
#include 
#include 

// Check consistency of Scala Native and operating system definitions.

_Static_assert(sizeof(((struct dirent *)0)->d_ino) <= 8,
               "os ino_t does not match Scala Native dirent");

_Static_assert(sizeof(((struct dirent *)0)->d_type) <= 2,
               "os dirent.d_type does not match Scala Native dirent");

#ifdef NAME_MAX
/* TL;DR - The Scala Native d_name definition should be changed to CString
 *         as soon as breaking changes are allowed. That punts allocation
 *         of storage with sufficient size for a file name to the
 *         operating system, which knows best.
 *
 *         Scala Native can always to a strlen/strnlen of the returned
 *         string and allocate, at its level, the exact required size.
 *         Scala Native code while almost always be copying the os d_name
 *         to a Scala 'String'. fromCString(os_d_name) can be done
 *         directly, and does not require an intermediate allocation and
 *         copy
 *
 * In 2024 and possibly much earlier, linux & FreeBSD  "getconf NAME_MAX /"
 * return 255 for the file systems the most commonly used on those operating
 * systems. They may or may not define NAME_MAX and readdir() may or
 * may not return strings longer that that; long story.
 *
 * macOS limits need to be explored. It specifies a max of 255 UTF-8
 * characters. Since each UTF-8 character can be up to 5 bytes long,
 * a 255 UTF-8 characters could be (255 * 5 == 1275) bytes.
 *
 * Then again, there are file systems, such as Amazon S3 which has a
 * file name length limit of 1024 characters)
 *
 */
_Static_assert(NAME_MAX <= 255, "NAME_MAX does not match Scala Native dirent");
#else
#define NAME_MAX 255 // manually match dirent.scala definition
#endif

struct scalanative_dirent {
    unsigned long long d_ino;  /** file serial number */
    char d_name[NAME_MAX + 1]; /** name of entry */
    short d_type;
};

int scalanative_dt_unknown() { return DT_UNKNOWN; }
int scalanative_dt_fifo() { return DT_FIFO; }
int scalanative_dt_chr() { return DT_CHR; }
int scalanative_dt_dir() { return DT_DIR; }
int scalanative_dt_blk() { return DT_BLK; }
int scalanative_dt_reg() { return DT_REG; }
int scalanative_dt_lnk() { return DT_LNK; }
int scalanative_dt_sock() { return DT_SOCK; }
int scalanative_dt_wht() {
#ifdef DW_WHT
    return DT_WHT;
#else
    return 0;
#endif
}

DIR *scalanative_opendir(const char *name) { return opendir(name); }

void scalanative_dirent_init(struct dirent *dirent,
                             struct scalanative_dirent *my_dirent) {
    my_dirent->d_ino = dirent->d_ino;

    // Note: code will _silently_ truncate any long d_name returned by OS.
    strncpy(my_dirent->d_name, dirent->d_name, NAME_MAX);
    my_dirent->d_name[NAME_MAX] = '\0';
    my_dirent->d_type = dirent->d_type;
}

// This function is for Scala Native internal use only.

// returns 0 in case of success, -1 in case of empty dir, errno otherwise
int scalanative_readdirImpl(DIR *dirp, struct scalanative_dirent *buf) {
    errno = 0;
    struct dirent *orig_buf = readdir(dirp);
    int result = 0;

    if (orig_buf != NULL)
        scalanative_dirent_init(orig_buf, buf);
    else if (errno == 0)
        result = -1;
    else
        result = errno;

    return result;
}
/* This function is for Scala Native internal use only.
 * It is provided to preserve the entry point and prevent a breaking
 * change in 0.5.2. To reduce enduring & compounding complexity, it should
 * be removed for 0.6.0.
 *
 * No Scala Native code defines or calls it.
 */

int scalanative_readdir(DIR *dirp, struct scalanative_dirent *buf) {
    return scalanative_readdirImpl(dirp, buf);
}

int scalanative_closedir(DIR *dirp) { return closedir(dirp); }

#endif // Unix or Mac OS
#endif




© 2015 - 2024 Weber Informatics LLC | Privacy Policy