⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbx_c_file.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
字号:
/***************************************************************************  CFile.c  The native File class  (c) 2000-2004 Beno顃 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __GBX_C_FILE_C#include <stdio.h>#include <pwd.h>#include <grp.h>#include <sys/stat.h>#include "gb_common.h"#include "gbx_api.h"#include "gambas.h"#include "gbx_class.h"#include "gb_file.h"#include "gbx_stream.h"#include "gbx_exec.h"#include "gbx_string.h"#include "gbx_date.h"#include "gbx_c_file.h"PUBLIC CFILE CFILE_in, CFILE_out, CFILE_err;DECLARE_EVENT(EVENT_Read);DECLARE_EVENT(EVENT_Write);static char _buffer[16];PRIVATE void init(CFILE *_object, FILE *file){  THIS->ob.ob.class = CLASS_File;  THIS->ob.ob.ref = 1;  THIS->ob.stream.type = &STREAM_buffer;  THIS->ob.stream.buffer.file = file;  THIS->ob.stream.buffer.size = 0;}PUBLIC void CFILE_init(void){  init(&CFILE_in, stdin);  init(&CFILE_out, stdout);  init(&CFILE_err, stderr);}PRIVATE void callback_read(int fd, int type, CFILE *file){  GB_Raise(file, EVENT_Read, 0);}PRIVATE void callback_write(int fd, int type, CFILE *file){  GB_Raise(file, EVENT_Write, 0);}PUBLIC CFILE *CFILE_create(STREAM *stream, int mode){  int fd;  CFILE *file;  OBJECT_new((void **)&file, CLASS_File, NULL, NULL);  OBJECT_UNREF_KEEP((void **)&file, "CFILE_new");  if (stream)  {    *CSTREAM_stream(file) = *stream;    file->watch_fd = -1;    if (mode & ST_WATCH)    {      fd = STREAM_handle(&file->ob.stream);      file->watch_fd = fd;      if (mode & ST_READ)        GB_Watch(fd, GB_WATCH_READ, (void *)callback_read, (long)file);      if (mode & ST_WRITE)        GB_Watch(fd, GB_WATCH_WRITE, (void *)callback_write, (long)file);      OBJECT_attach((OBJECT *)file, OP ? (OBJECT *)OP : (OBJECT *)CP, "File");    }  }  return file;}BEGIN_METHOD_VOID(CFILE_free)  STREAM_close(&THIS->ob.stream);  if (THIS->watch_fd >= 0)    GB_Watch(THIS->watch_fd, GB_WATCH_NONE, NULL, 0);END_METHODBEGIN_PROPERTY(CFILE_get_in)  GB_ReturnObject(&CFILE_in);END_PROPERTYBEGIN_PROPERTY(CFILE_get_out)  GB_ReturnObject(&CFILE_out);END_PROPERTYBEGIN_PROPERTY(CFILE_get_err)  GB_ReturnObject(&CFILE_err);END_PROPERTYBEGIN_PROPERTY(CFILE_type)  GB_ReturnInt(THIS->info.type);END_PROPERTYBEGIN_PROPERTY(CFILE_mode)  GB_ReturnInt(THIS->info.mode);END_PROPERTYBEGIN_PROPERTY(CFILE_hidden)  GB_ReturnBoolean(THIS->info.hidden);END_PROPERTYBEGIN_PROPERTY(CFILE_size)  GB_ReturnInt(THIS->info.size);END_PROPERTYBEGIN_PROPERTY(CFILE_atime)  GB_DATE date;  DATE_from_time(THIS->info.atime, 0, (VALUE *)&date);  GB_ReturnDate(&date);END_PROPERTYBEGIN_PROPERTY(CFILE_ctime)  GB_DATE date;  DATE_from_time(THIS->info.ctime, 0, (VALUE *)&date);  GB_ReturnDate(&date);END_PROPERTYBEGIN_PROPERTY(CFILE_mtime)  GB_DATE date;  DATE_from_time(THIS->info.mtime, 0, (VALUE *)&date);  GB_ReturnDate(&date);END_PROPERTYstatic char *get_file_user(CFILE *_object){  struct passwd *pwd;  uid_t uid = THIS->info.uid;  if (uid == 0)    return "root";  else  {    pwd = getpwuid(uid);    if (!pwd)    {      sprintf(_buffer, "%d", uid);      return _buffer;    }    else      return pwd->pw_name;  }}BEGIN_PROPERTY(CFILE_user)  GB_ReturnNewZeroString(get_file_user(THIS));END_PROPERTYstatic char *get_file_group(CFILE *_object){  struct group *grp;  gid_t gid = THIS->info.gid;  if (gid == 0)    return "root";  else  {    grp = getgrgid(gid);    if (!grp)    {      sprintf(_buffer, "%d", gid);      return _buffer;    }    else      return grp->gr_name;  }}BEGIN_PROPERTY(CFILE_group)  GB_ReturnNewZeroString(get_file_group(THIS));END_PROPERTYBEGIN_PROPERTY(CFILE_setuid)  GB_ReturnBoolean(THIS->info.mode & S_ISUID);END_PROPERTYBEGIN_PROPERTY(CFILE_setgid)  GB_ReturnBoolean(THIS->info.mode & S_ISGID);END_PROPERTYBEGIN_PROPERTY(CFILE_sticky)  GB_ReturnBoolean(THIS->info.mode & S_ISVTX);END_PROPERTY#if 0BEGIN_METHOD(CFILE_access, GB_INTEGER who; GB_INTEGER access)  bool ret;  int access = VARGOPT(access, GB_STAT_READ);  int who = VARG(who);  int mode = THIS->info.mode;  if ((access & GB_STAT_READ) == 0)    mode &= ~(S_IRUSR | S_IRGRP | S_IROTH);  if ((access & GB_STAT_WRITE) == 0)    mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);  if ((access & GB_STAT_EXEC) == 0)    mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);  switch(who)  {    case GB_STAT_USER: ret = mode & S_IRWXU; break;    case GB_STAT_GROUP: ret = mode & S_IRWXG; break;    case GB_STAT_OTHER: ret = mode & S_IRWXO; break;    default: ret = FALSE; break;  }  GB_ReturnBoolean(ret);END_METHOD#endifstatic void return_perm(CFILE *_object, int rf, int wf, int xf){  char perm[4];  char *p;  int mode = THIS->info.mode;    p = perm;    if (mode & rf) *p++ = 'r';  if (mode & wf) *p++ = 'w';  if (mode & xf) *p++ = 'x';    *p = 0;  GB_ReturnNewZeroString(perm);}BEGIN_PROPERTY(CFILE_perm_user)  return_perm(THIS, S_IRUSR, S_IWUSR, S_IXUSR);END_PROPERTYBEGIN_PROPERTY(CFILE_perm_group)  return_perm(THIS, S_IRGRP, S_IWGRP, S_IXGRP);END_PROPERTYBEGIN_PROPERTY(CFILE_perm_other)  return_perm(THIS, S_IROTH, S_IWOTH, S_IXOTH);END_PROPERTYBEGIN_METHOD(CFILE_perm_get, GB_STRING user)  char *who;  char *user = GB_ToZeroString(ARG(user));    who = get_file_user(THIS);  if (strcmp(user, who) == 0)  {    return_perm(THIS, S_IRUSR, S_IWUSR, S_IWUSR);    return;  }  who = get_file_group(THIS);  if (strlen(user) > 2 && user[0] == '*' && user[1] == '.' && strcmp(&user[2], who) == 0)  {    return_perm(THIS, S_IRGRP, S_IWGRP, S_IWGRP);    return;  }  return_perm(THIS, S_IROTH, S_IWOTH, S_IWOTH);END_METHODBEGIN_PROPERTY(CFILE_separator)  GB_ReturnConstZeroString("/");END_PROPERTYBEGIN_METHOD(CFILE_dir, GB_STRING path)  const char *path = GB_ToZeroString(ARG(path));  if (path)    GB_ReturnNewZeroString(FILE_get_dir(path));  else    GB_ReturnNull();/*  char *path = PARAM(path).addr;  int len = PARAM(path).len;  if (len == 0)  {    GB_ReturnNull();    return;  }  if (len == 1)  {    if (*path == '/')      GB_ReturnCopyString(path, len);    else      GB_ReturnNull();    return;  }  for(;;)  {    len--;    if ((len == 0) || (path[len] == '/'))    {      GB_ReturnCopyString(path, len);      return;    }  }*/END_METHODBEGIN_METHOD(CFILE_name, GB_STRING path)  if (LENGTH(path) && STRING(path)[LENGTH(path) - 1] == '/')    LENGTH(path)--;  GB_ReturnNewString(FILE_get_name(GB_ToZeroString(ARG(path))), -1);END_METHODBEGIN_METHOD(CFILE_ext, GB_STRING path)  const char *path = GB_ToZeroString(ARG(path));  if (path)    GB_ReturnNewZeroString(FILE_get_ext(path));  else    GB_ReturnNull();END_METHODBEGIN_METHOD(CFILE_basename, GB_STRING path)  const char *path = GB_ToZeroString(ARG(path));  if (path)    GB_ReturnNewZeroString(FILE_get_basename(path));  else    GB_ReturnNull();END_METHODBEGIN_METHOD(CFILE_load, GB_STRING path)  STREAM stream;  long len;  char *str;  boolean opened = FALSE;  TRY  {    STREAM_open(&stream, STRING_conv_file_name(STRING(path), LENGTH(path)), ST_READ);    opened = TRUE;    STREAM_lof(&stream, &len);    STRING_new_temp(&str, NULL, len);    STREAM_read(&stream, str, len);    STREAM_close(&stream);    GB_ReturnString(str);  }  CATCH  {    if (opened)      STREAM_close(&stream);    PROPAGATE();  }  END_TRYEND_METHODBEGIN_METHOD(CFILE_save, GB_STRING path; GB_STRING data)  STREAM stream;  boolean opened = FALSE;  TRY  {    STREAM_open(&stream, STRING_conv_file_name(STRING(path), LENGTH(path)), ST_CREATE);    opened = TRUE;    STREAM_write(&stream, STRING(data), LENGTH(data));    STREAM_close(&stream);  }  CATCH  {    if (opened)      STREAM_close(&stream);    PROPAGATE();  }  END_TRYEND_METHODPUBLIC GB_DESC NATIVE_Stream[] ={  GB_DECLARE(".Stream", sizeof(CSTREAM)),  GB_NOT_CREATABLE(),  GB_END_DECLARE};PUBLIC GB_DESC NATIVE_FilePerm[] ={  GB_DECLARE(".FilePerm", 0),  GB_VIRTUAL_CLASS(),  GB_METHOD("_get", "s", CFILE_perm_get, "(UserOrGroup)s"),  GB_PROPERTY_READ("User", "s", CFILE_perm_user),  GB_PROPERTY_READ("Group", "s", CFILE_perm_group),  GB_PROPERTY_READ("Other", "s", CFILE_perm_other),  GB_END_DECLARE};PUBLIC GB_DESC NATIVE_File[] ={  GB_DECLARE("File", sizeof(CFILE)),  GB_INHERITS(".Stream"),  GB_NOT_CREATABLE(),  GB_METHOD("_free", NULL, CFILE_free, NULL),  GB_STATIC_PROPERTY_READ("Separator", "s", CFILE_separator),  GB_STATIC_PROPERTY_READ("In", "File", CFILE_get_in),  GB_STATIC_PROPERTY_READ("Out", "File", CFILE_get_out),  GB_STATIC_PROPERTY_READ("Err", "File", CFILE_get_err),  GB_PROPERTY_READ("Type", "i", CFILE_type),  GB_PROPERTY_READ("Mode", "i", CFILE_mode),  GB_PROPERTY_READ("Hidden", "b", CFILE_hidden),  GB_PROPERTY_READ("Size", "i", CFILE_size),  GB_PROPERTY_READ("Time", "d", CFILE_mtime),  GB_PROPERTY_READ("LastAccess", "d", CFILE_atime),  GB_PROPERTY_READ("LastUpdate", "d", CFILE_mtime),  GB_PROPERTY_READ("LastChange", "d", CFILE_ctime),  GB_PROPERTY_READ("User", "s", CFILE_user),  GB_PROPERTY_READ("Group", "s", CFILE_group),  GB_PROPERTY_SELF("Perm", ".FilePerm"),  GB_PROPERTY_READ("SetGID", "b", CFILE_setgid),  GB_PROPERTY_READ("SetUID", "b", CFILE_setuid),  GB_PROPERTY_READ("Sticky", "b", CFILE_sticky),  //GB_METHOD("Access", "b", CFILE_access, "(Who)i[(Mode)i]"),  GB_STATIC_METHOD("Dir", "s", CFILE_dir, "(FileName)s"),  GB_STATIC_METHOD("Name", "s", CFILE_name, "(FileName)s"),  GB_STATIC_METHOD("Ext", "s", CFILE_ext, "(FileName)s"),  GB_STATIC_METHOD("BaseName", "s", CFILE_basename, "(FileName)s"),  GB_STATIC_METHOD("Load", "s", CFILE_load, "(FileName)s"),  GB_STATIC_METHOD("Save", NULL, CFILE_save, "(FileName)s(Data)s"),  GB_EVENT("Read", NULL, NULL, &EVENT_Read),  GB_EVENT("Write", NULL, NULL, &EVENT_Write),  GB_END_DECLARE};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -