[INTERPRETER]

* NEW: Split System and Application class implementation in tow different
  source files.
* NEW: A trick to watch existing file descriptors: opening ".XX" in direct
  mode, where "XX" is the file descritor value.


git-svn-id: svn://localhost/gambas/trunk@4132 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2011-09-18 15:21:11 +00:00
parent f315e8e717
commit 3b5b881d5e
10 changed files with 349 additions and 267 deletions

View File

@ -63,6 +63,7 @@ gbx3_SOURCES = \
gbx_c_gambas.h gbx_c_gambas.c \ gbx_c_gambas.h gbx_c_gambas.c \
gbx_c_file.h gbx_c_file.c \ gbx_c_file.h gbx_c_file.c \
gbx_c_application.h gbx_c_application.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_array.h gbx_c_array.c \
gbx_c_process.h gbx_c_process.c \ gbx_c_process.h gbx_c_process.c \
gbx_c_subcollection.h gbx_c_subcollection.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_gambas.h gbx_c_gambas.c \
gbx_c_file.h gbx_c_file.c \ gbx_c_file.h gbx_c_file.c \
gbx_c_application.h gbx_c_application.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_array.h gbx_c_array.c \
gbx_c_process.h gbx_c_process.c \ gbx_c_process.h gbx_c_process.c \
gbx_c_string.h gbx_c_string.c \ gbx_c_string.h gbx_c_string.c \

View File

@ -50,8 +50,6 @@
#include "gbx_c_application.h" #include "gbx_c_application.h"
//static GB_FUNCTION signal_func;
//static bool has_signal_func;
static bool _daemon = FALSE; static bool _daemon = FALSE;
extern char **environ; extern char **environ;
@ -89,39 +87,6 @@ BEGIN_PROPERTY(Application_Path)
END_PROPERTY 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) BEGIN_PROPERTY(Application_Name)
GB_ReturnConstZeroString(PROJECT_name); GB_ReturnConstZeroString(PROJECT_name);
@ -157,16 +122,6 @@ BEGIN_PROPERTY(Application_Version)
END_PROPERTY END_PROPERTY
BEGIN_PROPERTY(CAPPLICATION_args)
static OBJECT args;
args.class = CLASS_AppArgs;
GB_ReturnObject(&args);
END_PROPERTY
BEGIN_PROPERTY(Application_Args_Count) BEGIN_PROPERTY(Application_Args_Count)
GB_ReturnInt(PROJECT_argc); GB_ReturnInt(PROJECT_argc);
@ -291,107 +246,6 @@ BEGIN_PROPERTY(Application_Startup)
END_PROPERTY 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 #endif
GB_DESC NATIVE_AppArgs[] = GB_DESC NATIVE_AppArgs[] =
@ -438,43 +292,3 @@ GB_DESC NATIVE_App[] =
GB_END_DECLARE 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
};

View File

@ -30,11 +30,6 @@
extern GB_DESC NATIVE_AppEnv[]; extern GB_DESC NATIVE_AppEnv[];
extern GB_DESC NATIVE_AppArgs[]; extern GB_DESC NATIVE_AppArgs[];
extern GB_DESC NATIVE_App[]; extern GB_DESC NATIVE_App[];
extern GB_DESC NATIVE_System[];
extern GB_DESC NATIVE_User[];
#endif #endif
//void CAPP_init(void);
//void CAPP_got_signal(void);
#endif #endif

View File

@ -139,8 +139,8 @@ GB_DESC NATIVE_Gambas[] =
GB_CONSTANT("Binary", "i", GB_COMP_BINARY), GB_CONSTANT("Binary", "i", GB_COMP_BINARY),
GB_CONSTANT("IgnoreCase", "i", GB_COMP_NOCASE), GB_CONSTANT("IgnoreCase", "i", GB_COMP_NOCASE),
GB_CONSTANT("Language", "i", GB_COMP_LANG), GB_CONSTANT("Language", "i", GB_COMP_LANG),
GB_CONSTANT("Like","i",GB_COMP_LIKE), GB_CONSTANT("Like", "i", GB_COMP_LIKE),
GB_CONSTANT("Natural","i",GB_COMP_NATURAL), GB_CONSTANT("Natural", "i", GB_COMP_NATURAL),
GB_CONSTANT("Ascent", "i", GB_COMP_ASCENT), GB_CONSTANT("Ascent", "i", GB_COMP_ASCENT),
GB_CONSTANT("Descent", "i", GB_COMP_DESCENT), GB_CONSTANT("Descent", "i", GB_COMP_DESCENT),
@ -195,10 +195,6 @@ GB_DESC NATIVE_Gambas[] =
GB_CONSTANT("Write", "i", W_OK), GB_CONSTANT("Write", "i", W_OK),
GB_CONSTANT("Exec", "i", X_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("Sunday", "i", 0),
GB_CONSTANT("Monday", "i", 1), GB_CONSTANT("Monday", "i", 1),
GB_CONSTANT("Tuesday", "i", 2), GB_CONSTANT("Tuesday", "i", 2),

224
main/gbx/gbx_c_system.c Normal file
View File

@ -0,0 +1,224 @@
/***************************************************************************
gbx_c_system.c
(c) 2000-2011 Benoît Minisini <gambas@users.sourceforge.net>
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 <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#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
};

34
main/gbx/gbx_c_system.h Normal file
View File

@ -0,0 +1,34 @@
/***************************************************************************
gbx_c_system.h
(c) 2000-2011 Benoît Minisini <gambas@users.sourceforge.net>
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

View File

@ -36,6 +36,7 @@
#include "gbx_c_error.h" #include "gbx_c_error.h"
#include "gbx_c_collection.h" #include "gbx_c_collection.h"
#include "gbx_c_file.h" #include "gbx_c_file.h"
#include "gbx_c_system.h"
#include "gbx_c_application.h" #include "gbx_c_application.h"
#include "gbx_c_array.h" #include "gbx_c_array.h"
#include "gbx_c_process.h" #include "gbx_c_process.h"

View File

@ -173,7 +173,9 @@ void STREAM_open(STREAM *stream, const char *path, int mode)
} }
else 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; ARCHIVE *arch = NULL;

View File

@ -84,6 +84,7 @@ typedef
STREAM_COMMON common; STREAM_COMMON common;
int64_t size; int64_t size;
int fd; int fd;
unsigned watch : 1;
} }
PACKED PACKED
STREAM_DIRECT; STREAM_DIRECT;

View File

@ -1,22 +1,22 @@
/*************************************************************************** /***************************************************************************
gbx_stream_direct.c gbx_stream_direct.c
(c) 2000-2011 Benoît Minisini <gambas@users.sourceforge.net> (c) 2000-2011 Benoît Minisini <gambas@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. MA 02110-1301, USA.
***************************************************************************/ ***************************************************************************/
@ -27,6 +27,7 @@
#include "gb_error.h" #include "gb_error.h"
#include "gbx_value.h" #include "gbx_value.h"
#include "gb_limit.h" #include "gb_limit.h"
#include "gbx_number.h"
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
@ -43,58 +44,78 @@
static int stream_open(STREAM *stream, const char *path, int mode) static int stream_open(STREAM *stream, const char *path, int mode)
{ {
int fd; int fd;
struct stat info; struct stat info;
int fmode; int fmode;
if (mode & ST_CREATE) if (mode & ST_CREATE)
fmode = O_CREAT | O_TRUNC; fmode = O_CREAT | O_TRUNC;
else if (mode & ST_APPEND) else if (mode & ST_APPEND)
fmode = O_APPEND | O_CREAT; fmode = O_APPEND | O_CREAT;
else else
fmode = 0; fmode = 0;
switch (mode & ST_MODE) 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))
{ {
stream->common.available_now = FALSE; case ST_READ: fmode |= O_RDONLY; break;
fcntl(fd, F_SETFL, O_NONBLOCK); 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 else
stream->common.available_now = TRUE; {
stream->direct.watch = FALSE;
FD = fd; fd = open(path, fmode, 0666);
return FALSE; 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))
{
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) static int stream_close(STREAM *stream)
{ {
if (close(FD) < 0) if (!stream->direct.watch)
return TRUE; {
if (close(FD) < 0)
return TRUE;
}
FD = -1; FD = -1;
return FALSE; 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) 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) static int stream_tell(STREAM *stream, int64_t *pos)
{ {
*pos = lseek(FD, 0, SEEK_CUR); *pos = lseek(FD, 0, SEEK_CUR);
return (*pos < 0); return (*pos < 0);
} }
static int stream_flush(STREAM *stream) 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 #define stream_eof NULL
@ -157,12 +169,13 @@ static int stream_lof(STREAM *stream, int64_t *len)
return TRUE; return TRUE;
*len = info.st_size; *len = info.st_size;
return FALSE; return FALSE;
} }
static int stream_handle(STREAM *stream) static int stream_handle(STREAM *stream)
{ {
return FD; return FD;
} }