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

📄 doio.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (stio->dirp)	    closedir(stio->dirp);	if (!(stio->dirp = opendir(str_get(st[sp+1]))))	    goto nope;	break;    case O_READDIR:	if (gimme == G_ARRAY) {	    --sp;	    /*SUPPRESS 560*/	    while (dp = readdir(stio->dirp)) {#ifdef DIRNAMLEN		(void)astore(ary,++sp,		  str_2mortal(str_make(dp->d_name,dp->d_namlen)));#else		(void)astore(ary,++sp,		  str_2mortal(str_make(dp->d_name,0)));#endif	    }	}	else {	    if (!(dp = readdir(stio->dirp)))		goto nope;	    st[sp] = str_mortal(&str_undef);#ifdef DIRNAMLEN	    str_nset(st[sp], dp->d_name, dp->d_namlen);#else	    str_set(st[sp], dp->d_name);#endif	}	break;#if defined(HAS_TELLDIR) || defined(telldir)    case O_TELLDIR: {#ifndef telldir	    long telldir();#endif	    st[sp] = str_mortal(&str_undef);	    str_numset(st[sp], (double)telldir(stio->dirp));	    break;	}#endif#if defined(HAS_SEEKDIR) || defined(seekdir)    case O_SEEKDIR:	st[sp] = str_mortal(&str_undef);	along = (long)str_gnum(st[sp+1]);	(void)seekdir(stio->dirp,along);	break;#endif#if defined(HAS_REWINDDIR) || defined(rewinddir)    case O_REWINDDIR:	st[sp] = str_mortal(&str_undef);	(void)rewinddir(stio->dirp);	break;#endif    case O_CLOSEDIR:	st[sp] = str_mortal(&str_undef);	(void)closedir(stio->dirp);	stio->dirp = 0;	break;    default:	goto phooey;    }    return sp;nope:    st[sp] = &str_undef;    if (!errno)	errno = EBADF;    return sp;#endifphooey:    fatal("Unimplemented directory operation");}intapply(type,arglast)int type;int *arglast;{    register STR **st = stack->ary_array;    register int sp = arglast[1];    register int items = arglast[2] - sp;    register int val;    register int val2;    register int tot = 0;    char *s;#ifdef TAINT    for (st += ++sp; items--; st++)	tainted |= (*st)->str_tainted;    st = stack->ary_array;    sp = arglast[1];    items = arglast[2] - sp;#endif    switch (type) {    case O_CHMOD:#ifdef TAINT	taintproper("Insecure dependency in chmod");#endif	if (--items > 0) {	    tot = items;	    val = (int)str_gnum(st[++sp]);	    while (items--) {		if (chmod(str_get(st[++sp]),val))		    tot--;	    }	}	break;#ifdef HAS_CHOWN    case O_CHOWN:#ifdef TAINT	taintproper("Insecure dependency in chown");#endif	if (items > 2) {	    items -= 2;	    tot = items;	    val = (int)str_gnum(st[++sp]);	    val2 = (int)str_gnum(st[++sp]);	    while (items--) {		if (chown(str_get(st[++sp]),val,val2))		    tot--;	    }	}	break;#endif#ifdef HAS_KILL    case O_KILL:#ifdef TAINT	taintproper("Insecure dependency in kill");#endif	if (--items > 0) {	    tot = items;	    s = str_get(st[++sp]);	    if (isUPPER(*s)) {		if (*s == 'S' && s[1] == 'I' && s[2] == 'G')		    s += 3;		if (!(val = whichsig(s)))		    fatal("Unrecognized signal name \"%s\"",s);	    }	    else		val = (int)str_gnum(st[sp]);	    if (val < 0) {		val = -val;		while (items--) {		    int proc = (int)str_gnum(st[++sp]);#ifdef HAS_KILLPG		    if (killpg(proc,val))	/* BSD */#else		    if (kill(-proc,val))	/* SYSV */#endif			tot--;		}	    }	    else {		while (items--) {		    if (kill((int)(str_gnum(st[++sp])),val))			tot--;		}	    }	}	break;#endif    case O_UNLINK:#ifdef TAINT	taintproper("Insecure dependency in unlink");#endif	tot = items;	while (items--) {	    s = str_get(st[++sp]);	    if (euid || unsafe) {		if (UNLINK(s))		    tot--;	    }	    else {	/* don't let root wipe out directories without -U */#ifdef HAS_LSTAT		if (lstat(s,&statbuf) < 0 || S_ISDIR(statbuf.st_mode))#else		if (stat(s,&statbuf) < 0 || S_ISDIR(statbuf.st_mode))#endif		    tot--;		else {		    if (UNLINK(s))			tot--;		}	    }	}	break;    case O_UTIME:#ifdef TAINT	taintproper("Insecure dependency in utime");#endif	if (items > 2) {#ifdef I_UTIME	    struct utimbuf utbuf;#else	    struct {		long    actime;		long	modtime;	    } utbuf;#endif	    Zero(&utbuf, sizeof utbuf, char);	    utbuf.actime = (long)str_gnum(st[++sp]);    /* time accessed */	    utbuf.modtime = (long)str_gnum(st[++sp]);    /* time modified */	    items -= 2;#ifndef lint	    tot = items;	    while (items--) {		if (utime(str_get(st[++sp]),&utbuf))		    tot--;	    }#endif	}	else	    items = 0;	break;    }    return tot;}/* Do the permissions allow some operation?  Assumes statcache already set. */intcando(bit, effective, statbufp)int bit;int effective;register struct stat *statbufp;{#ifdef DOSISH    /* [Comments and code from Len Reed]     * MS-DOS "user" is similar to UNIX's "superuser," but can't write     * to write-protected files.  The execute permission bit is set     * by the Miscrosoft C library stat() function for the following:     *		.exe files     *		.com files     *		.bat files     *		directories     * All files and directories are readable.     * Directories and special files, e.g. "CON", cannot be     * write-protected.     * [Comment by Tom Dinger -- a directory can have the write-protect     *		bit set in the file system, but DOS permits changes to     *		the directory anyway.  In addition, all bets are off     *		here for networked software, such as Novell and     *		Sun's PC-NFS.]     */     /* Atari stat() does pretty much the same thing. we set x_bit_set_in_stat      * too so it will actually look into the files for magic numbers      */     return (bit & statbufp->st_mode) ? TRUE : FALSE;#else /* ! MSDOS */    if ((effective ? euid : uid) == 0) {	/* root is special */	if (bit == S_IXUSR) {	    if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode))		return TRUE;	}	else	    return TRUE;		/* root reads and writes anything */	return FALSE;    }    if (statbufp->st_uid == (effective ? euid : uid) ) {	if (statbufp->st_mode & bit)	    return TRUE;	/* ok as "user" */    }    else if (ingroup((int)statbufp->st_gid,effective)) {	if (statbufp->st_mode & bit >> 3)	    return TRUE;	/* ok as "group" */    }    else if (statbufp->st_mode & bit >> 6)	return TRUE;	/* ok as "other" */    return FALSE;#endif /* ! MSDOS */}intingroup(testgid,effective)int testgid;int effective;{    if (testgid == (effective ? egid : gid))	return TRUE;#ifdef HAS_GETGROUPS#ifndef NGROUPS#define NGROUPS 32#endif    {	GROUPSTYPE gary[NGROUPS];	int anum;	anum = getgroups(NGROUPS,gary);	while (--anum >= 0)	    if (gary[anum] == testgid)		return TRUE;    }#endif    return FALSE;}#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)intdo_ipcget(optype, arglast)int optype;int *arglast;{    register STR **st = stack->ary_array;    register int sp = arglast[0];    key_t key;    int n, flags;    key = (key_t)str_gnum(st[++sp]);    n = (optype == O_MSGGET) ? 0 : (int)str_gnum(st[++sp]);    flags = (int)str_gnum(st[++sp]);    errno = 0;    switch (optype)    {#ifdef HAS_MSG    case O_MSGGET:	return msgget(key, flags);#endif#ifdef HAS_SEM    case O_SEMGET:	return semget(key, n, flags);#endif#ifdef HAS_SHM    case O_SHMGET:	return shmget(key, n, flags);#endif#if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)    default:	fatal("%s not implemented", opname[optype]);#endif    }    return -1;			/* should never happen */}intdo_ipcctl(optype, arglast)int optype;int *arglast;{    register STR **st = stack->ary_array;    register int sp = arglast[0];    STR *astr;    char *a;    int id, n, cmd, infosize, getinfo, ret;    id = (int)str_gnum(st[++sp]);    n = (optype == O_SEMCTL) ? (int)str_gnum(st[++sp]) : 0;    cmd = (int)str_gnum(st[++sp]);    astr = st[++sp];    infosize = 0;    getinfo = (cmd == IPC_STAT);    switch (optype)    {#ifdef HAS_MSG    case O_MSGCTL:	if (cmd == IPC_STAT || cmd == IPC_SET)	    infosize = sizeof(struct msqid_ds);	break;#endif#ifdef HAS_SHM    case O_SHMCTL:	if (cmd == IPC_STAT || cmd == IPC_SET)	    infosize = sizeof(struct shmid_ds);	break;#endif#ifdef HAS_SEM    case O_SEMCTL:	if (cmd == IPC_STAT || cmd == IPC_SET)	    infosize = sizeof(struct semid_ds);	else if (cmd == GETALL || cmd == SETALL)	{	    struct semid_ds semds;	    if (semctl(id, 0, IPC_STAT, &semds) == -1)		return -1;	    getinfo = (cmd == GETALL);	    infosize = semds.sem_nsems * sizeof(short);		/* "short" is technically wrong but much more portable		   than guessing about u_?short(_t)? */	}	break;#endif#if !defined(HAS_MSG) || !defined(HAS_SEM) || !defined(HAS_SHM)    default:	fatal("%s not implemented", opname[optype]);#endif    }    if (infosize)    {	if (getinfo)	{	    STR_GROW(astr, infosize+1);	    a = str_get(astr);	}	else	{	    a = str_get(astr);	    if (astr->str_cur != infosize)	    {		errno = EINVAL;		return -1;	    }	}    }    else    {	int i = (int)str_gnum(astr);	a = (char *)i;		/* ouch */    }    errno = 0;    switch (optype)    {#ifdef HAS_MSG    case O_MSGCTL:	ret = msgctl(id, cmd, (struct msqid_ds *)a);	break;#endif#ifdef HAS_SEM    case O_SEMCTL:	ret = semctl(id, n, cmd, a);	break;#endif#ifdef HAS_SHM    case O_SHMCTL:	ret = shmctl(id, cmd, (struct shmid_ds *)a);	break;#endif    }    if (getinfo && ret >= 0) {	astr->str_cur = infosize;	astr->str_ptr[infosize] = '\0';    }    return ret;}intdo_msgsnd(arglast)int *arglast;{#ifdef HAS_MSG    register STR **st = stack->ary_array;    register int sp = arglast[0];    STR *mstr;    char *mbuf;    int id, msize, flags;    id = (int)str_gnum(st[++sp]);    mstr = st[++sp];    flags = (int)str_gnum(st[++sp]);    mbuf = str_get(mstr);    if ((msize = mstr->str_cur - sizeof(long)) < 0) {	errno = EINVAL;	return -1;    }    errno = 0;    return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);#else    fatal("msgsnd not implemented");#endif}intdo_msgrcv(arglast)int *arglast;{#ifdef HAS_MSG    register STR **st = stack->ary_array;    register int sp = arglast[0];    STR *mstr;    char *mbuf;    long mtype;    int id, msize, flags, ret;    id = (int)str_gnum(st[++sp]);    mstr = st[++sp];    msize = (int)str_gnum(st[++sp]);    mtype = (long)str_gnum(st[++sp]);    flags = (int)str_gnum(st[++sp]);    mbuf = str_get(mstr);    if (mstr->str_cur < sizeof(long)+msize+1) {	STR_GROW(mstr, sizeof(long)+msize+1);	mbuf = str_get(mstr);    }    errno = 0;    ret = msgrcv(id, (struct msgbuf *)mbuf, msize, mtype, flags);    if (ret >= 0) {	mstr->str_cur = sizeof(long)+ret;	mstr->str_ptr[sizeof(long)+ret] = '\0';    }    return ret;#else    fatal("msgrcv not implemented");#endif}intdo_semop(arglast)int *arglast;{#ifdef HAS_SEM    register STR **st = stack->ary_array;    register int sp = arglast[0];    STR *opstr;    char *opbuf;    int id, opsize;    id = (int)str_gnum(st[++sp]);    opstr = st[++sp];    opbuf = str_get(opstr);    opsize = opstr->str_cur;    if (opsize < sizeof(struct sembuf)	|| (opsize % sizeof(struct sembuf)) != 0) {	errno = EINVAL;	return -1;    }    errno = 0;    return semop(id, (struct sembuf *)opbuf, opsize/sizeof(struct sembuf));#else    fatal("semop not implemented");#endif}intdo_shmio(optype, arglast)int optype;int *arglast;{#ifdef HAS_SHM    register STR **st = stack->ary_array;    register int sp = arglast[0];    STR *mstr;    char *mbuf, *shm;    int id, mpos, msize;    struct shmid_ds shmds;#ifndef VOIDSHMAT    extern char *shmat();#endif    id = (int)str_gnum(st[++sp]);    mstr = st[++sp];    mpos = (int)str_gnum(st[++sp]);    msize = (int)str_gnum(st[++sp]);    errno = 0;    if (shmctl(id, IPC_STAT, &shmds) == -1)	return -1;    if (mpos < 0 || msize < 0 || mpos + msize > shmds.shm_segsz) {	errno = EFAULT;		/* can't do as caller requested */	return -1;    }    shm = (char*)shmat(id, (char*)NULL, (optype == O_SHMREAD) ? SHM_RDONLY : 0);    if (shm == (char *)-1)	/* I hate System V IPC, I really do */	return -1;    mbuf = str_get(mstr);    if (optype == O_SHMREAD) {	if (mstr->str_cur < msize) {	    STR_GROW(mstr, msize+1);	    mbuf = str_get(mstr);	}	Copy(shm + mpos, mbuf, msize, char);	mstr->str_cur = msize;	mstr->str_ptr[msize] = '\0';    }    else {	int n;	if ((n = mstr->str_cur) > msize)	    n = msize;	Copy(mbuf, shm + mpos, n, char);	if (n < msize)	    memzero(shm + mpos + n, msize - n);    }    return shmdt(shm);#else    fatal("shm I/O not implemented");#endif}#endif /* SYSV IPC */

⌨️ 快捷键说明

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