📄 sysdep.c
字号:
getwd (pathname) char *pathname;{ char *npath, *spath; extern char *getcwd (); spath = npath = getcwd ((char *) 0, MAXPATHLEN); /* On Altos 3068, getcwd can return @hostname/dir, so discard up to first slash. Should be harmless on other systems. */ while (*npath && *npath != '/') npath++; strcpy (pathname, npath); free (spath); /* getcwd uses malloc */ return pathname;}#endif HAVE_GETWD#ifndef HAVE_RENAME/* * Emulate rename using unlink/link. Note that this is * only partially correct. Also, doesn't enforce restriction * that files be of same type (regular->regular, dir->dir, etc). */rename (from, to) char *from; char *to;{ if (access (from, 0) == 0) { unlink (to); if (link (from, to) == 0) if (unlink (from) == 0) return (0); } return (-1);}#endif /* not HAVE_RENAME *//* VARARGS */setpriority (){ return (0);}#ifndef HAVE_VFORK/* * Substitute fork(2) for vfork(2) on USG flavors. */vfork (){ return (fork ());}#endif /* not HAVE_VFORK */#ifdef MISSING_UTIMES/* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */utimes (){}#endif#ifdef IRIS_UTIME/* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the utimbuf structure defined anywhere but in the man page. */struct utimbuf { long actime; long modtime; };utimes (name, tvp) char *name; struct timeval tvp[];{ struct utimbuf utb; utb.actime = tvp[0].tv_sec; utb.modtime = tvp[1].tv_sec; utime (name, &utb);}#endif /* IRIS_UTIME */#if 0#ifdef HPUX/* HPUX curses library references perror, but as far as we know it won't be called. Anyway this definition will do for now. */perror (){}#endif /* HPUX */#endif /* 0 */#ifndef HAVE_DUP2/* * Emulate BSD dup2(2). First close newd if it already exists. * Then, attempt to dup oldd. If not successful, call dup2 recursively * until we are, then close the unsuccessful ones. */dup2 (oldd, newd) int oldd; int newd;{ register int fd; sys_close (newd);#ifdef F_DUPFD fd = fcntl (oldd, F_DUPFD, newd); if (fd != newd) error ("cant dup2(%i,%i) : %s", oldd, newd, sys_errlist[errno]);#else while ((fd = dup (oldd)) != newd) { dup2 (oldd, newd); sys_close (fd); }#endif}#endif /* not HAVE_DUP2 *//* * Gettimeofday. Simulate as much as possible. Only accurate * to nearest second. Emacs doesn't use tzp so ignore it for now. * Only needed when subprocesses are defined. */#ifdef subprocesses#ifndef HAVE_GETTIMEOFDAY#ifdef HAVE_TIMEVAL /* ARGSUSED */gettimeofday (tp, tzp) struct timeval *tp; struct timezone *tzp;{ extern long time (); tp->tv_sec = time ((long *)0); tp->tv_usec = 0;} #endif#endif#endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL */ /* * This function will go away as soon as all the stubs fixed. (fnf) */croak (badfunc) char *badfunc;{ printf ("%s not yet implemented\r\n", badfunc); reset_sys_modes (); exit (1);}#endif /* USG *//* Directory routines for systems that don't have them. */#ifdef SYSV_SYSTEM_DIR#include <dirent.h>#ifndef HAVE_CLOSEDIRintclosedir (dirp) register DIR *dirp; /* stream from opendir() */{ sys_close (dirp->dd_fd); free ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */ free ((char *) dirp);}#endif /* not HAVE_CLOSEDIR */#endif /* SYSV_SYSTEM_DIR */#ifdef NONSYSTEM_DIR_LIBRARYDIR *opendir (filename) char *filename; /* name of directory */{ register DIR *dirp; /* -> malloc'ed storage */ register int fd; /* file descriptor for read */ struct stat sbuf; /* result of fstat() */ fd = sys_open (filename, 0); if (fd < 0) return 0; if (fstat (fd, &sbuf) < 0 || (sbuf.st_mode & S_IFMT) != S_IFDIR || (dirp = (DIR *) malloc (sizeof (DIR))) == 0) { sys_close (fd); return 0; /* bad luck today */ } dirp->dd_fd = fd; dirp->dd_loc = dirp->dd_size = 0; /* refill needed */ return dirp;}voidclosedir (dirp) register DIR *dirp; /* stream from opendir() */{ sys_close (dirp->dd_fd); free ((char *) dirp);}#ifndef VMS#define DIRSIZ 14struct olddir { ino_t od_ino; /* inode */ char od_name[DIRSIZ]; /* filename */ };#endif /* not VMS */struct direct dir_static; /* simulated directory contents *//* ARGUSED */struct direct *readdir (dirp) register DIR *dirp; /* stream from opendir() */{#ifndef VMS register struct olddir *dp; /* -> directory data */#else /* VMS */ register struct dir$_name *dp; /* -> directory data */ register struct dir$_version *dv; /* -> version data */#endif /* VMS */ for (; ;) { if (dirp->dd_loc >= dirp->dd_size) dirp->dd_loc = dirp->dd_size = 0; if (dirp->dd_size == 0 /* refill buffer */ && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0) return 0;#ifndef VMS dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc]; dirp->dd_loc += sizeof (struct olddir); if (dp->od_ino != 0) /* not deleted entry */ { dir_static.d_ino = dp->od_ino; strncpy (dir_static.d_name, dp->od_name, DIRSIZ); dir_static.d_name[DIRSIZ] = '\0'; dir_static.d_namlen = strlen (dir_static.d_name); dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + dir_static.d_namlen - dir_static.d_namlen % 4; return &dir_static; /* -> simulated structure */ }#else /* VMS */ dp = (struct dir$_name *) dirp->dd_buf; if (dirp->dd_loc == 0) dirp->dd_loc = (dp->dir$b_namecount&1) ? dp->dir$b_namecount + 1 : dp->dir$b_namecount; dv = (struct dir$_version *)&dp->dir$t_name[dirp->dd_loc]; dir_static.d_ino = dv->dir$w_fid_num; dir_static.d_namlen = dp->dir$b_namecount; dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + dir_static.d_namlen - dir_static.d_namlen % 4; strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount); dir_static.d_name[dir_static.d_namlen] = '\0'; dirp->dd_loc = dirp->dd_size; /* only one record at a time */ return &dir_static;#endif /* VMS */ }}#ifdef VMS/* readdirver is just like readdir except it returns all versions of a file as separate entries. *//* ARGUSED */struct direct *readdirver (dirp) register DIR *dirp; /* stream from opendir() */{ register struct dir$_name *dp; /* -> directory data */ register struct dir$_version *dv; /* -> version data */ if (dirp->dd_loc >= dirp->dd_size - sizeof (struct dir$_name)) dirp->dd_loc = dirp->dd_size = 0; if (dirp->dd_size == 0 /* refill buffer */ && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0) return 0; dp = (struct dir$_name *) dirp->dd_buf; if (dirp->dd_loc == 0) dirp->dd_loc = (dp->dir$b_namecount & 1) ? dp->dir$b_namecount + 1 : dp->dir$b_namecount; dv = (struct dir$_version *) &dp->dir$t_name[dirp->dd_loc]; strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount); sprintf (&dir_static.d_name[dp->dir$b_namecount], ";%d", dv->dir$w_version); dir_static.d_namlen = strlen (dir_static.d_name); dir_static.d_ino = dv->dir$w_fid_num; dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + dir_static.d_namlen - dir_static.d_namlen % 4; dirp->dd_loc = ((char *) (++dv) - dp->dir$t_name); return &dir_static;}#endif /* VMS */#endif /* NONSYSTEM_DIR_LIBRARY *//* Functions for VMS */#ifdef VMS#include <pwd.h>#include <acldef.h>#include <chpdef.h>#include <jpidef.h>/* Return as a string the VMS error string pertaining to STATUS. Reuses the same static buffer each time it is called. */char *vmserrstr (status) int status; /* VMS status code */{ int bufadr[2]; short len; static char buf[257]; bufadr[0] = sizeof buf - 1; bufadr[1] = buf; if (! (SYS$GETMSG (status, &len, bufadr, 0x1, 0) & 1)) return "untranslatable VMS error status"; buf[len] = '\0'; return buf;}#ifdef access#undef access /* The following is necessary because 'access' emulation by VMS C (2.0) does * not work correctly. (It also doesn't work well in version 2.3.) */#ifdef VMS4_4#define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \ { strlen(string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }typedef union { struct { unsigned short s_buflen; unsigned short s_code; char *s_bufadr; unsigned short *s_retlenadr; } s; int end;} item;#define buflen s.s_buflen#define code s.s_code#define bufadr s.s_bufadr#define retlenadr s.s_retlenadr#define R_OK 4 /* test for read permission */#define W_OK 2 /* test for write permission */#define X_OK 1 /* test for execute (search) permission */#define F_OK 0 /* test for presence of file */intsys_access (path, mode) char *path; int mode;{ static char *user = NULL; char dir_fn[512]; /* translate possible directory spec into .DIR file name, so brain-dead * access() can treat the directory like a file. */ if (directory_file_name (path, dir_fn)) path = dir_fn; if (mode == F_OK) return access (path, mode); if (user == NULL && (user = getenv ("USER")) == NULL) return -1; { int stat; int flags; int acces; int dummy; item itemlst[3]; DESCRIPTOR(path_desc, path); DESCRIPTOR(user_desc, user); flags = 0; acces = 0; if ((mode & X_OK) && ((stat = access(path, mode)) < 0 || mode == X_OK)) return stat; if (mode & R_OK) acces |= CHP$M_READ; if (mode & W_OK) acces |= CHP$M_WRITE; itemlst[0].buflen = sizeof (int); itemlst[0].code = CHP$_FLAGS; itemlst[0].bufadr = &flags; itemlst[0].retlenadr = &dummy; itemlst[1].buflen = sizeof (int); itemlst[1].code = CHP$_ACCESS; itemlst[1].bufadr = &acces; itemlst[1].retlenadr = &dummy; itemlst[2].end = CHP$_END; stat = SYS$CHECK_ACCESS(&ACL$C_FILE, &path_desc, &user_desc, itemlst); return stat == SS$_NORMAL ? 0 : -1; }}#else /* not VMS4_4 */#include <prvdef.h>#define ACE$M_WRITE 2#define ACE$C_KEYID 1static unsigned short memid, grpid;static unsigned int uic;/* Called from init_sys_modes, so it happens not very often but at least each time Emacs is loaded. */sys_access_reinit (){ uic = 0;}intsys_access (filename, type) char * filename; int type;{ struct FAB fab; struct XABPRO xab; int status, prvmask[2], size, i, typecode, acl_controlled; unsigned int *aclptr, *aclend, aclbuf[60]; /* Get UIC and GRP values for protection checking. */ if (uic == 0) { status = LIB$GETJPI (&JPI$_UIC, 0, 0, &uic, 0, 0); if (! (status & 1)) return -1; memid = uic & 0xFFFF; grpid = uic >> 16; } if (type != 2) /* not checking write access */ return access (filename, type); /* Check write protection. */ #define CHECKPRIV(bit) (prvmask[bit / 32] & (1 << (bit % 32)))#define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE)) /* Find privilege bits */ status = sys$setprv (0, 0, 0, prvmask); if (! (status & 1)) error ("Unable to find privileges: %s", vmserrstr (status)); if (CHECKPRIV (PRV$V_BYPASS)) return 0; /* BYPASS enabled */ fab = cc$rms_fab; fab.fab$b_fac = FAB$M_GET; fab.fab$l_fna = filename; fab.fab$b_fns = strlen (filename); fab.fab$l_xab = &xab; xab = cc$rms_xabpro; xab.xab$l_aclbuf = aclbuf; xab.xab$w_aclsiz = sizeof (aclbuf); status = sys$open (&fab, 0, 0); if (! (status & 1)) return -1; sys$close (&fab, 0, 0); /* Check system access */ if (CHECKPRIV (PRV$V_SYSPRV) && WRITEABLE (XAB$V_SYS)) return 0; /* Check ACL entries, if any */ acl_controlled = 0; if (xab.xab$w_acllen > 0) { aclptr = aclbuf; aclend = &aclbuf[xab.xab$w_acllen / 4]; while (*aclptr && aclptr < aclend) { size = (*aclptr & 0xff) / 4; typecode = (*aclptr >> 8) & 0xff; if (typecode == ACE$C_KEYID) for (i = size - 1; i > 1; i--) if (aclptr[i] == uic) { acl_controlled = 1; if (aclptr[1] & ACE$M_WRITE) return 0; /* Write access through ACL */ } aclptr = &aclptr[size]; } if (acl_controlled) /* ACL specified, prohibits write access */ return -1; } /* No ACL entries specified, check normal protection */ if (WRITEABLE (XAB$V_WLD)) /* World writeable */ return 0; if (WRITEABLE (XAB$V_GRP) && (unsigned short) (xab.xab$l_uic >> 16) == grpid) return 0; /* Group writeable */ if (WRITEABLE (XAB$V_OWN) && (xab.xab$l_uic & 0xFFFF) == memid) return 0; /* Owner writeable */ return -1; /* Not writeable */}#endif /* not VMS4_4 */#endif /* access */ static char vtbuf[NAM$C_MAXRSS+1];/* translate a vms file spec to a unix path */char *sys_translate_vms (vfile) char * vfile;{ char * p; char * targ; if (!vfile) return 0; targ = vtbuf; /* leading device or logical name is a root directory */ if (p = strchr (vfile, ':')) { *t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -