This is slunix.c in view mode; [Download] [Up]
/* 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" #if defined (__EMX__) # include <io.h> /* for chmod */ #endif #include <sys/types.h> #include <sys/stat.h> #include <signal.h> #include <time.h> #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #include <errno.h> #include <string.h> #include "slang.h" /* map value of errno to standard slang return values. */ static int map_errno(void) { switch (errno) { case EACCES: return -1; /* insufficient privilege */ case ENOENT: return -2; /* invalid path */ default: return -50; } } #define EQS(a, b) ((*(a) == *(b)) && (!strcmp(a + 1, b + 1))) static struct stat Stat_Buf; static int parse_stat(struct stat *s, char *f) { if (!strncmp(f, "st_", 3)) f += 3; if (EQS("dev", f)) return s->st_dev; if (EQS("ino", f)) return s->st_ino; if (EQS("mode", f)) return s->st_mode; if (EQS("nlink", f)) return s->st_nlink; if (EQS("uid", f)) return s->st_uid; if (EQS("gid", f)) return s->st_gid; if (EQS("rdev", f)) return s->st_rdev; if (EQS("size", f)) return s->st_size; if (EQS("atime", f)) return s->st_atime; if (EQS("mtime", f)) return s->st_mtime; if (EQS("ctime", f)) return s->st_ctime; SLang_doerror("Unknown stat field."); return (0); } static int unix_stat_file(char *file) { if (!stat (file, &Stat_Buf)) return 0; return map_errno(); } #if !defined (__GO32__) && !defined (__EMX__) static int unix_lstat_file(char *file) { if (!lstat (file, &Stat_Buf)) return 0; return map_errno(); } #endif static int unix_stat_struct(char *field) { return parse_stat(&Stat_Buf, field); } /* 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) { if (!strcmp (what, "sock")) return S_ISSOCK(Stat_Buf.st_mode); if (!strcmp (what, "fifo")) return S_ISFIFO(Stat_Buf.st_mode); if (!strcmp (what, "blk")) return S_ISBLK(Stat_Buf.st_mode); if (!strcmp (what, "chr")) return S_ISCHR(Stat_Buf.st_mode); if (!strcmp (what, "dir")) return S_ISDIR(Stat_Buf.st_mode); if (!strcmp (what, "reg")) return S_ISREG(Stat_Buf.st_mode); if (!strcmp (what, "lnk")) return S_ISLNK(Stat_Buf.st_mode); SLang_doerror ("stat_is: Unrecognized type."); return 0; } static int unix_chmod(char *file, int *mode) { if (!chmod(file, (mode_t) *mode)) return 0; return map_errno(); } static int unix_chown(char *file, int *owner, int *group) { if (!chown(file, (uid_t) *owner, (gid_t) *group)) return 0; return map_errno(); } /* This is mainly designed to check pids, but who knows.... */ static int unix_kill(void) { int pid, sig; if (SLang_pop_integer(&sig) || SLang_pop_integer(&pid)) return (-1); return kill ((pid_t) pid, sig); } static char *unix_ctime(int *tt) { char *t; t = ctime ((time_t *) tt); t[24] = 0; /* knock off \n */ return (t); } static SLang_Name_Type slunix_table[] = { MAKE_INTRINSIC(".unix_kill", unix_kill, INT_TYPE, 0), /* Prototype: Integer unix_kill(Integer pid, Integer sig); * This function may be used to send a signal given by the integer @sig@ * to the process specified by @pid@. The function returns zero upon * sucess and @-1@ upon failure. */ MAKE_INTRINSIC(".unix_ctime", unix_ctime, STRING_TYPE, 1), /* Prototype: String unix_ctime(Integer secs); * This function returns a string representation of the time as given * by @secs@ seconds since 1970. */ #if !defined (__GO32__) && !defined (__EMX__) MAKE_INTRINSIC(".lstat_file", unix_lstat_file, INT_TYPE, 1), /* Prototype: Integer lstat_file(String file); * This function is like @stat_file@ but if @file@ is a symbolic link, * this @lstat_file@ returns information about the link itself. * See the documentation for @stat_file@ for more information. * Related Functions: @stat_file@ */ #endif MAKE_INTRINSIC(".stat_file", unix_stat_file, INT_TYPE, 1), /* Prototype: Integer stat_file(String file); * This function returns information about @file@ through the use of the * system @stat@ call. If the stat call fails, the function returns a * negative integer. If it is successful, it returns zero. Upon failure * it returns a negative number. To retrieve information obtained by this * this function call, use the @stat_struct@ function. * Related Functions: @lstat_file@, @stat_struct@ */ MAKE_INTRINSIC(".stat_struct", unix_stat_struct, INT_TYPE, 1), /* Prototype: Integer stat_struct(String field); * This functions returns information obtained by the most recent call to * the @stat_file@ or @lstat_file@ functions. The @field@ argument * specifies what piece of information to return. Valid values for * @field@ are: * @ "dev" * @ "ino" * @ "mode" * @ "nlink" * @ "uid" * @ "gid" * @ "rdev" * @ "size" * @ "atime" * @ "mtime" * @ "ctime" * See the man page for @stat@ for a discussion of these fields. * Example: * @ define file_size (file) * @ { * @ if (stat_file(file) < 0) error ("Unable to stat file!"); * @ return stat_struct("size"); * @ } * Related Functions: @lstat_file@, @stat_file@, @stat_mode_parse@ */ MAKE_INTRINSIC(".stat_is", stat_is, INT_TYPE, 1), /* Prototype: Integer stat_is (String type); * This function returns a boolean value about the type of file specified * in the last call to @stat_file@. Specifically, @type@ must be one of * the strings: * @ "sock" (socket) * @ "fifo" (fifo) * @ "blk" (block device) * @ "chr" (character device) * @ "reg" (regular file) * @ "lnk" (link) * @ "dir" (dir) * Related Functions: @stat_file@, @stat_struct@ */ MAKE_INTRINSIC(".chown", unix_chown, INT_TYPE, 3), /* Prototype: Integer chown(String file, Integer uid, Integer gid); * This function may be used to change the ownership of @file@ to that of * user id @uid@ and group id @gid@. This function returns 0 upon * success and a negative number up failure. Specifically, it returns -1 * if the process does not have sufficent privileges to change the * ownership, or -2 if the file does not exist. * Related Functions: @chmod@, @stat_file@ */ MAKE_INTRINSIC(".chmod", unix_chmod, INT_TYPE, 2), /* Prototype: Integer chmod(String file, Integer mode); * The @chmod@ function changes the permissions of @file@ to those * specified by @mode@. It returns 0 upon success, -1 if the process * lacks sufficient privilege for the operation, or -2 if the file does * not exist. See the system specific documentation for the C library * function @chmod@ for a discussion of the @mode@ parameter. * Related Functions: @chown@, @stat_file@ */ SLANG_END_TABLE }; int init_SLunix() { if (!SLdefine_for_ifdef ("SLUNIX")) return 0; return SLang_add_table(slunix_table, "_Unix"); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.