Browse Source

More errno stuff

K. Lange 4 years ago
parent
commit
b1fe4fa4ce
8 changed files with 80 additions and 45 deletions
  1. 1 1
      apps/compositor.c
  2. 44 33
      kernel/sys/syscall.c
  3. 12 3
      libc/dirent/dir.c
  4. 4 3
      libc/pthread/pthread.c
  5. 11 1
      libc/stdio/stdio.c
  6. 2 1
      libc/unistd/chdir.c
  7. 4 3
      libc/unistd/fstat.c
  8. 2 0
      libc/unistd/open.c

+ 1 - 1
apps/compositor.c

@@ -2000,7 +2000,7 @@ int main(int argc, char * argv[]) {
 		mfd = open("/dev/mouse", O_RDONLY);
 		kfd = open("/dev/kbd", O_RDONLY);
 		amfd = open("/dev/absmouse", O_RDONLY);
-		if (amfd == -1) {
+		if (amfd < 0) {
 			amfd = open("/dev/vmmouse", O_RDONLY);
 			vmmouse = 1;
 		}

+ 44 - 33
kernel/sys/syscall.c

@@ -66,7 +66,7 @@ static int sys_read(int fd, char * ptr, int len) {
 		node->offset += out;
 		return (int)out;
 	}
-	return -1;
+	return -EBADF;
 }
 
 static int sys_ioctl(int fd, int request, void * argp) {
@@ -74,7 +74,7 @@ static int sys_ioctl(int fd, int request, void * argp) {
 		PTR_VALIDATE(argp);
 		return ioctl_fs(FD_ENTRY(fd), request, argp);
 	}
-	return -1;
+	return -EBADF;
 }
 
 static int sys_readdir(int fd, int index, struct dirent * entry) {
@@ -84,12 +84,12 @@ static int sys_readdir(int fd, int index, struct dirent * entry) {
 		if (kentry) {
 			memcpy(entry, kentry, sizeof *entry);
 			free(kentry);
-			return 0;
-		} else {
 			return 1;
+		} else {
+			return 0;
 		}
 	}
-	return -1;
+	return -EBADF;
 }
 
 static int sys_write(int fd, char * ptr, int len) {
@@ -104,7 +104,7 @@ static int sys_write(int fd, char * ptr, int len) {
 		node->offset += out;
 		return out;
 	}
-	return -1;
+	return -EBADF;
 }
 
 static int sys_waitpid(int pid, int * status, int options) {
@@ -121,11 +121,13 @@ static int sys_open(const char * file, int flags, int mode) {
 
 	if (node && !has_permission(node, 04)) {
 		debug_print(WARNING, "access denied (read, sys_open, file=%s)", file);
+		close_fs(node);
 		return -EACCES;
 	}
 	if (node && ((flags & O_RDWR) || (flags & O_APPEND) || (flags & O_WRONLY) || (flags & O_TRUNC))) {
 		if (!has_permission(node, 02)) {
 			debug_print(WARNING, "access denied (write, sys_open, file=%s)", file);
+			close_fs(node);
 			return -EACCES;
 		}
 	}
@@ -143,7 +145,7 @@ static int sys_open(const char * file, int flags, int mode) {
 	}
 	if (!node) {
 		debug_print(NOTICE, "File does not exist; someone should be setting errno?");
-		return -1;
+		return -ENOENT;
 	}
 	if (flags & O_APPEND) {
 		node->offset = node->length;
@@ -159,7 +161,7 @@ static int sys_access(const char * file, int flags) {
 	PTR_VALIDATE(file);
 	debug_print(INFO, "access(%s, 0x%x) from pid=%d", file, flags, getpid());
 	fs_node_t * node = kopen((char *)file, 0);
-	if (!node) return -1;
+	if (!node) return -ENOENT;
 	close_fs(node);
 	return 0;
 }
@@ -170,7 +172,7 @@ static int sys_close(int fd) {
 		FD_ENTRY(fd) = NULL;
 		return 0;
 	}
-	return -1;
+	return -EBADF;
 }
 
 static int sys_sbrk(int size) {
@@ -255,8 +257,7 @@ static int sys_execve(const char * filename, char *const argv[], char *const env
 
 	debug_print(INFO,"Executing...");
 	/* Discard envp */
-	exec((char *)filename, argc, (char **)argv_, (char **)envp_);
-	return -1;
+	return exec((char *)filename, argc, (char **)argv_, (char **)envp_);
 }
 
 static int sys_seek(int fd, int offset, int whence) {
@@ -277,7 +278,7 @@ static int sys_seek(int fd, int offset, int whence) {
 		}
 		return FD_ENTRY(fd)->offset;
 	}
-	return -1;
+	return -EBADF;
 }
 
 static int stat_node(fs_node_t * fn, uintptr_t st) {
@@ -337,11 +338,16 @@ static int sys_chmod(char * file, int mode) {
 	PTR_VALIDATE(file);
 	fs_node_t * fn = kopen(file, 0);
 	if (fn) {
+		/* Can group members change bits? I think it's only owners. */
+		if (current_process->user != 0 && current_process->user != fn->uid) {
+			close_fs(fn);
+			return -EPERM;
+		}
 		result = chmod_fs(fn, mode);
 		close_fs(fn);
 		return result;
 	} else {
-		return -1;
+		return -ENOENT;
 	}
 }
 
@@ -350,11 +356,16 @@ static int sys_chown(char * file, int uid, int gid) {
 	PTR_VALIDATE(file);
 	fs_node_t * fn = kopen(file, 0);
 	if (fn) {
+		/* TODO: Owners can change groups... */
+		if (current_process->user != 0) {
+			close_fs(fn);
+			return -EPERM;
+		}
 		result = chown_fs(fn, uid, gid);
 		close_fs(fn);
 		return result;
 	} else {
-		return -1;
+		return -ENOENT;
 	}
 }
 
@@ -364,7 +375,7 @@ static int sys_stat(int fd, uintptr_t st) {
 	if (FD_CHECK(fd)) {
 		return stat_node(FD_ENTRY(fd), st);
 	}
-	return -1;
+	return -EBADF;
 }
 
 static int sys_mkpipe(void) {
@@ -386,7 +397,7 @@ static int sys_setuid(user_t new_uid) {
 		current_process->user = new_uid;
 		return 0;
 	}
-	return -1;
+	return -EPERM;
 }
 
 static int sys_uname(struct utsname * name) {
@@ -413,7 +424,7 @@ static int sys_uname(struct utsname * name) {
 
 static int sys_signal(uint32_t signum, uintptr_t handler) {
 	if (signum > NUMSIGNALS) {
-		return -1;
+		return -EINVAL;
 	}
 	uintptr_t old = current_process->signals.functions[signum];
 	current_process->signals.functions[signum] = handler;
@@ -430,7 +441,7 @@ static void inspect_memory (uintptr_t vaddr) {
 static int sys_reboot(void) {
 	debug_print(NOTICE, "[kernel] Reboot requested from process %d by user #%d", current_process->id, current_process->user);
 	if (current_process->user != USER_ROOT_UID) {
-		return -1;
+		return -EPERM;
 	} else {
 		debug_print(NOTICE, "[kernel] Good bye!");
 		/* Goodbye, cruel world */
@@ -452,7 +463,7 @@ static int sys_chdir(char * newdir) {
 	if (chd) {
 		if ((chd->flags & FS_DIRECTORY) == 0) {
 			close_fs(chd);
-			return -1;
+			return -ENOTDIR;
 		}
 		close_fs(chd);
 		free(current_process->wd_name);
@@ -460,7 +471,7 @@ static int sys_chdir(char * newdir) {
 		memcpy(current_process->wd_name, path, strlen(path) + 1);
 		return 0;
 	} else {
-		return -1;
+		return -ENOENT;
 	}
 }
 
@@ -478,13 +489,13 @@ static int sys_sethostname(char * new_hostname) {
 		PTR_VALIDATE(new_hostname);
 		size_t len = strlen(new_hostname) + 1;
 		if (len > 256) {
-			return 1;
+			return -ENAMETOOLONG;
 		}
 		hostname_len = len;
 		memcpy(hostname, new_hostname, hostname_len);
 		return 0;
 	} else {
-		return 1;
+		return -EPERM;
 	}
 }
 
@@ -548,7 +559,7 @@ static int sys_sysfunc(int fn, char ** args) {
 					PTR_VALIDATE(args[0]);
 					fs_node_t * file = kopen((char *)args[0], 0);
 					if (!file) {
-						return -1;
+						return -EINVAL;
 					}
 					size_t length = file->length;
 					uint8_t * buffer = malloc(length);
@@ -572,7 +583,7 @@ static int sys_sysfunc(int fn, char ** args) {
 					fs_node_t * tty = FD_ENTRY(0);
 					return create_kernel_tasklet(debug_hook, "[kttydebug]", tty);
 				} else {
-					return -1;
+					return -EINVAL;
 				}
 			case 8:
 				debug_print(NOTICE, "Loading module %s.", args[0]);
@@ -698,7 +709,7 @@ static int sys_sysfunc(int fn, char ** args) {
 			debug_print(ERROR, "Bad system function %d", fn);
 			break;
 	}
-	return -1; /* Bad system function or access failure */
+	return -EINVAL; /* Bad system function or access failure */
 }
 
 static int sys_sleepabs(unsigned long seconds, unsigned long subseconds) {
@@ -736,8 +747,8 @@ static int sys_fork(void) {
 }
 
 static int sys_clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg) {
-	if (!new_stack || !PTR_INRANGE(new_stack)) return -1;
-	if (!thread_func || !PTR_INRANGE(thread_func)) return -1;
+	if (!new_stack || !PTR_INRANGE(new_stack)) return -EINVAL;
+	if (!thread_func || !PTR_INRANGE(thread_func)) return -EINVAL;
 	return (int)clone(new_stack, thread_func, arg);
 }
 
@@ -767,10 +778,10 @@ static int sys_gettimeofday(struct timeval * tv, void * tz) {
 
 static int sys_openpty(int * master, int * slave, char * name, void * _ign0, void * size) {
 	/* We require a place to put these when we are done. */
-	if (!master || !slave) return -1;
-	if (master && !PTR_INRANGE(master)) return -1;
-	if (slave && !PTR_INRANGE(slave)) return -1;
-	if (size && !PTR_INRANGE(size)) return -1;
+	if (!master || !slave) return -EINVAL;
+	if (master && !PTR_INRANGE(master)) return -EINVAL;
+	if (slave && !PTR_INRANGE(slave)) return -EINVAL;
+	if (size && !PTR_INRANGE(size)) return -EINVAL;
 
 	/* Create a new pseudo terminal */
 	fs_node_t * fs_master;
@@ -854,7 +865,7 @@ static int sys_lstat(char * file, uintptr_t st) {
 static int sys_fswait(int c, int fds[]) {
 	PTR_VALIDATE(fds);
 	for (int i = 0; i < c; ++i) {
-		if (!FD_CHECK(fds[i])) return -1;
+		if (!FD_CHECK(fds[i])) return -EBADF;
 	}
 	fs_node_t ** nodes = malloc(sizeof(fs_node_t *)*(c+1));
 	for (int i = 0; i < c; ++i) {
@@ -870,7 +881,7 @@ static int sys_fswait(int c, int fds[]) {
 static int sys_fswait_timeout(int c, int fds[], int timeout) {
 	PTR_VALIDATE(fds);
 	for (int i = 0; i < c; ++i) {
-		if (!FD_CHECK(fds[i])) return -1;
+		if (!FD_CHECK(fds[i])) return -EBADF;
 	}
 	fs_node_t ** nodes = malloc(sizeof(fs_node_t *)*(c+1));
 	for (int i = 0; i < c; ++i) {

+ 12 - 3
libc/dirent/dir.c

@@ -2,11 +2,13 @@
 #include <fcntl.h>
 #include <string.h>
 #include <syscall.h>
+#include <errno.h>
 #include <bits/dirent.h>
 
 DIR * opendir (const char * dirname) {
 	int fd = open(dirname, O_RDONLY);
-	if (fd == -1) {
+	if (fd < 0) {
+		errno = -fd;
 		return NULL;
 	}
 
@@ -20,7 +22,7 @@ int closedir (DIR * dir) {
 	if (dir && (dir->fd != -1)) {
 		return close(dir->fd);
 	} else {
-		return -1;
+		return -EBADF;
 	}
 }
 
@@ -28,7 +30,14 @@ struct dirent * readdir (DIR * dirp) {
 	static struct dirent ent;
 
 	int ret = syscall_readdir(dirp->fd, ++dirp->cur_entry, &ent);
-	if (ret != 0) {
+	if (ret < 0) {
+		errno = -ret;
+		memset(&ent, 0, sizeof(struct dirent));
+		return NULL;
+	}
+
+	if (ret == 0) {
+		/* end of directory */
 		memset(&ent, 0, sizeof(struct dirent));
 		return NULL;
 	}

+ 4 - 3
libc/pthread/pthread.c

@@ -7,14 +7,15 @@
 #include <syscall.h>
 #include <signal.h>
 #include <pthread.h>
+#include <errno.h>
 
 #define PTHREAD_STACK_SIZE 0x100000
 
 int clone(uintptr_t a,uintptr_t b,void* c) {
-	return syscall_clone(a,b,c);
+	__sets_errno(syscall_clone(a,b,c));
 }
 int gettid() {
-	return syscall_gettid();
+	return syscall_gettid(); /* never fails */
 }
 
 int pthread_create(pthread_t * thread, pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) {
@@ -26,7 +27,7 @@ int pthread_create(pthread_t * thread, pthread_attr_t * attr, void *(*start_rout
 }
 
 int pthread_kill(pthread_t thread, int sig) {
-	return kill(thread.id, sig);
+	__sets_errno(kill(thread.id, sig));
 }
 
 void pthread_exit(void * value) {

+ 11 - 1
libc/stdio/stdio.c

@@ -4,6 +4,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <errno.h>
 
 #include <_xlog.h>
 
@@ -179,6 +180,7 @@ FILE * fopen(const char *path, const char *mode) {
 	int fd = syscall_open(path, flags, mask);
 
 	if (fd < 0) {
+		errno = -fd;
 		return NULL;
 	}
 
@@ -212,6 +214,7 @@ FILE * freopen(const char *path, const char *mode, FILE * stream) {
 		stream->ungetc = -1;
 		stream->eof = 0;
 		if (fd < 0) {
+			errno = -fd;
 			return NULL;
 		}
 	}
@@ -265,6 +268,7 @@ int fseek(FILE * stream, long offset, int whence) {
 
 	int resp = syscall_lseek(stream->fd,offset,whence);
 	if (resp < 0) {
+		errno = -resp;
 		return -1;
 	}
 	return 0;
@@ -277,7 +281,12 @@ long ftell(FILE * stream) {
 	stream->available = 0;
 	stream->ungetc = -1;
 	stream->eof = 0;
-	return syscall_lseek(stream->fd, 0, SEEK_CUR);
+	long resp = syscall_lseek(stream->fd, 0, SEEK_CUR);
+	if (resp < 0) {
+		errno = -resp;
+		return -1;
+	}
+	return resp;
 }
 
 size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream) {
@@ -300,6 +309,7 @@ size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE * stream) {
 	for (size_t i = 0; i < nmemb; ++i) {
 		int r = syscall_write(stream->fd, tracking, size);
 		if (r < 0) {
+			errno = -r;
 			_XLOG("write error in fwrite");
 			return -1;
 		}

+ 2 - 1
libc/unistd/chdir.c

@@ -1,9 +1,10 @@
 #include <unistd.h>
 #include <syscall.h>
+#include <errno.h>
 
 DEFN_SYSCALL1(chdir, 28, char *);
 
 int chdir(const char *path) {
-	return syscall_chdir((char*)path);
+	__sets_errno(syscall_chdir((char*)path));
 }
 

+ 4 - 3
libc/unistd/fstat.c

@@ -1,10 +1,11 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <syscall.h>
+#include <syscall_nums.h>
+#include <errno.h>
 
-DEFN_SYSCALL2(fstat, 15, int, void *);
+DEFN_SYSCALL2(fstat, SYS_STAT, int, void *);
 
 int fstat(int file, struct stat *st) {
-	syscall_fstat(file, st);
-	return 0;
+	__sets_errno(syscall_fstat(file, st));
 }

+ 2 - 0
libc/unistd/open.c

@@ -17,6 +17,7 @@ int open(const char *name, int flags, ...) {
 
 	result = syscall_open(name, flags, mode);
 	if (result == -1) {
+		/* Not sure this is necessary */
 		if (flags & O_CREAT) {
 			errno = EACCES;
 		} else {
@@ -24,6 +25,7 @@ int open(const char *name, int flags, ...) {
 		}
 	} else if (result < 0) {
 		errno = -result;
+		result = -1;
 	}
 	return result;
 }