1 /***********************************************************/
2 /* */
3 /* File system stuff */
4 /* */
5 /***********************************************************/
6
7 #include <apricot.h>
8 #include <sys/stat.h>
9 #include "unix/guts.h"
10 #include "Application.h"
11 #include "File.h"
12
13 void
prima_rebuild_watchers(void)14 prima_rebuild_watchers( void)
15 {
16 int i;
17 PFile f;
18
19 FD_ZERO( &guts.read_set);
20 FD_ZERO( &guts.write_set);
21 FD_ZERO( &guts.excpt_set);
22 FD_SET( guts.connection, &guts.read_set);
23 guts.max_fd = guts.connection;
24 for ( i = 0; i < guts.files->count; i++) {
25 f = (PFile)list_at( guts.files,i);
26 if ( f-> eventMask & feRead) {
27 FD_SET( f->fd, &guts.read_set);
28 if ( f->fd > guts.max_fd)
29 guts.max_fd = f->fd;
30 }
31 if ( f-> eventMask & feWrite) {
32 FD_SET( f->fd, &guts.write_set);
33 if ( f->fd > guts.max_fd)
34 guts.max_fd = f->fd;
35 }
36 if ( f-> eventMask & feException) {
37 FD_SET( f->fd, &guts.excpt_set);
38 if ( f->fd > guts.max_fd)
39 guts.max_fd = f->fd;
40 }
41 }
42 }
43
44 Bool
apc_file_attach(Handle self)45 apc_file_attach( Handle self)
46 {
47 if ( PFile(self)->fd >= FD_SETSIZE ) return false;
48
49 if ( list_index_of( guts.files, self) >= 0) {
50 prima_rebuild_watchers();
51 return true;
52 }
53 protect_object( self);
54 list_add( guts.files, self);
55 prima_rebuild_watchers();
56 return true;
57 }
58
59 Bool
apc_file_detach(Handle self)60 apc_file_detach( Handle self)
61 {
62 int i;
63 if (( i = list_index_of( guts.files, self)) >= 0) {
64 list_delete_at( guts.files, i);
65 unprotect_object( self);
66 prima_rebuild_watchers();
67 }
68 return true;
69 }
70
71 Bool
apc_file_change_mask(Handle self)72 apc_file_change_mask( Handle self)
73 {
74 return apc_file_attach( self);
75 }
76
77 PList
apc_getdir(const char * dirname,Bool is_utf8)78 apc_getdir( const char *dirname, Bool is_utf8)
79 {
80 DIR *dh;
81 struct dirent *de;
82 PList dirlist = NULL;
83 char *type;
84 char path[ 2048];
85 struct stat s;
86
87 if (( dh = opendir( dirname)) && (dirlist = plist_create( 50, 50))) {
88 while (( de = readdir( dh))) {
89 list_add( dirlist, (Handle)duplicate_string( de-> d_name));
90 #if defined(DT_REG) && defined(DT_DIR)
91 switch ( de-> d_type) {
92 case DT_FIFO: type = "fifo"; break;
93 case DT_CHR: type = "chr"; break;
94 case DT_DIR: type = "dir"; break;
95 case DT_BLK: type = "blk"; break;
96 case DT_REG: type = "reg"; break;
97 case DT_LNK: type = "lnk"; break;
98 case DT_SOCK: type = "sock"; break;
99 #ifdef DT_WHT
100 case DT_WHT: type = "wht"; break;
101 #endif
102 default:
103 #endif
104 snprintf( path, 2047, "%s/%s", dirname, de-> d_name);
105 type = NULL;
106 if ( stat( path, &s) == 0) {
107 switch ( s. st_mode & S_IFMT) {
108 case S_IFIFO: type = "fifo"; break;
109 case S_IFCHR: type = "chr"; break;
110 case S_IFDIR: type = "dir"; break;
111 case S_IFBLK: type = "blk"; break;
112 case S_IFREG: type = "reg"; break;
113 case S_IFLNK: type = "lnk"; break;
114 case S_IFSOCK: type = "sock"; break;
115 #ifdef S_IFWHT
116 case S_IFWHT: type = "wht"; break;
117 #endif
118 }
119 }
120 if ( !type) type = "unknown";
121 #if defined(DT_REG) && defined(DT_DIR)
122 }
123 #endif
124 list_add( dirlist, (Handle)duplicate_string( type));
125 }
126 closedir( dh);
127 }
128 return dirlist;
129 }
130
131 int
apc_fs_access(const char * name,Bool is_utf8,int mode,Bool effective)132 apc_fs_access(const char *name, Bool is_utf8, int mode, Bool effective)
133 {
134 return
135 #ifdef HAVE_EACCESS
136 effective ? eaccess(name, mode) :
137 #endif
138 access(name, mode);
139 }
140
141 Bool
apc_fs_chdir(const char * path,Bool is_utf8)142 apc_fs_chdir(const char *path, Bool is_utf8 )
143 {
144 return chdir(path) == 0;
145 }
146
147 Bool
apc_fs_chmod(const char * path,Bool is_utf8,int mode)148 apc_fs_chmod( const char *path, Bool is_utf8, int mode)
149 {
150 return chmod(path, mode) == 0;
151 }
152
153 Bool
apc_fs_closedir(PDirHandleRec dh)154 apc_fs_closedir( PDirHandleRec dh)
155 {
156 return closedir(dh->handle) == 0;
157 }
158
159 char *
apc_fs_from_local(const char * text,int * len)160 apc_fs_from_local(const char * text, int * len)
161 {
162 return (char*) text;
163 }
164
165 char*
apc_fs_getcwd()166 apc_fs_getcwd()
167 {
168 char pwd[PATH_MAX];
169 return getcwd(pwd, sizeof(pwd)) == NULL ? NULL : duplicate_string(pwd);
170 }
171
172 char *
apc_fs_to_local(const char * text,Bool fail_if_cannot,int * len)173 apc_fs_to_local(const char * text, Bool fail_if_cannot, int * len)
174 {
175 return (char*)text;
176 }
177
178 char*
apc_fs_getenv(const char * varname,Bool is_utf8,Bool * do_free)179 apc_fs_getenv(const char * varname, Bool is_utf8, Bool * do_free)
180 {
181 *do_free = false;
182 return getenv(varname);
183 }
184
185 Bool
apc_fs_link(const char * oldname,Bool is_old_utf8,const char * newname,Bool is_new_utf8)186 apc_fs_link( const char* oldname, Bool is_old_utf8, const char * newname, Bool is_new_utf8 )
187 {
188 return link(oldname, newname) == 0;
189 }
190
191 Bool
apc_fs_mkdir(const char * path,Bool is_utf8,int mode)192 apc_fs_mkdir( const char* path, Bool is_utf8, int mode)
193 {
194 return mkdir(path, mode) == 0;
195 }
196
197 Bool
apc_fs_opendir(const char * path,PDirHandleRec dh)198 apc_fs_opendir( const char* path, PDirHandleRec dh)
199 {
200 return (dh->handle = opendir(path)) != NULL;
201 }
202
203 int
apc_fs_open_file(const char * path,Bool is_utf8,int flags,int mode)204 apc_fs_open_file( const char* path, Bool is_utf8, int flags, int mode)
205 {
206 return open(path, flags, mode);
207 }
208
209 Bool
apc_fs_readdir(PDirHandleRec dh,char * entry)210 apc_fs_readdir( PDirHandleRec dh, char * entry)
211 {
212 struct dirent *de;
213 if ( !( de = readdir(dh->handle)))
214 return false;
215 strncpy( entry, de->d_name, PATH_MAX_UTF8);
216 return true;
217 }
218
219 Bool
apc_fs_rename(const char * oldname,Bool is_old_utf8,const char * newname,Bool is_new_utf8)220 apc_fs_rename( const char* oldname, Bool is_old_utf8, const char * newname, Bool is_new_utf8 )
221 {
222 return rename(oldname, newname) == 0;
223 }
224
225 Bool
apc_fs_rewinddir(PDirHandleRec dh)226 apc_fs_rewinddir( PDirHandleRec dh )
227 {
228 rewinddir(dh->handle);
229 return true;
230 }
231
232 Bool
apc_fs_rmdir(const char * path,Bool is_utf8)233 apc_fs_rmdir( const char* path, Bool is_utf8 )
234 {
235 return rmdir(path) == 0;
236 }
237
238 Bool
apc_fs_seekdir(PDirHandleRec dh,long position)239 apc_fs_seekdir( PDirHandleRec dh, long position )
240 {
241 seekdir(dh->handle, position);
242 return true;
243 }
244
245 Bool
apc_fs_setenv(const char * varname,Bool is_name_utf8,const char * value,Bool is_value_utf8)246 apc_fs_setenv(const char * varname, Bool is_name_utf8, const char * value, Bool is_value_utf8)
247 {
248 Perl_my_setenv(aTHX_ varname, value);
249 return true;
250 }
251
252 Bool
apc_fs_stat(const char * name,Bool is_utf8,Bool link,PStatRec statrec)253 apc_fs_stat(const char *name, Bool is_utf8, Bool link, PStatRec statrec)
254 {
255 struct stat statbuf;
256 if ( link ) {
257 if ( lstat(name, &statbuf) < 0 )
258 return 0;
259 } else {
260 if ( stat(name, &statbuf) < 0 )
261 return 0;
262 }
263 statrec-> dev = statbuf. st_dev;
264 statrec-> ino = statbuf. st_ino;
265 statrec-> mode = statbuf. st_mode;
266 statrec-> nlink = statbuf. st_nlink;
267 statrec-> uid = statbuf. st_uid;
268 statrec-> gid = statbuf. st_gid;
269 statrec-> rdev = statbuf. st_rdev;
270 statrec-> size = statbuf. st_size;
271 statrec-> blksize = statbuf. st_blksize;
272 statrec-> blocks = statbuf. st_blocks;
273 #ifdef __APPLE__
274 #define ST_F(a) st_##a##timespec
275 #else
276 #define ST_F(a) st_##a##tim
277 #endif
278 statrec-> atim = (float) statbuf.ST_F(a).tv_sec + (float) statbuf.ST_F(a).tv_nsec / 1000000000.0;
279 statrec-> mtim = (float) statbuf.ST_F(m).tv_sec + (float) statbuf.ST_F(m).tv_nsec / 1000000000.0;
280 statrec-> ctim = (float) statbuf.ST_F(c).tv_sec + (float) statbuf.ST_F(c).tv_nsec / 1000000000.0;
281 #undef ST_F
282 return 1;
283 }
284
285 long
apc_fs_telldir(PDirHandleRec dh)286 apc_fs_telldir( PDirHandleRec dh )
287 {
288 return telldir(dh-> handle);
289 }
290
291 Bool
apc_fs_unlink(const char * path,Bool is_utf8)292 apc_fs_unlink( const char* path, Bool is_utf8 )
293 {
294 return unlink(path) == 0;
295 }
296
297 Bool
apc_fs_utime(double atime,double mtime,const char * path,Bool is_utf8)298 apc_fs_utime( double atime, double mtime, const char* path, Bool is_utf8 )
299 {
300 struct timeval tv[2];
301 tv[0].tv_sec = (long) atime;
302 tv[0].tv_usec = (atime - (float) tv[0].tv_sec) * 1000000;
303 tv[1].tv_sec = (long) mtime;
304 tv[1].tv_usec = (mtime - (float) tv[1].tv_sec) * 1000000;
305
306 return utimes(path, tv) == 0;
307 }
308
309