3 #include <boost/filesystem.hpp>
6 namespace fslib
= boost::filesystem
;
7 typedef fslib::filesystem_error fslib_error
;
9 struct VXPopen
: VXIOBase
11 FILE* fn_base_open(const char* path
, const char* mode
)
13 return popen(path
, mode
);
16 void fn_base_close(FILE* handle
)
23 const char* oshelper_strerror(int errval
)
25 #if defined(VOX_PLATFORM_MSWINDOWS)
28 FORMAT_MESSAGE_FROM_SYSTEM
|
29 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
30 FORMAT_MESSAGE_IGNORE_INSERTS
,
31 NULL
, errval
, MAKELANGID(LANG_NEUTRAL
,SUBLANG_DEFAULT
),
32 (LPTSTR
)&tempmessage
,0,NULL
);
33 return (const char*)tempmessage
;
35 return strerror(errval
);
41 #if defined(VOX_PLATFORM_MSWINDOWS)
42 return ::GetLastError();
48 const char* oshelper_lasterror()
50 return oshelper_strerror(oshelper_errno());
53 bool oshelper_killpid(int pid
, int sign
)
56 #if defined(VOX_PLATFORM_UNIX)
57 failed
= (kill(pid
, sign
) == -1);
58 #elif defined(VOX_PLATFORM_MSWINDOWS)
60 HANDLE hnd
= OpenProcess(1, 0, pid
);
61 failed
= (0 != TerminateProcess(hnd
, 0));
66 int oshelper_sleep(VXFloat milisec
)
68 #ifdef VOX_PLATFORM_MSWINDOWS
71 timespec req
= {0, 0};
78 milisec
= milisec
- (sec
* 1000);
80 req
.tv_nsec
= milisec
*1000000L;
81 while(nanosleep(&req
, &req
) == -1)
89 bool oshelper_chdir(const std::string
& path
)
92 #if defined(VOX_PLATFORM_MSWINDOWS)
93 status
= _chdir(path
.c_str());
94 #elif defined(VOX_PLATFORM_UNIX)
95 status
= chdir(path
.c_str());
100 bool oshelper_chmod(const std::string
& path
, unsigned int octal
)
103 #if defined(VOX_PLATFORM_MSWINDOWS)
104 status
= _chmod(path
.c_str(), octal
);
105 #elif defined(VOX_PLATFORM_UNIX)
106 status
= chmod(path
.c_str(), octal
);
108 return (status
== 0);
111 bool oshelper_mkdir(const std::string
& path
, int octal
)
114 #if defined(VOX_PLATFORM_MSWINDOWS)
116 status
= _mkdir(path
.c_str());
117 #elif defined(VOX_PLATFORM_UNIX)
118 status
= mkdir(path
.c_str(), octal
);
120 return (status
== -1);
123 template<typename Type
>
124 inline static const char* oshelper_exception_message(Type
& err
)
126 return err
.code().message().c_str();
129 VXInteger
oslib_getenv(VXState
* v
)
131 const char* env_name
;
132 const char* env_value
;
133 v
->GetString(2, &env_name
, NULL
);
134 env_value
= getenv(env_name
);
135 if(env_value
!= NULL
)
137 v
->Push(v
->NewString(env_value
));
143 VXInteger
oslib_system(VXState
* v
)
145 const char* shellcmd
;
146 if(system(NULL
) == 0)
148 return v
->ThrowError("system() is not available");
150 v
->GetString(2, &shellcmd
, NULL
);
151 v
->Push(VXInteger(system(shellcmd
)));
156 VXInteger
oslib_clock(VXState
* v
)
158 v
->Push(VXFloat(clock()) / VXFloat(CLOCKS_PER_SEC
));
162 VXInteger
oslib_time(VXState
* v
)
166 v
->Push(VXInteger(t
));
170 VXInteger
oslib_remove(VXState
* v
)
173 v
->GetString(2, &path
, NULL
);
178 catch(fslib_error
& err
)
180 return v
->ThrowError(oshelper_exception_message(err
));
185 VXInteger
oslib_remove_all(VXState
* v
)
188 v
->GetString(2, &path
, NULL
);
191 fslib::remove_all(path
);
193 catch(fslib_error
& err
)
195 return v
->ThrowError(oshelper_exception_message(err
));
200 VXInteger
oslib_exit(VXState
* v
)
203 if(VX_FAILED(v
->GetInteger(2, &status
)))
212 VXInteger
oslib_rename(VXState
* v
)
216 v
->GetString(2, &oldpath
, NULL
);
217 v
->GetString(3, &newpath
, NULL
);
220 fslib::rename(oldpath
, newpath
);
222 catch(fslib_error
& err
)
224 return v
->ThrowError(oshelper_exception_message(err
));
229 VXInteger
oslib_date(VXState
* v
)
234 VXInteger format
= 'l';
237 v
->GetInteger(2,&it
);
241 v
->GetInteger(3, (VXInteger
*)&format
);
255 date
= localtime(&t
);
259 return v
->ThrowError("crt api failure");
261 VXTableObj
* tb
= v
->NewTable();
262 tb
->NewSlot(v
->NewString("sec"), VXInteger(date
->tm_sec
));
263 tb
->NewSlot(v
->NewString("min"), VXInteger(date
->tm_min
));
264 tb
->NewSlot(v
->NewString("hour"), VXInteger(date
->tm_hour
));
265 tb
->NewSlot(v
->NewString("day"), VXInteger(date
->tm_mday
));
266 tb
->NewSlot(v
->NewString("month"), VXInteger(date
->tm_mon
));
267 tb
->NewSlot(v
->NewString("year"), VXInteger(date
->tm_year
));
268 tb
->NewSlot(v
->NewString("wday"), VXInteger(date
->tm_wday
));
269 tb
->NewSlot(v
->NewString("yday"), VXInteger(date
->tm_yday
));
274 VXInteger
oslib_listdir(VXState
* v
)
278 v
->GetString(2, &path
, NULL
);
281 fslib::directory_iterator end
;
282 fslib::directory_iterator
iter(path
);
283 VXArrayObj
* arr
= v
->NewArray();
284 for(; iter
!=end
; iter
++)
286 s_itm
= (*iter
).path().string();
287 arr
->Append(v
->NewString(s_itm
.c_str(), s_itm
.length()));
291 catch(fslib_error
& err
)
293 return v
->ThrowError(oshelper_exception_message(err
));
298 VXInteger
oslib_kill(VXState
* v
)
302 v
->GetInteger(2, &pid
);
303 if(VX_FAILED(v
->GetInteger(3, &sign
)))
307 v
->PushInteger(oshelper_killpid(pid
, sign
));
311 VXInteger
oslib_mkdir(VXState
* v
)
314 VXInteger permissions
;
315 v
->GetString(2, &path
, NULL
);
316 if(VX_FAILED(v
->GetInteger(3, &permissions
)))
320 if(oshelper_mkdir(path
, permissions
) == false)
322 return v
->ThrowError(oshelper_lasterror());
327 VXInteger
oslib_chmod(VXState
* v
)
330 VXInteger permissions
;
331 v
->GetString(2, &path
, NULL
);
332 v
->GetInteger(3, &permissions
);
333 if(oshelper_chmod(path
, permissions
) == false)
335 return v
->ThrowError(oshelper_lasterror());
340 VXInteger
oslib_basename(VXState
* v
)
344 v
->GetString(2, &path
, NULL
);
345 newpath
= fslib::path(path
).filename().string();
346 v
->Push(v
->NewString(newpath
.c_str(), newpath
.length()));
350 VXInteger
oslib_dirname(VXState
* v
)
354 v
->GetString(2, &path
, NULL
);
355 fslib::path
_tmp(path
);
356 newpath
= fslib::path(path
).parent_path().string();
357 v
->Push(v
->NewString(newpath
.c_str(), newpath
.length()));
361 VXInteger
oslib_usleep(VXState
* v
)
364 v
->GetFloat(2, &howlong
);
365 oshelper_sleep(howlong
);
369 VXInteger
oslib_sleep(VXState
* v
)
372 v
->GetInteger(2, &howlong
);
373 oshelper_sleep(howlong
* 1000);
377 VXInteger
oslib_filesize(VXState
* v
)
380 v
->GetString(2, &path
, NULL
);
383 v
->Push(VXInteger(fslib::file_size(path
)));
385 catch(fslib_error
& err
)
387 return v
->ThrowError(oshelper_exception_message(err
));
392 VXInteger
oslib_exists(VXState
* v
)
395 v
->GetString(2, &path
, NULL
);
398 v
->Push(bool(fslib::exists(path
)));
400 catch(fslib_error
& err
)
402 return v
->ThrowError(oshelper_exception_message(err
));
407 VXInteger
oslib_isfile(VXState
* v
)
410 v
->GetString(2, &path
, NULL
);
411 v
->Push(bool(fslib::is_regular_file(path
)));
415 VXInteger
oslib_isdir(VXState
* v
)
418 v
->GetString(2, &path
, NULL
);
421 v
->Push(bool(fslib::is_directory(path
)));
423 catch(fslib_error
& err
)
425 return v
->ThrowError(oshelper_exception_message(err
));
430 VXInteger
oslib_stat(VXState
* v
)
434 v
->GetString(2, &path
, NULL
);
435 if(stat(path
, &buf
) == 0)
437 VXTableObj
* tb
= v
->NewTable();
442 return v
->ThrowError(oshelper_lasterror());
447 VXInteger
popenclass_fn_releasehook(VXUserPointer p
, VXInteger size
)
450 VXPopen
* self
= (VXPopen
*)p
;
451 if(self
->isclosed
== false)
459 VXInteger
popenclass_fn_constructor(VXState
* v
)
465 v
->GetString(2, &path
, NULL
);
466 if(VX_FAILED(v
->GetString(3, &mode
, NULL
)))
470 if(!self
->open(path
, mode
))
472 return v
->ThrowError(oshelper_lasterror());
474 v
->SetInstanceUp(1, (VXUserPointer
*)&self
);
475 v
->SetReleaseHook(1, popenclass_fn_releasehook
);
479 VXInteger
popenclass_fn_read(VXState
* v
)
485 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
486 if(VX_FAILED(v
->GetInteger(2, &howmuch
)))
490 buffer
= new char[howmuch
+1];
491 haveread
= self
->readbuf(buffer
, howmuch
);
494 buffer
[haveread
] = 0;
495 v
->PushString(buffer
, haveread
);
505 VXInteger
popenclass_fn_flush(VXState
* v
)
508 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
509 v
->Push(self
->flushstream());
513 VXInteger
popenclass_fn_name(VXState
* v
)
516 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
517 v
->PushString(self
->name
);
521 VXInteger
popenclass_fn_readline(VXState
* v
)
525 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
530 self
->readline(buffer
);
531 v
->Push(v
->NewString(buffer
.c_str(), buffer
.length()));
535 VXInteger
popenclass_fn_readchar(VXState
* v
)
539 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
540 c
= self
->readchar();
553 VXInteger
popenclass_fn_close(VXState
* v
)
556 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
557 v
->Push(self
->close());
561 VXInteger
popenclass_fn_write(VXState
* v
)
567 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
568 v
->GetString(2, &data
, &len
);
569 if(self
->write(data
, len
, &written
) == true)
574 /* when the file got opened in readonly mode, write()
575 will fail, so don't just ignore it, but handle it */
576 return v
->ThrowError(self
->error());
579 VXInteger
popenclass_fn_eof(VXState
* v
)
582 v
->GetInstanceUp(1, (VXUserPointer
*)&self
, 0);
583 v
->Push(bool(self
->eof()));
587 static VXRegFunction popen_funcs
[]=
589 {"constructor", popenclass_fn_constructor
, -2, ".ss"},
590 {"name", popenclass_fn_name
, -1, ".n"},
591 {"read", popenclass_fn_read
, -1, ".n"},
592 {"readchar", popenclass_fn_readchar
, 1, NULL
},
593 {"readline", popenclass_fn_readline
, -1, NULL
},
594 {"write", popenclass_fn_write
, 2, ".s"},
595 {"close", popenclass_fn_close
, 1, NULL
},
596 {"flush", popenclass_fn_flush
, 1, "x"},
597 {"eof", popenclass_fn_eof
, 1, "x"},
601 VXInteger
oslib_uname(VXState
* v
)
603 #if defined(VOX_PLATFORM_UNIX)
607 VXTableObj
* tb
= v
->NewTable();
608 tb
->NewSlot(v
->NewString("sysname"), v
->NewString(buf
.sysname
));
609 tb
->NewSlot(v
->NewString("nodename"), v
->NewString(buf
.nodename
));
610 tb
->NewSlot(v
->NewString("release"), v
->NewString(buf
.release
));
611 tb
->NewSlot(v
->NewString("version"), v
->NewString(buf
.version
));
612 tb
->NewSlot(v
->NewString("machine"), v
->NewString(buf
.machine
));
616 return v
->ThrowError(oshelper_lasterror());
618 return v
->ThrowError("uname() is not available on this platform");
624 VXInteger
oslib_tempname(VXState
* v
)
626 char* result
; // char*, because it needs to be free()'d
629 if(VX_FAILED(v
->GetString(2, &path
, NULL
)))
631 if(VX_FAILED(v
->GetString(3, &tpl
, NULL
)))
633 result
= tempnam(path
, tpl
);
634 v
->Push(v
->NewString(result
));
639 VXInteger
oslib_joinpath(VXState
* v
)
644 std::string fullpath
;
646 for(i
=2; i
!=(v
->GetTop()+1); i
++)
650 v
->ToString(ob
, strval
);
651 strval
.String()->Get(&str
);
655 fullpath
= p
.string();
656 v
->Push(v
->NewString(fullpath
.c_str(), fullpath
.length()));
660 VXInteger
oslib_abspath(VXState
* v
)
663 std::string fullpath
;
664 v
->GetString(2, &subject
);
665 fslib::path
p(subject
);
666 fullpath
= p
.string();
667 v
->Push(v
->NewString(fullpath
.c_str(), fullpath
.length()));
671 VXRegFunction oslib_funcs
[]=
673 {"getenv", oslib_getenv
, 2, ".s"},
674 {"system", oslib_system
, 2, ".s"},
675 {"date", oslib_date
, -1, ".nn"},
676 {"remove", oslib_remove
, 2, ".s"},
677 {"remove_all", oslib_remove_all
, 2, ".s"},
678 {"listdir", oslib_listdir
, 2, ".s"},
679 {"rename", oslib_rename
, 3, ".ss"},
680 {"clock", oslib_clock
, 0, NULL
},
681 {"time", oslib_time
, 1, NULL
},
682 {"exit", oslib_exit
, -1, ".n"},
683 {"kill", oslib_kill
, -1, ".nn"},
684 {"chmod", oslib_chmod
, 3, ".sn"},
685 {"mkdir", oslib_mkdir
, 3, ".s|.n"},
686 {"basename", oslib_basename
, 2, ".s"},
687 {"dirname", oslib_dirname
, 2, ".s"},
688 {"usleep", oslib_usleep
, 2, ".n"},
689 {"sleep", oslib_sleep
, 2, ".n"},
690 {"exists", oslib_exists
, 2, ".s"},
691 {"isdir", oslib_isdir
, 2, ".s"},
692 {"isfile", oslib_isfile
, 2, ".s"},
693 {"abspath", oslib_abspath
, 2, ".s"},
694 {"joinpath", oslib_joinpath
, -1, "."},
695 {"filesize", oslib_filesize
, 2, ".s"},
696 {"uname", oslib_uname
, 1, NULL
},
697 {"tempname", oslib_tempname
, -1, ".ss"},
701 VXInteger
voxstd_register_oslib(VXState
* v
)
703 VXTableObj
* tb
= v
->NewTable();
704 v
->RegisterLib("os", oslib_funcs
, true, tb
);
705 tb
->Set(v
->NewString("popen"), v
->RegClass(popen_funcs
));
706 #ifndef VX_NO_LOADLIB
707 oslib_register_libload(v
, tb
);