📄 slposdir.c
字号:
/* file intrinsics for S-Lang *//* Copyright (c) 1992, 1999, 2001, 2002, 2003 John E. Davis * This file is part of the S-Lang library. * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */#include "slinclud.h"#if defined(__unix__) || (defined (__os2__) && defined (__EMX__))# include <sys/types.h>#endif#ifdef HAVE_IO_H# include <io.h> /* for chmod */#endif#if defined(__BORLANDC__)# include <process.h># include <dos.h>#endif#ifdef HAVE_FCNTL_H# include <fcntl.h>#endif#ifdef HAVE_SYS_FCNTL_H# include <sys/fcntl.h>#endif#ifdef __unix__# include <sys/file.h>#endif#if defined(__BORLANDC__)# include <dir.h>#endif#if defined(_MSC_VER)# include <io.h>#endif#if defined(__DECC) && defined(VMS)# include <unixio.h># include <unixlib.h>#endif#ifdef VMS# include <stat.h>#else# include <sys/stat.h>#endif#if defined(VMS)# define USE_LISTDIR_INTRINSIC 0#else# define USE_LISTDIR_INTRINSIC 1#endif#if USE_LISTDIR_INTRINSIC#if defined(__WIN32__)# include <windows.h>#else# if defined(__OS2__) && defined(__IBMC__)# define INCL_DOS# define INCL_ERRORS# include <os2.h># include <direct.h># include <ctype.h># else# ifdef HAVE_DIRENT_H# include <dirent.h># else# ifdef HAVE_DIRECT_H# include <direct.h># else# define dirent direct# define NEED_D_NAMLEN# if HAVE_SYS_NDIR_H# include <sys/ndir.h># endif# if HAVE_SYS_DIR_H# include <sys/dir.h># endif# if HAVE_NDIR_H# include <ndir.h># endif# endif# endif# endif#endif#endif /* USE_LISTDIR_INTRINSIC */#include <errno.h>#include "slang.h"#include "_slang.h"typedef struct{ struct stat st; int st_opt_attrs;}Stat_Type;static SLang_CStruct_Field_Type Stat_Struct [] ={ MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_dev, "st_dev", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_ino, "st_ino", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_mode, "st_mode", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_nlink, "st_nlink", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_uid, "st_uid", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_gid, "st_gid", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_rdev, "st_rdev", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_size, "st_size", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_atime, "st_atime", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_mtime, "st_mtime", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st.st_ctime, "st_ctime", 0), MAKE_CSTRUCT_INT_FIELD(Stat_Type, st_opt_attrs, "st_opt_attrs", 0), SLANG_END_CSTRUCT_TABLE};static int push_stat_struct (struct stat *st, int opt_attrs){ Stat_Type s; s.st = *st; s.st_opt_attrs = opt_attrs; return SLang_push_cstruct ((VOID_STAR) &s, Stat_Struct);}static void stat_cmd (char *file){ struct stat st; int status; int opt_attrs; status = stat (file, &st);#if defined(__MSDOS__) || defined(__WIN32__) if (status == -1) { unsigned int len = strlen (file); if (len && ((file[len-1] == '\\') || (file[len-1] == '/'))) { file = SLmake_nstring (file, len-1); if (file == NULL) return; status = stat (file, &st); SLfree (file); } }#endif if (status == -1) { _SLerrno_errno = errno; SLang_push_null (); return; }#ifdef __WIN32__ opt_attrs = GetFileAttributes (file);#else opt_attrs = 0;#endif push_stat_struct (&st, opt_attrs);}static void lstat_cmd (char *file){#ifdef HAVE_LSTAT struct stat st; int opt_attrs; if (-1 == lstat (file, &st)) { _SLerrno_errno = errno; SLang_push_null (); return; }#ifdef __WIN32__ opt_attrs = GetFileAttributes (file);#else opt_attrs = 0;#endif push_stat_struct (&st, opt_attrs);#else stat_cmd (file);#endif}/* Well, it appears that on some systems, these are not defined. Here I * provide them. These are derived from the Linux stat.h file. */#ifdef __os2__# ifdef __IBMC__/* IBM VA3 doesn't declare S_IFMT */# define S_IFMT (S_IFDIR | S_IFCHR | S_IFREG)# endif#endif#ifndef S_ISLNK# ifdef S_IFLNK# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)# else# define S_ISLNK(m) 0# endif#endif#ifndef S_ISREG# ifdef S_IFREG# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)# else# define S_ISREG(m) 0# endif#endif#ifndef S_ISDIR# ifdef S_IFDIR# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)# else# define S_ISDIR(m) 0# endif#endif#ifndef S_ISCHR# ifdef S_IFCHR# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)# else# define S_ISCHR(m) 0# endif#endif#ifndef S_ISBLK# ifdef S_IFBLK# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)# else# define S_ISBLK(m) 0# endif#endif#ifndef S_ISFIFO# ifdef S_IFIFO# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)# else# define S_ISFIFO(m) 0# endif#endif#ifndef S_ISSOCK# ifdef S_IFSOCK# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)# else# define S_ISSOCK(m) 0# endif#endifstatic char stat_is_cmd (char *what, int *mode_ptr){ int ret; int st_mode = *mode_ptr; if (!strcmp (what, "sock")) ret = S_ISSOCK(st_mode); else if (!strcmp (what, "fifo")) ret = S_ISFIFO(st_mode); else if (!strcmp (what, "blk")) ret = S_ISBLK(st_mode); else if (!strcmp (what, "chr")) ret = S_ISCHR(st_mode); else if (!strcmp (what, "dir")) ret = S_ISDIR(st_mode); else if (!strcmp (what, "reg")) ret = S_ISREG(st_mode); else if (!strcmp (what, "lnk")) ret = S_ISLNK(st_mode); else { SLang_verror (SL_INVALID_PARM, "stat_is: Unrecognized type: %s", what); return -1; } return (char) (ret != 0);}#ifdef HAVE_READLINKstatic void readlink_cmd (char *s){ char buf[2048]; int n; n = readlink (s, buf, sizeof (buf)-1); if (n == -1) { _SLerrno_errno = errno; s = NULL; } else { buf[n] = 0; s = buf; } (void) SLang_push_string (s);}#endifstatic int chmod_cmd (char *file, int *mode){ if (-1 == chmod(file, (mode_t) *mode)) { _SLerrno_errno = errno; return -1; } return 0;}#ifdef HAVE_CHOWNstatic int chown_cmd (char *file, int *owner, int *group){ int ret; if (-1 == (ret = chown(file, (uid_t) *owner, (gid_t) *group))) _SLerrno_errno = errno; return ret;}#endif/* add trailing slash to dir */static void fixup_dir (char *dir){#ifndef VMS int n; if ((n = strlen(dir)) > 1) { n--;#if defined(IBMPC_SYSTEM) if ( dir[n] != '/' && dir[n] != '\\' ) strcat(dir, "\\" );#else if (dir[n] != '/' ) strcat(dir, "/" );#endif }#endif /* !VMS */}static void slget_cwd (void){ char cwd[1024]; char *p;#ifndef HAVE_GETCWD p = getwd (cwd);#else# if defined (__EMX__) p = _getcwd2(cwd, 1022); /* includes drive specifier */# else p = getcwd(cwd, 1022); /* djggp includes drive specifier */# endif#endif if (p == NULL) { _SLerrno_errno = errno; SLang_push_null (); return; }#ifndef VMS#ifdef __GO32__ /* You never know about djgpp since it favors unix */ { char ch; p = cwd; while ((ch = *p) != 0) { if (ch == '/') *p = '\\'; p++; } }#endif fixup_dir (cwd);#endif SLang_push_string (cwd);}static int chdir_cmd (char *s){ int ret; while (-1 == (ret = chdir (s))) {#ifdef EINTR if (errno == EINTR) continue;#endif _SLerrno_errno = errno; break; } return ret;}#ifdef VMSstatic int remove_cmd (char *);/* If the file looks like xxx, then change it to xxx.dir. If * it looks like A:[B.xxx] then change it to A:[B]xxx.dir. */static char *vms_convert_dirspec_to_vms_dir (char *str){ char *s; char *version; unsigned int len; char *dot; len = strlen (str); version = strchr (str, ';'); if (version == NULL) version = str + len; /* version points to the version of the input string */ if (NULL == (s = SLmalloc (len + 8)))/* allow extra space to work with */ return NULL; len = (unsigned int) (version - str); strncpy (s, str, len); s[len] = 0; str = s; /* Lowercase the whole thing */ while (*s != 0) { *s = LOWER_CASE(*s); s++; } if ((s > str) && (s[-1] != ']')) { if ((s >= str + 4) && (0 == strcmp (s - 4, ".dir"))) s -= 4; goto add_dir_version; } /* Check for one of two possibilities: * * dev:[x] --> dev:x * dev:[a.x] --> dev:[a]x */ if (NULL == (dot = strchr (str, '.'))) { /* First possibility */ if (NULL == (s = strchr (str, '['))) return str; /* let someone else figure this out */ while (s[1] != ']') { s[0] = s[1]; s++; } *s = 0; goto add_dir_version; } while (NULL != (s = strchr (dot + 1, '.'))) dot = s; *dot = ']'; s = str + (len - 1); /* Drop */ add_dir_version: strcpy (s, ".dir"); strcpy (s+4, version); return str;}#endifstatic int rmdir_cmd (char *s){#ifdef VMS int status; if (NULL == (s = vms_convert_dirspec_to_vms_dir (s))) return -1; status = remove_cmd (s); SLfree (s); return status;#else int ret; while (-1 == (ret = rmdir (s))) {#ifdef EINTR if (errno == EINTR) continue;#endif _SLerrno_errno = errno; break; } return ret;#endif}static int remove_cmd (char *s){ int ret;#ifdef VMS# define REMOVE delete#else# ifdef REAL_UNIX_SYSTEM# define REMOVE unlink# else# define REMOVE remove# endif#endif while (-1 == (ret = REMOVE (s))) {#ifdef EINTR if (errno == EINTR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -