diff --git a/main/gbx/Makefile.am b/main/gbx/Makefile.am index 6e4713087..ea33e52cb 100644 --- a/main/gbx/Makefile.am +++ b/main/gbx/Makefile.am @@ -63,6 +63,7 @@ gbx3_SOURCES = \ gbx_c_gambas.h gbx_c_gambas.c \ gbx_c_file.h gbx_c_file.c \ gbx_c_application.h gbx_c_application.c \ + gbx_c_system.h gbx_c_system.c \ gbx_c_array.h gbx_c_array.c \ gbx_c_process.h gbx_c_process.c \ gbx_c_subcollection.h gbx_c_subcollection.c \ @@ -84,6 +85,7 @@ gb_la_SOURCES = \ gbx_c_gambas.h gbx_c_gambas.c \ gbx_c_file.h gbx_c_file.c \ gbx_c_application.h gbx_c_application.c \ + gbx_c_system.h gbx_c_system.c \ gbx_c_array.h gbx_c_array.c \ gbx_c_process.h gbx_c_process.c \ gbx_c_string.h gbx_c_string.c \ diff --git a/main/gbx/gbx_c_application.c b/main/gbx/gbx_c_application.c index adc23c624..38dcbfedd 100644 --- a/main/gbx/gbx_c_application.c +++ b/main/gbx/gbx_c_application.c @@ -50,8 +50,6 @@ #include "gbx_c_application.h" -//static GB_FUNCTION signal_func; -//static bool has_signal_func; static bool _daemon = FALSE; extern char **environ; @@ -89,39 +87,6 @@ BEGIN_PROPERTY(Application_Path) END_PROPERTY -BEGIN_PROPERTY(User_Home) - - GB_ReturnString(PROJECT_get_home()); - -END_PROPERTY - - -BEGIN_PROPERTY(User_Name) - - struct passwd *info = getpwuid(getuid()); - - if (info) - GB_ReturnNewZeroString(info->pw_name); - else - GB_Error((char *)E_MEMORY); - -END_PROPERTY - - -BEGIN_PROPERTY(User_Id) - - GB_ReturnInteger(getuid()); - -END_PROPERTY - - -BEGIN_PROPERTY(User_Group) - - GB_ReturnInteger(getgid()); - -END_PROPERTY - - BEGIN_PROPERTY(Application_Name) GB_ReturnConstZeroString(PROJECT_name); @@ -157,16 +122,6 @@ BEGIN_PROPERTY(Application_Version) END_PROPERTY -BEGIN_PROPERTY(CAPPLICATION_args) - - static OBJECT args; - - args.class = CLASS_AppArgs; - GB_ReturnObject(&args); - -END_PROPERTY - - BEGIN_PROPERTY(Application_Args_Count) GB_ReturnInt(PROJECT_argc); @@ -291,107 +246,6 @@ BEGIN_PROPERTY(Application_Startup) END_PROPERTY - -BEGIN_PROPERTY(System_Language) - - if (READ_PROPERTY) - GB_ReturnNewZeroString(LOCAL_get_lang()); - else - LOCAL_set_lang(GB_ToZeroString(PROP(GB_STRING))); - -END_PROPERTY - - -BEGIN_PROPERTY(System_FirstDayOfWeek) - - if (READ_PROPERTY) - GB_ReturnInteger(LOCAL_get_first_day_of_week()); - else - LOCAL_set_first_day_of_week(VPROP(GB_INTEGER)); - -END_PROPERTY - - -BEGIN_PROPERTY(System_Charset) - - GB_ReturnString(LOCAL_encoding); - -END_PROPERTY - - -BEGIN_PROPERTY(System_Rtl) - - GB_ReturnBoolean(LOCAL_local.rtl); - -END_PROPERTY - - -BEGIN_PROPERTY(System_Path) - - GB_ReturnString(PROJECT_exec_path); - -END_PROPERTY - - -BEGIN_PROPERTY(System_Host) - - char buffer[256]; - - gethostname(buffer, 255); - GB_ReturnNewZeroString(buffer); - -END_PROPERTY - - -BEGIN_PROPERTY(System_Domain) - - char buffer[256]; - - if (getdomainname(buffer, 255)) - GB_Error("Unable to retrieve domain name: &1", strerror(errno)); - else - GB_ReturnNewZeroString(buffer); - -END_PROPERTY - - -BEGIN_PROPERTY(System_ByteOrder) - - GB_ReturnInteger(EXEC_big_endian); - -END_PROPERTY - - -BEGIN_PROPERTY(System_Backtrace) - - STACK_BACKTRACE *bt = STACK_get_backtrace(); - - GB_ReturnObject(DEBUG_get_string_array_from_backtrace(bt)); - STACK_free_backtrace(&bt); - -END_PROPERTY - - -BEGIN_PROPERTY(System_Error) - - GB_ReturnInteger(errno); - -END_PROPERTY - - -BEGIN_METHOD(System_GetExternSymbol, GB_STRING library; GB_STRING name) - - char *library = GB_ToZeroString(ARG(library)); - char *name = GB_ToZeroString(ARG(name)); - void *ptr = NULL; - - if (*library && *name) - ptr = EXTERN_get_symbol(library, name); - - GB_ReturnPointer(ptr); - -END_METHOD - #endif GB_DESC NATIVE_AppArgs[] = @@ -438,43 +292,3 @@ GB_DESC NATIVE_App[] = GB_END_DECLARE }; -GB_DESC NATIVE_System[] = -{ - GB_DECLARE("System", 0), GB_VIRTUAL_CLASS(), - - GB_STATIC_PROPERTY_READ("Path", "s", System_Path), - GB_CONSTANT("Version", "s", GAMBAS_VERSION_STRING), - GB_CONSTANT("FullVersion", "s", GAMBAS_FULL_VERSION_STRING), - GB_STATIC_PROPERTY_READ("Backtrace", "String[]", System_Backtrace), - - GB_STATIC_PROPERTY("Language", "s", System_Language), - GB_STATIC_PROPERTY("FirstDayOfWeek", "i", System_FirstDayOfWeek), - GB_STATIC_PROPERTY_READ("RightToLeft", "b", System_Rtl), - GB_STATIC_PROPERTY_READ("Charset", "s", System_Charset), - GB_STATIC_PROPERTY_READ("Host", "s", System_Host), - GB_STATIC_PROPERTY_READ("Domain", "s", System_Domain), - GB_STATIC_PROPERTY_READ("ByteOrder", "i", System_ByteOrder), - GB_STATIC_PROPERTY_READ("Error", "i", System_Error), - - GB_CONSTANT("Family", "s", SYSTEM), - GB_CONSTANT("Architecture", "s", ARCHITECTURE), - - GB_STATIC_METHOD("GetExternSymbol", "p", System_GetExternSymbol, "(Library)s(Symbol)s"), - - GB_STATIC_PROPERTY_SELF("User", "User"), - - GB_END_DECLARE -}; - -GB_DESC NATIVE_User[] = -{ - GB_DECLARE("User", 0), GB_VIRTUAL_CLASS(), - - GB_STATIC_PROPERTY_READ("Name", "s", User_Name), - GB_STATIC_PROPERTY_READ("Id", "i", User_Id), - GB_STATIC_PROPERTY_READ("Group", "i", User_Group), - GB_STATIC_PROPERTY_READ("Home", "s", User_Home), - - GB_END_DECLARE -}; - diff --git a/main/gbx/gbx_c_application.h b/main/gbx/gbx_c_application.h index a30c453e0..b882af36b 100644 --- a/main/gbx/gbx_c_application.h +++ b/main/gbx/gbx_c_application.h @@ -30,11 +30,6 @@ extern GB_DESC NATIVE_AppEnv[]; extern GB_DESC NATIVE_AppArgs[]; extern GB_DESC NATIVE_App[]; -extern GB_DESC NATIVE_System[]; -extern GB_DESC NATIVE_User[]; #endif -//void CAPP_init(void); -//void CAPP_got_signal(void); - #endif diff --git a/main/gbx/gbx_c_gambas.c b/main/gbx/gbx_c_gambas.c index 4cd238836..6f6bd64e9 100644 --- a/main/gbx/gbx_c_gambas.c +++ b/main/gbx/gbx_c_gambas.c @@ -139,8 +139,8 @@ GB_DESC NATIVE_Gambas[] = GB_CONSTANT("Binary", "i", GB_COMP_BINARY), GB_CONSTANT("IgnoreCase", "i", GB_COMP_NOCASE), GB_CONSTANT("Language", "i", GB_COMP_LANG), - GB_CONSTANT("Like","i",GB_COMP_LIKE), - GB_CONSTANT("Natural","i",GB_COMP_NATURAL), + GB_CONSTANT("Like", "i", GB_COMP_LIKE), + GB_CONSTANT("Natural", "i", GB_COMP_NATURAL), GB_CONSTANT("Ascent", "i", GB_COMP_ASCENT), GB_CONSTANT("Descent", "i", GB_COMP_DESCENT), @@ -195,10 +195,6 @@ GB_DESC NATIVE_Gambas[] = GB_CONSTANT("Write", "i", W_OK), GB_CONSTANT("Exec", "i", X_OK), - //GB_CONSTANT("User", "i", GB_STAT_USER), - //GB_CONSTANT("Group", "i", GB_STAT_GROUP), - //GB_CONSTANT("Other", "i", GB_STAT_OTHER), - GB_CONSTANT("Sunday", "i", 0), GB_CONSTANT("Monday", "i", 1), GB_CONSTANT("Tuesday", "i", 2), diff --git a/main/gbx/gbx_c_system.c b/main/gbx/gbx_c_system.c new file mode 100644 index 000000000..e5e6a76a6 --- /dev/null +++ b/main/gbx/gbx_c_system.c @@ -0,0 +1,224 @@ +/*************************************************************************** + + gbx_c_system.c + + (c) 2000-2011 Benoît Minisini + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +***************************************************************************/ + +#define __GBX_C_SYSTEM_C + +#include "gambas.h" +#include "gbx_info.h" + +#ifndef GBX_INFO + +#include "config.h" + +#include +#include +#include + +#include "gb_common.h" +#include "gb_error.h" +#include "gbx_api.h" +#include "gbx_class.h" +#include "gbx_project.h" +#include "gbx_local.h" +#include "gbx_event.h" +#include "gbx_string.h" +#include "gbx_exec.h" +#include "gbx_extern.h" +#include "gbx_object.h" + +#include "gbx_c_system.h" + +BEGIN_PROPERTY(User_Home) + + GB_ReturnString(PROJECT_get_home()); + +END_PROPERTY + + +BEGIN_PROPERTY(User_Name) + + struct passwd *info = getpwuid(getuid()); + + if (info) + GB_ReturnNewZeroString(info->pw_name); + else + GB_Error((char *)E_MEMORY); + +END_PROPERTY + + +BEGIN_PROPERTY(User_Id) + + GB_ReturnInteger(getuid()); + +END_PROPERTY + + +BEGIN_PROPERTY(User_Group) + + GB_ReturnInteger(getgid()); + +END_PROPERTY + + +BEGIN_PROPERTY(System_Language) + + if (READ_PROPERTY) + GB_ReturnNewZeroString(LOCAL_get_lang()); + else + LOCAL_set_lang(GB_ToZeroString(PROP(GB_STRING))); + +END_PROPERTY + + +BEGIN_PROPERTY(System_FirstDayOfWeek) + + if (READ_PROPERTY) + GB_ReturnInteger(LOCAL_get_first_day_of_week()); + else + LOCAL_set_first_day_of_week(VPROP(GB_INTEGER)); + +END_PROPERTY + + +BEGIN_PROPERTY(System_Charset) + + GB_ReturnString(LOCAL_encoding); + +END_PROPERTY + + +BEGIN_PROPERTY(System_RightToLeft) + + GB_ReturnBoolean(LOCAL_local.rtl); + +END_PROPERTY + + +BEGIN_PROPERTY(System_Path) + + GB_ReturnString(PROJECT_exec_path); + +END_PROPERTY + + +BEGIN_PROPERTY(System_Host) + + char buffer[256]; + + gethostname(buffer, 255); + GB_ReturnNewZeroString(buffer); + +END_PROPERTY + + +BEGIN_PROPERTY(System_Domain) + + char buffer[256]; + + if (getdomainname(buffer, 255)) + GB_Error("Unable to retrieve domain name: &1", strerror(errno)); + else + GB_ReturnNewZeroString(buffer); + +END_PROPERTY + + +BEGIN_PROPERTY(System_ByteOrder) + + GB_ReturnInteger(EXEC_big_endian); + +END_PROPERTY + + +BEGIN_PROPERTY(System_Backtrace) + + STACK_BACKTRACE *bt = STACK_get_backtrace(); + + GB_ReturnObject(DEBUG_get_string_array_from_backtrace(bt)); + STACK_free_backtrace(&bt); + +END_PROPERTY + + +BEGIN_PROPERTY(System_Error) + + GB_ReturnInteger(errno); + +END_PROPERTY + + +BEGIN_METHOD(System_GetExternSymbol, GB_STRING library; GB_STRING name) + + char *library = GB_ToZeroString(ARG(library)); + char *name = GB_ToZeroString(ARG(name)); + void *ptr = NULL; + + if (*library && *name) + ptr = EXTERN_get_symbol(library, name); + + GB_ReturnPointer(ptr); + +END_METHOD + +#endif + +GB_DESC NATIVE_User[] = +{ + GB_DECLARE("User", 0), GB_VIRTUAL_CLASS(), + + GB_STATIC_PROPERTY_READ("Name", "s", User_Name), + GB_STATIC_PROPERTY_READ("Id", "i", User_Id), + GB_STATIC_PROPERTY_READ("Group", "i", User_Group), + GB_STATIC_PROPERTY_READ("Home", "s", User_Home), + + GB_END_DECLARE +}; + +GB_DESC NATIVE_System[] = +{ + GB_DECLARE("System", 0), GB_VIRTUAL_CLASS(), + + GB_STATIC_PROPERTY_READ("Path", "s", System_Path), + GB_CONSTANT("Version", "s", GAMBAS_VERSION_STRING), + GB_CONSTANT("FullVersion", "s", GAMBAS_FULL_VERSION_STRING), + GB_STATIC_PROPERTY_READ("Backtrace", "String[]", System_Backtrace), + + GB_STATIC_PROPERTY("Language", "s", System_Language), + GB_STATIC_PROPERTY("FirstDayOfWeek", "i", System_FirstDayOfWeek), + GB_STATIC_PROPERTY_READ("RightToLeft", "b", System_RightToLeft), + GB_STATIC_PROPERTY_READ("Charset", "s", System_Charset), + GB_STATIC_PROPERTY_READ("Host", "s", System_Host), + GB_STATIC_PROPERTY_READ("Domain", "s", System_Domain), + GB_STATIC_PROPERTY_READ("ByteOrder", "i", System_ByteOrder), + GB_STATIC_PROPERTY_READ("Error", "i", System_Error), + + GB_CONSTANT("Family", "s", SYSTEM), + GB_CONSTANT("Architecture", "s", ARCHITECTURE), + + GB_STATIC_METHOD("GetExternSymbol", "p", System_GetExternSymbol, "(Library)s(Symbol)s"), + + GB_STATIC_PROPERTY_SELF("User", "User"), + + GB_END_DECLARE +}; diff --git a/main/gbx/gbx_c_system.h b/main/gbx/gbx_c_system.h new file mode 100644 index 000000000..10d77ae49 --- /dev/null +++ b/main/gbx/gbx_c_system.h @@ -0,0 +1,34 @@ +/*************************************************************************** + + gbx_c_system.h + + (c) 2000-2011 Benoît Minisini + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +***************************************************************************/ + +#ifndef __GBX_C_SYSTEM_H +#define __GBX_C_SYSTEM_H + +#include "gambas.h" + +#ifndef __GBX_C_SYSTEM_C +extern GB_DESC NATIVE_User[]; +extern GB_DESC NATIVE_System[]; +#endif + +#endif diff --git a/main/gbx/gbx_class_init.c b/main/gbx/gbx_class_init.c index 85792a78a..db8ccc270 100644 --- a/main/gbx/gbx_class_init.c +++ b/main/gbx/gbx_class_init.c @@ -36,6 +36,7 @@ #include "gbx_c_error.h" #include "gbx_c_collection.h" #include "gbx_c_file.h" +#include "gbx_c_system.h" #include "gbx_c_application.h" #include "gbx_c_array.h" #include "gbx_c_process.h" diff --git a/main/gbx/gbx_stream.c b/main/gbx/gbx_stream.c index e8a9e0027..b62a092ba 100644 --- a/main/gbx/gbx_stream.c +++ b/main/gbx/gbx_stream.c @@ -173,10 +173,12 @@ void STREAM_open(STREAM *stream, const char *path, int mode) } else { - if (FILE_is_relative(path)) + // ".99" is used for opening a file descriptor in direct mode + + if (FILE_is_relative(path) && !((mode & ST_DIRECT) && isdigit(path[1]))) { ARCHIVE *arch = NULL; - + if (strncmp(path, "../", 3)) ARCHIVE_get_current(&arch); else if (!EXEC_arch) diff --git a/main/gbx/gbx_stream.h b/main/gbx/gbx_stream.h index 5a11ecff7..ba7228986 100644 --- a/main/gbx/gbx_stream.h +++ b/main/gbx/gbx_stream.h @@ -84,6 +84,7 @@ typedef STREAM_COMMON common; int64_t size; int fd; + unsigned watch : 1; } PACKED STREAM_DIRECT; diff --git a/main/gbx/gbx_stream_direct.c b/main/gbx/gbx_stream_direct.c index ee4ae3f94..29d59eafd 100644 --- a/main/gbx/gbx_stream_direct.c +++ b/main/gbx/gbx_stream_direct.c @@ -1,22 +1,22 @@ /*************************************************************************** - gbx_stream_direct.c + gbx_stream_direct.c - (c) 2000-2011 Benoît Minisini + (c) 2000-2011 Benoît Minisini - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ @@ -27,6 +27,7 @@ #include "gb_error.h" #include "gbx_value.h" #include "gb_limit.h" +#include "gbx_number.h" #include #include @@ -43,58 +44,78 @@ static int stream_open(STREAM *stream, const char *path, int mode) { - int fd; - struct stat info; - int fmode; + int fd; + struct stat info; + int fmode; - if (mode & ST_CREATE) - fmode = O_CREAT | O_TRUNC; - else if (mode & ST_APPEND) - fmode = O_APPEND | O_CREAT; - else - fmode = 0; + if (mode & ST_CREATE) + fmode = O_CREAT | O_TRUNC; + else if (mode & ST_APPEND) + fmode = O_APPEND | O_CREAT; + else + fmode = 0; - switch (mode & ST_MODE) - { - case ST_READ: fmode |= O_RDONLY; break; - case ST_WRITE: fmode |= O_WRONLY; break; - case ST_READ_WRITE: fmode |= O_RDWR; break; - default: fmode |= O_RDONLY; - } - - fd = open(path, fmode, 0666); - if (fd < 0) - return TRUE; - - if (fstat(fd, &info) < 0) - return TRUE; - - if (S_ISDIR(info.st_mode)) - { - errno = EISDIR; - return TRUE; - } - - if (!S_ISREG(info.st_mode)) + switch (mode & ST_MODE) { - stream->common.available_now = FALSE; - fcntl(fd, F_SETFL, O_NONBLOCK); + case ST_READ: fmode |= O_RDONLY; break; + case ST_WRITE: fmode |= O_WRONLY; break; + case ST_READ_WRITE: fmode |= O_RDWR; break; + default: fmode |= O_RDONLY; + } + + if (path[0] == '.' && isdigit(path[1])) + { + VALUE val; + if (NUMBER_from_string(NB_READ_INTEGER, &path[1], strlen(path) - 1, &val) || val._integer.value < 0) + { + errno = ENOENT; + return TRUE; + } + + fd = val._integer.value; + stream->direct.watch = TRUE; } else - stream->common.available_now = TRUE; + { + stream->direct.watch = FALSE; + + fd = open(path, fmode, 0666); + if (fd < 0) + return TRUE; - FD = fd; - return FALSE; + if (fstat(fd, &info) < 0) + return TRUE; + + if (S_ISDIR(info.st_mode)) + { + errno = EISDIR; + return TRUE; + } + + if (!S_ISREG(info.st_mode)) + { + stream->common.available_now = FALSE; + fcntl(fd, F_SETFL, O_NONBLOCK); + } + else + stream->common.available_now = TRUE; + } + + FD = fd; + return FALSE; } static int stream_close(STREAM *stream) { - if (close(FD) < 0) - return TRUE; + if (!stream->direct.watch) + { + if (close(FD) < 0) + return TRUE; + } - FD = -1; - return FALSE; + FD = -1; + return FALSE; } @@ -117,32 +138,23 @@ static int stream_write(STREAM *stream, char *buffer, int len) static int stream_seek(STREAM *stream, int64_t pos, int whence) { - return (lseek(FD, pos, whence) < 0); + return (lseek(FD, pos, whence) < 0); } static int stream_tell(STREAM *stream, int64_t *pos) { - *pos = lseek(FD, 0, SEEK_CUR); - return (*pos < 0); + *pos = lseek(FD, 0, SEEK_CUR); + return (*pos < 0); } static int stream_flush(STREAM *stream) { - return FALSE; + return FALSE; } -/*static int stream_eof(STREAM *stream) -{ - int ilen; - - if (STREAM_get_readable(FD, &ilen)) - return TRUE; - - return (ilen == 0); -}*/ #define stream_eof NULL @@ -157,12 +169,13 @@ static int stream_lof(STREAM *stream, int64_t *len) return TRUE; *len = info.st_size; - return FALSE; + return FALSE; } + static int stream_handle(STREAM *stream) { - return FD; + return FD; }