#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;
}