From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

/***********************************************************/
/* */
/* File system stuff */
/* */
/***********************************************************/
#include <apricot.h>
#include <sys/stat.h>
#include "unix/guts.h"
#include "Application.h"
#include "File.h"
void
prima_rebuild_watchers( void)
{
int i;
PFile f;
FD_ZERO( &guts.read_set);
FD_ZERO( &guts.write_set);
FD_ZERO( &guts.excpt_set);
FD_SET( guts.connection, &guts.read_set);
guts.max_fd = guts.connection;
for ( i = 0; i < guts.files->count; i++) {
f = (PFile)list_at( guts.files,i);
if ( f-> eventMask & feRead) {
FD_SET( f->fd, &guts.read_set);
if ( f->fd > guts.max_fd)
guts.max_fd = f->fd;
}
if ( f-> eventMask & feWrite) {
FD_SET( f->fd, &guts.write_set);
if ( f->fd > guts.max_fd)
guts.max_fd = f->fd;
}
if ( f-> eventMask & feException) {
FD_SET( f->fd, &guts.excpt_set);
if ( f->fd > guts.max_fd)
guts.max_fd = f->fd;
}
}
}
Bool
apc_file_attach( Handle self)
{
if ( PFile(self)->fd >= FD_SETSIZE ) return false;
if ( list_index_of( guts.files, self) >= 0) {
prima_rebuild_watchers();
return true;
}
protect_object( self);
list_add( guts.files, self);
prima_rebuild_watchers();
return true;
}
Bool
apc_file_detach( Handle self)
{
int i;
if (( i = list_index_of( guts.files, self)) >= 0) {
list_delete_at( guts.files, i);
unprotect_object( self);
prima_rebuild_watchers();
}
return true;
}
Bool
apc_file_change_mask( Handle self)
{
return apc_file_attach( self);
}
PList
apc_getdir( const char *dirname, Bool is_utf8)
{
DIR *dh;
struct dirent *de;
PList dirlist = NULL;
char *type;
char path[ 2048];
struct stat s;
if (( dh = opendir( dirname)) && (dirlist = plist_create( 50, 50))) {
while (( de = readdir( dh))) {
list_add( dirlist, (Handle)duplicate_string( de-> d_name));
#if defined(DT_REG) && defined(DT_DIR)
switch ( de-> d_type) {
case DT_FIFO: type = "fifo"; break;
case DT_CHR: type = "chr"; break;
case DT_DIR: type = "dir"; break;
case DT_BLK: type = "blk"; break;
case DT_REG: type = "reg"; break;
case DT_LNK: type = "lnk"; break;
case DT_SOCK: type = "sock"; break;
#ifdef DT_WHT
case DT_WHT: type = "wht"; break;
#endif
default:
#endif
snprintf( path, 2047, "%s/%s", dirname, de-> d_name);
type = NULL;
if ( stat( path, &s) == 0) {
switch ( s. st_mode & S_IFMT) {
case S_IFIFO: type = "fifo"; break;
case S_IFCHR: type = "chr"; break;
case S_IFDIR: type = "dir"; break;
case S_IFBLK: type = "blk"; break;
case S_IFREG: type = "reg"; break;
case S_IFLNK: type = "lnk"; break;
case S_IFSOCK: type = "sock"; break;
#ifdef S_IFWHT
case S_IFWHT: type = "wht"; break;
#endif
}
}
if ( !type) type = "unknown";
#if defined(DT_REG) && defined(DT_DIR)
}
#endif
list_add( dirlist, (Handle)duplicate_string( type));
}
closedir( dh);
}
return dirlist;
}
int
apc_fs_access(const char *name, Bool is_utf8, int mode, Bool effective)
{
return
#ifdef HAVE_EACCESS
effective ? eaccess(name, mode) :
#endif
access(name, mode);
}
Bool
apc_fs_chdir(const char *path, Bool is_utf8 )
{
return chdir(path) == 0;
}
Bool
apc_fs_chmod( const char *path, Bool is_utf8, int mode)
{
return chmod(path, mode) == 0;
}
Bool
apc_fs_closedir( PDirHandleRec dh)
{
return closedir(dh->handle) == 0;
}
char *
apc_fs_from_local(const char * text, int * len)
{
return (char*) text;
}
char*
apc_fs_getcwd()
{
char pwd[PATH_MAX];
return getcwd(pwd, sizeof(pwd)) == NULL ? NULL : duplicate_string(pwd);
}
char *
apc_fs_to_local(const char * text, Bool fail_if_cannot, int * len)
{
return (char*)text;
}
char*
apc_fs_getenv(const char * varname, Bool is_utf8, Bool * do_free)
{
*do_free = false;
return getenv(varname);
}
Bool
apc_fs_link( const char* oldname, Bool is_old_utf8, const char * newname, Bool is_new_utf8 )
{
return link(oldname, newname) == 0;
}
Bool
apc_fs_mkdir( const char* path, Bool is_utf8, int mode)
{
return mkdir(path, mode) == 0;
}
Bool
apc_fs_opendir( const char* path, PDirHandleRec dh)
{
return (dh->handle = opendir(path)) != NULL;
}
int
apc_fs_open_file( const char* path, Bool is_utf8, int flags, int mode)
{
return open(path, flags, mode);
}
Bool
apc_fs_readdir( PDirHandleRec dh, char * entry)
{
struct dirent *de;
if ( !( de = readdir(dh->handle)))
return false;
strlcpy( entry, de->d_name, PATH_MAX_UTF8);
return true;
}
Bool
apc_fs_rename( const char* oldname, Bool is_old_utf8, const char * newname, Bool is_new_utf8 )
{
return rename(oldname, newname) == 0;
}
Bool
apc_fs_rewinddir( PDirHandleRec dh )
{
rewinddir(dh->handle);
return true;
}
Bool
apc_fs_rmdir( const char* path, Bool is_utf8 )
{
return rmdir(path) == 0;
}
Bool
apc_fs_seekdir( PDirHandleRec dh, long position )
{
seekdir(dh->handle, position);
return true;
}
Bool
apc_fs_setenv(const char * varname, Bool is_name_utf8, const char * value, Bool is_value_utf8)
{
Perl_my_setenv(aTHX_ varname, value);
return true;
}
Bool
apc_fs_stat(const char *name, Bool is_utf8, Bool link, PStatRec statrec)
{
struct stat statbuf;
if ( link ) {
if ( lstat(name, &statbuf) < 0 )
return 0;
} else {
if ( stat(name, &statbuf) < 0 )
return 0;
}
statrec-> dev = statbuf. st_dev;
statrec-> ino = statbuf. st_ino;
statrec-> mode = statbuf. st_mode;
statrec-> nlink = statbuf. st_nlink;
statrec-> uid = statbuf. st_uid;
statrec-> gid = statbuf. st_gid;
statrec-> rdev = statbuf. st_rdev;
statrec-> size = statbuf. st_size;
statrec-> blksize = statbuf. st_blksize;
statrec-> blocks = statbuf. st_blocks;
#ifdef __APPLE__
#define ST_F(a) st_##a##timespec
#else
#define ST_F(a) st_##a##tim
#endif
statrec-> atim = (float) statbuf.ST_F(a).tv_sec + (float) statbuf.ST_F(a).tv_nsec / 1000000000.0;
statrec-> mtim = (float) statbuf.ST_F(m).tv_sec + (float) statbuf.ST_F(m).tv_nsec / 1000000000.0;
statrec-> ctim = (float) statbuf.ST_F(c).tv_sec + (float) statbuf.ST_F(c).tv_nsec / 1000000000.0;
#undef ST_F
return 1;
}
long
apc_fs_telldir( PDirHandleRec dh )
{
return telldir(dh-> handle);
}
Bool
apc_fs_unlink( const char* path, Bool is_utf8 )
{
return unlink(path) == 0;
}
Bool
apc_fs_utime( double atime, double mtime, const char* path, Bool is_utf8 )
{
struct timeval tv[2];
tv[0].tv_sec = (long) atime;
tv[0].tv_usec = (atime - (float) tv[0].tv_sec) * 1000000;
tv[1].tv_sec = (long) mtime;
tv[1].tv_usec = (mtime - (float) tv[1].tv_sec) * 1000000;
return utimes(path, tv) == 0;
}