/* Unix system calls */ /* Copyright (c) 1992, 1995 John E. Davis * All rights reserved. * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ #include "config.h" #include "sl-feat.h" #include #if defined (__EMX__) || defined(__BORLANDC__) # include /* for chmod */ #endif #include #include #include #include #ifdef HAVE_UNISTD_H # include #endif #include #include #include "slang.h" #include "_slang.h" static int push_stat_struct (struct stat *st) { char *field_names [11]; unsigned char field_types[11]; VOID_STAR field_values [11]; int int_values [11]; unsigned int i; field_names [0] = "st_dev"; int_values [0] = (int) st->st_dev; field_names [1] = "st_ino"; int_values [1] = (int) st->st_ino; field_names [2] = "st_mode"; int_values [2] = (int) st->st_mode; field_names [3] = "st_nlink"; int_values [3] = (int) st->st_nlink; field_names [4] = "st_uid"; int_values [4] = (int) st->st_uid; field_names [5] = "st_gid"; int_values [5] = (int) st->st_gid; field_names [6] = "st_rdev"; int_values [6] = (int) st->st_rdev; field_names [7] = "st_size"; int_values [7] = (int) st->st_size; field_names [8] = "st_atime"; int_values [8] = (int) st->st_atime; field_names [9] = "st_mtime"; int_values [9] = (int) st->st_mtime; field_names [10] = "st_ctime"; int_values [10] = (int) st->st_ctime; for (i = 0; i < 11; i++) { field_types [i] = SLANG_INT_TYPE; field_values [i] = (VOID_STAR) (int_values + i); } return _SLstruct_create_struct (11, field_names, field_types, field_values); } static void unix_stat_file (char *file) { struct stat st; if (-1 == stat (file, &st)) { _SLerrno_errno = errno; _SLang_push_null (); } else push_stat_struct (&st); } static void unix_lstat_file (char *file) { #ifdef HAVE_LSTAT struct stat st; if (-1 == lstat (file, &st)) { _SLerrno_errno = errno; _SLang_push_null (); } else push_stat_struct (&st); #else unix_stat_file (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. */ #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 #endif static int stat_is (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 { ret = -1; SLang_verror (SL_INVALID_PARM, "stat_is: Unrecognized type."); } SLang_free_slstring (what); return ret; } static int unix_chmod (char *file, int *mode) { if (-1 == chmod(file, (mode_t) *mode)) { _SLerrno_errno = errno; return -1; } return 0; } #if HAVE_CHOWN static int unix_chown (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 #ifdef HAVE_KILL /* This is mainly designed to check pids, but who knows.... */ static int unix_kill (int *pid, int *sig) { int ret; if (-1 == (ret = kill ((pid_t) *pid, *sig))) _SLerrno_errno = errno; return ret; } #endif static char *unix_ctime (int *tt) { char *t; t = ctime ((time_t *) tt); t[24] = 0; /* knock off \n */ return (t); } static SLang_Intrin_Fun_Type slunix_table[] = { #ifdef HAVE_KILL MAKE_INTRINSIC_II("unix_kill", unix_kill, SLANG_INT_TYPE), #endif MAKE_INTRINSIC_I("unix_ctime", unix_ctime, SLANG_STRING_TYPE), MAKE_INTRINSIC_S("lstat_file", unix_lstat_file, SLANG_VOID_TYPE), MAKE_INTRINSIC_S("stat_file", unix_stat_file, SLANG_VOID_TYPE), MAKE_INTRINSIC_SI("stat_is", stat_is, SLANG_INT_TYPE), #if HAVE_CHOWN MAKE_INTRINSIC_SII("chown", unix_chown, SLANG_INT_TYPE), #endif MAKE_INTRINSIC_SI("chmod", unix_chmod, SLANG_INT_TYPE), SLANG_END_TABLE }; int SLang_init_slunix (void) { if ((-1 == SLadd_intrin_fun_table (slunix_table, "__SLUNIX__")) || (-1 == _SLerrno_init ())) return -1; return 0; }