Linux0.11 Not owner
关于 rm, chmod 一类命令提示 Not owner 的问题,是由于 0.11 版无 lstat 系统调用。
可以直接从 0.12 版复制新加的系统调用,补完即可,相信看过这部分代码后,大家都能做到。
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_select 82
#define __NR_symlink 83
#define __NR_lstat 84
#define __NR_readlink 85
#define __NR_uselib 86
补丁如下:
diff --git a/fs/exec.c b/fs/exec.c
index c26c4e4..0c4aac8 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -38,6 +38,11 @@ extern int sys_close(int fd);
*/
#define MAX_ARG_PAGES 32
+int sys_uselib(const char * library)
+{
+ return -ENOENT;
+}
+
/*
* create_tables() parses the env- and arg-strings in new user
* memory and creates the pointer tables from them, and puts their
diff --git a/fs/namei.c b/fs/namei.c
index 97d0de4..bd7f86b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -294,7 +294,7 @@ static struct m_inode * dir_namei(const char * pathname,
}
/*
- * namei()
+ * namei()
*
* is used by most simple commands to get the inode of a specified name.
* Open, link etc use their own routines, but this is enough for things
@@ -718,6 +718,11 @@ int sys_unlink(const char * name)
return 0;
}
+int sys_symlink(const char * oldname, const char * newname)
+{
+ return -EPERM;
+}
+
int sys_link(const char * oldname, const char * newname)
{
struct dir_entry * de;
diff --git a/fs/stat.c b/fs/stat.c
index 61a4ceb..7d3934a 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -44,6 +44,17 @@ int sys_stat(char * filename, struct stat * statbuf)
return 0;
}
+int sys_lstat(char * filename, struct stat * statbuf)
+{
+ struct m_inode * inode;
+
+ if (!(inode = namei(filename)))
+ return -ENOENT;
+ cp_stat(inode,statbuf);
+ iput(inode);
+ return 0;
+}
+
int sys_fstat(unsigned int fd, struct stat * statbuf)
{
struct file * f;
@@ -54,3 +65,9 @@ int sys_fstat(unsigned int fd, struct stat * statbuf)
cp_stat(inode,statbuf);
return 0;
}
+
+int sys_readlink(const char * path, char * buf, int bufsiz)
+{
+ return -ENOENT;
+}
+
diff --git a/include/linux/sys.h b/include/linux/sys.h
index c538fc1..fea031b 100644
--- a/include/linux/sys.h
+++ b/include/linux/sys.h
@@ -70,6 +70,22 @@ extern int sys_sgetmask();
extern int sys_ssetmask();
extern int sys_setreuid();
extern int sys_setregid();
+extern int sys_sigpending();
+extern int sys_sigsuspend();
+extern int sys_sethostname();
+extern int sys_setrlimit();
+extern int sys_getrlimit();
+extern int sys_getrusage();
+extern int sys_gettimeofday();
+extern int sys_settimeofday();
+extern int sys_getgroups();
+extern int sys_setgroups();
+extern int sys_select();
+extern int sys_symlink();
+extern int sys_lstat();
+extern int sys_readlink();
+extern int sys_uselib();
+
fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
@@ -83,4 +99,8 @@ sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,
sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,
sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,
sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,
-sys_setreuid,sys_setregid };
+sys_setreuid,sys_setregid, sys_sigsuspend, sys_sigpending, sys_sethostname,
+sys_setrlimit, sys_getrlimit, sys_getrusage, sys_gettimeofday,
+sys_settimeofday, sys_getgroups, sys_setgroups, sys_select, sys_symlink,
+sys_lstat, sys_readlink, sys_uselib };
+
diff --git a/include/sys/stat.h b/include/sys/stat.h
index 41c3840..e917e9c 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -18,6 +18,7 @@ struct stat {
};
#define S_IFMT 00170000
+#define S_IFLNK 0120000
#define S_IFREG 0100000
#define S_IFBLK 0060000
#define S_IFDIR 0040000
@@ -27,6 +28,7 @@ struct stat {
#define S_ISGID 0002000
#define S_ISVTX 0001000
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
diff --git a/include/sys/times.h b/include/sys/times.h
index 68d5bfb..a61fa99 100644
--- a/include/sys/times.h
+++ b/include/sys/times.h
@@ -1,6 +1,49 @@
#ifndef _TIMES_H
#define _TIMES_H
+/* gettimofday returns this */
+struct timeval {
+ long tv_sec; /* seconds */
+ long tv_usec; /* microseconds */
+};
+
+struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+
+#define DST_NONE 0 /* not on dst */
+#define DST_USA 1 /* USA style dst */
+#define DST_AUST 2 /* Australian style dst */
+#define DST_WET 3 /* Western European dst */
+#define DST_MET 4 /* Middle European dst */
+#define DST_EET 5 /* Eastern European dst */
+#define DST_CAN 6 /* Canada */
+#define DST_GB 7 /* Great Britain and Eire */
+#define DST_RUM 8 /* Rumania */
+#define DST_TUR 9 /* Turkey */
+#define DST_AUSTALT 10 /* Australian style with shift in 1986 */
+
+#define FD_SET(fd,fdsetp) (*(fdsetp) |= (1 << (fd)))
+#define FD_CLR(fd,fdsetp) (*(fdsetp) &= ~(1 << (fd)))
+#define FD_ISSET(fd,fdsetp) ((*(fdsetp) >> fd) & 1)
+#define FD_ZERO(fdsetp) (*(fdsetp) = 0)
+
+
+/*
+ * Names of the interval timers, and structure
+ * defining a timer setting.
+ */
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+
+
#include <sys/types.h>
struct tms {
diff --git a/include/unistd.h b/include/unistd.h
index 956554a..1d2a881 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -129,6 +129,24 @@
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
+#define __NR_sigsuspend 72
+/*
+ * add Linux0.12 system call
+ */
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_lstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
#define _syscall0(type,name) \
type name(void) \
diff --git a/kernel/signal.c b/kernel/signal.c
index c6afb3a..365530b 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -7,8 +7,8 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>
-
#include <signal.h>
+#include <errno.h>
void do_exit(int error_code);
@@ -25,6 +25,19 @@ int sys_ssetmask(int newmask)
return old;
}
+int sys_sigpending(sigset_t *set)
+{
+ /* fill in "set" with signals pending but blocked. */
+ verify_area(set,4);
+ put_fs_long(current->blocked & current->signal, (unsigned long *)set);
+ return 0;
+}
+
+int sys_sigsuspend(int restart, unsigned long old_mask, unsigned long set)
+{
+ return -EINTR;
+}
+
static inline void save_old(char * from,char * to)
{
int i;
diff --git a/kernel/sys.c b/kernel/sys.c
index 2c01e67..7809a12 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -13,6 +13,35 @@
#include <sys/times.h>
#include <sys/utsname.h>
+#define NGROUPS 32 /* Max number of groups per user */
+#define NOGROUP -1
+#define MAXHOSTNAMELEN 8
+
+
+struct rlimit {
+ int rlim_cur;
+ int rlim_max;
+};
+
+struct rusage {
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
+ long ru_maxrss; /* maximum resident set size */
+ long ru_ixrss; /* integral shared memory size */
+ long ru_idrss; /* integral unshared data size */
+ long ru_isrss; /* integral unshared stack size */
+ long ru_minflt; /* page reclaims */
+ long ru_majflt; /* page faults */
+ long ru_nswap; /* swaps */
+ long ru_inblock; /* block input operations */
+ long ru_oublock; /* block output operations */
+ long ru_msgsnd; /* messages sent */
+ long ru_msgrcv; /* messages received */
+ long ru_nsignals; /* signals received */
+ long ru_nvcsw; /* voluntary context switches */
+ long ru_nivcsw; /* involuntary " */
+};
+
int sys_ftime()
{
return -ENOSYS;
@@ -153,6 +182,8 @@ int sys_stime(long * tptr)
return 0;
}
+
+
int sys_times(struct tms * tbuf)
{
if (tbuf) {
@@ -203,6 +234,11 @@ int sys_getpgrp(void)
return current->pgrp;
}
+int sys_select( unsigned long *buffer )
+{
+ return -ERROR;
+}
+
int sys_setsid(void)
{
if (current->leader && !suser())
@@ -213,6 +249,16 @@ int sys_setsid(void)
return current->pgrp;
}
+int sys_getgroups(int gidsetsize, gid_t *grouplist)
+{
+ return -ERROR;
+}
+
+int sys_setgroups(int gidsetsize, gid_t *grouplist)
+{
+ return -ERROR;
+}
+
int sys_uname(struct utsname * name)
{
static struct utsname thisname = {
@@ -227,6 +273,37 @@ int sys_uname(struct utsname * name)
return 0;
}
+int sys_sethostname(char *name, int len)
+{
+ return -ERROR;
+}
+
+int sys_getrlimit(int resource, struct rlimit *rlim)
+{
+ return -ERROR;
+
+}
+
+int sys_setrlimit(int resource, struct rlimit *rlim)
+{
+ return -ERROR;
+}
+
+int sys_getrusage(int who, struct rusage *ru)
+{
+ return -ERROR;
+}
+
+int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ return -ERROR;
+}
+
+int sys_settimeofday(struct timeval *tv, struct timezone *tz)
+{
+ return -ERROR;
+}
+
int sys_umask(int mask)
{
int old = current->umask;
@@ -234,3 +311,4 @@ int sys_umask(int mask)
current->umask = mask & 0777;
return (old);
}
+
diff --git a/kernel/system_call.s b/kernel/system_call.s
index a348344..baa906a 100644
--- a/kernel/system_call.s
+++ b/kernel/system_call.s
@@ -59,7 +59,7 @@ sa_mask = 4
sa_flags = 8
sa_restorer = 12
-nr_system_calls = 72
+nr_system_calls = 86
浙公网安备 33010602011771号