[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_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 \

View File

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

View File

@ -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

View File

@ -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),

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_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"

View File

@ -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)

View File

@ -84,6 +84,7 @@ typedef
STREAM_COMMON common;
int64_t size;
int fd;
unsigned watch : 1;
}
PACKED
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
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 <fcntl.h>
#include <unistd.h>
@ -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;
}