Cleaned up send_message, corrected errno scope, added errno support.
authorPaul Pearce <pearce@eecs.berkeley.edu>
Thu, 4 Jun 2009 01:15:30 +0000 (21:15 -0400)
committerKevin Klues <klueska@cs.berkeley.edu>
Fri, 5 Jun 2009 01:24:39 +0000 (18:24 -0700)
Rewrote send_message to reduce redundent code. Also made changes to
function to facilitate reporting errno for all file io syscalls. Made
change to the file syscalls themselves to deal with errno reporting.
Removed #undef .. extern in newlib_backend.h that was creating 2 copies
of errno. This now lets userlab apps get access to errno by simply
including errno.h. Also made various housekeeping code changes.

Created a new test file, file_error to test errno functionality, and put
hooks into matrix.c.

user/apps/parlib/Makefrag
user/apps/parlib/file_error.c [new file with mode: 0644]
user/apps/parlib/matrix.c
user/parlib/inc/newlib_backend.h
user/parlib/src/newlib_backend.c

index 8585466..8ab9070 100644 (file)
@@ -16,10 +16,12 @@ USER_APPS_PARLIB_LDLIBS    := --start-group -lc -lm -lg -lparlib --end-group
 USER_APPS_PARLIB_LDOBJS    := $(OBJDIR)/$(USER_PARLIB_DIR)/entry.o \
                               $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/readline.o \
                               $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/file_io.o \
+                              $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/file_error.o \
                               $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/clrscrn.o \
                               $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/draw_nanwan.o \
                               $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/change_user.o  
 
+
 USER_APPS_PARLIB_LDDEPENDS := $(USER_APPS_PARLIB_LDOBJS) \
                               $(OBJDIR)/$(USER_PARLIB_DIR)/libparlib.a \
                               $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/%.o       
diff --git a/user/apps/parlib/file_error.c b/user/apps/parlib/file_error.c
new file mode 100644 (file)
index 0000000..67dbe84
--- /dev/null
@@ -0,0 +1,39 @@
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define IN_BUF_SIZE 1024
+
+extern char * readline(const char *prompt);
+
+void file_error()
+{
+               
+       char buf[IN_BUF_SIZE];
+
+       printf("Starting error testing....\n\n");
+
+       errno = 0;
+       int bad_fd = open("./test/DNE", O_RDWR, 0);
+       printf("Opened:       DNE\n");
+        printf("FD:           %d\n", bad_fd);
+        printf("ERRNO:        %s\n", strerror(errno));
+
+       errno = 0;
+       int result = read(bad_fd, buf, IN_BUF_SIZE - 1);
+       printf("Read:         %d bytes\n", result);
+       printf("ERRNO:        %s\n", strerror(errno));
+
+       errno = 0;
+       result = unlink("DNE");
+        printf("UNLINKED:     DNE\n");
+       printf("RESULT:       %d\n", result);
+        printf("ERRNO:        %s\n", strerror(errno));
+       
+       printf("\nTests Complete.\n\n");
+}
index 02910cd..2ee6686 100644 (file)
@@ -10,6 +10,7 @@ extern void clrscrn(int leaverows);
 extern void change_user();
 extern void set_default_user();
 extern void file_io();
+extern void file_error();
 extern char prompt[256];
 
 void help() {
@@ -18,6 +19,7 @@ void help() {
               "  clear_screen:     Clear the Screen\n"
               "  change_user:      Change Username\n"
                "  file_io:          Run File Related IO Tests\n"
+               "  file_error:       Run File Error Related Tests\n"
              );
 }
 
@@ -41,6 +43,8 @@ int main(int argc, char** argv)
                        change_user();
                else if (strcmp(s, "file_io") == 0)
                        file_io();
+               else if (strcmp(s, "file_error") == 0)
+                       file_error();
                else
                        help(); 
 
index d4fcf40..868c0fe 100644 (file)
@@ -6,8 +6,6 @@
 
 #include <errno.h>
 #include <sys/stat.h>
-#undef errno
-extern int errno;
 
 #define OPEN_ID                0
 #define CLOSE_ID       1
@@ -23,16 +21,16 @@ extern int errno;
 
 
 // Fixed size of the client->server msgs for the various calls.
-#define OPEN_MESSAGE_FIXED_SIZE        sizeof(syscall_id_t) + 3*sizeof(int)
-#define CLOSE_MESSAGE_FIXED_SIZE       sizeof(syscall_id_t) + sizeof(int)
-#define READ_MESSAGE_FIXED_SIZE        sizeof(syscall_id_t) + 2*sizeof(int)
-#define WRITE_MESSAGE_FIXED_SIZE       sizeof(syscall_id_t) + 2*sizeof(int)
-#define LSEEK_MESSAGE_FIXED_SIZE       sizeof(syscall_id_t) + 3*sizeof(int)
-#define ISATTY_MESSAGE_FIXED_SIZE      sizeof(syscall_id_t) + sizeof(int)
-#define LINK_MESSAGE_FIXED_SIZE        sizeof(syscall_id_t) + 2*sizeof(int)
-#define UNLINK_MESSAGE_FIXED_SIZE      sizeof(syscall_id_t) + sizeof(int)
-#define FSTAT_MESSAGE_FIXED_SIZE       sizeof(syscall_id_t) + sizeof(int)
-#define STAT_MESSAGE_FIXED_SIZE        sizeof(syscall_id_t) + sizeof(int)
+#define OPEN_MESSAGE_FIXED_SIZE       sizeof(syscall_id_t) + 3*sizeof(int)
+#define CLOSE_MESSAGE_FIXED_SIZE      sizeof(syscall_id_t) + sizeof(int)
+#define READ_MESSAGE_FIXED_SIZE       sizeof(syscall_id_t) + 2*sizeof(int)
+#define WRITE_MESSAGE_FIXED_SIZE      sizeof(syscall_id_t) + 2*sizeof(int)
+#define LSEEK_MESSAGE_FIXED_SIZE      sizeof(syscall_id_t) + 3*sizeof(int)
+#define ISATTY_MESSAGE_FIXED_SIZE     sizeof(syscall_id_t) + sizeof(int)
+#define LINK_MESSAGE_FIXED_SIZE       sizeof(syscall_id_t) + 2*sizeof(int)
+#define UNLINK_MESSAGE_FIXED_SIZE     sizeof(syscall_id_t) + sizeof(int)
+#define FSTAT_MESSAGE_FIXED_SIZE      sizeof(syscall_id_t) + sizeof(int)
+#define STAT_MESSAGE_FIXED_SIZE       sizeof(syscall_id_t) + sizeof(int)
 
 // What is the max number of arguments (besides the syscall_id_t) we can have.
 // This should be the max of the above sizes.
@@ -41,18 +39,6 @@ extern int errno;
 //             If we change the above defs to no longer be sizeof(int) this will break in server.c
 #define MAX_FIXED_ARG_COUNT 3
 
-// Fixed server-> respponse msg sizes.
-#define OPEN_RETURN_MESSAGE_FIXED_SIZE                sizeof(int)
-#define CLOSE_RETURN_MESSAGE_FIXED_SIZE        sizeof(int)
-#define READ_RETURN_MESSAGE_FIXED_SIZE                sizeof(int)
-#define WRITE_RETURN_MESSAGE_FIXED_SIZE        sizeof(int)
-#define LSEEK_RETURN_MESSAGE_FIXED_SIZE        sizeof(int)
-#define ISATTY_RETURN_MESSAGE_FIXED_SIZE       sizeof(int)
-#define UNLINK_RETURN_MESSAGE_FIXED_SIZE       sizeof(int)
-#define LINK_RETURN_MESSAGE_FIXED_SIZE                sizeof(int)
-#define STAT_RETURN_MESSAGE_FIXED_SIZE                sizeof(int) + sizeof(struct stat)
-#define FSTAT_RETURN_MESSAGE_FIXED_SIZE        sizeof(int) + sizeof(struct stat)
-
 // New errno we want to define if a channel error occurs
 // Not yet fully implimented
 #define ECHANNEL -999
index 77a8af5..9f77549 100644 (file)
@@ -44,7 +44,7 @@ int close(int file) {
 
        // If trying to close stdin/out/err just return
        if ((file == STDIN_FILENO) || (file == STDERR_FILENO) 
-            || (file == STDOUT_FILENO))
+                                   || (file == STDOUT_FILENO))
                return 0;
 
        // Allocate a new buffer of proper size
@@ -67,15 +67,19 @@ int close(int file) {
 
        free(out_msg);
 
+       int return_val;
+
        if (result != NULL) {
                // Read result
-               int return_val;
                return_val = *((int *) result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
                free(result);
-               return return_val;
        } else {
-               return -1;
+               errno = ECHANNEL;
+               return_val = -1;
        }
+       
+       return return_val;
 }
 
 /* execve()
@@ -150,6 +154,7 @@ int fstat(int file, struct stat *st)
                        memcpy(st, ((int *)result) + 1, sizeof(struct stat));
                free(result);
        } else {
+               errno = ECHANNEL;
                return_val = -1;
        }
 
@@ -200,15 +205,19 @@ int isatty(int file)
 
        free(out_msg);
 
+       int return_val;
+
        if (result != NULL) {
                // Read result
-               int return_val;
                return_val = *((int *) result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
                free(result);
-               return return_val;
        } else {
-               return -1;
+               errno = ECHANNEL;
+               return_val = -1;
        }
+       
+       return return_val;
 }
 
 /* kill()
@@ -270,8 +279,8 @@ int link(char *old, char *new)
                if (return_val == -1) errno = *(((int *)result) + 1);
                free(result);
        } else {
-               return_val = -1;
                errno = ECHANNEL;
+               return_val = -1;
        }
 
        return return_val;
@@ -309,15 +318,19 @@ off_t lseek(int file, off_t ptr, int dir)
 
        free(out_msg);
 
+       int return_val;
+
        if (result != NULL) {
                // Read result
-               int return_val;
                return_val = *((int *) result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
                free(result);
-               return return_val;
        } else {
-               return -1;
+               errno = ECHANNEL;
+               return_val = -1;
        }
+
+       return return_val;
 }
 
 /* open()
@@ -362,8 +375,10 @@ int open(const char *name, int flags, int mode)
 
        if (result != NULL) {
                return_val = *((int *)result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
                free(result);
        } else {
+               errno = ECHANNEL;
                return_val = -1;
        }
 
@@ -412,8 +427,12 @@ ssize_t read(int file, void *ptr, size_t len)
                return_val = *((int *)result);
                if (return_val > 0)
                        memcpy(ptr, ((int *)result) + 1, return_val);
+               else 
+                       errno = *(((int *)result) + 1);
+
                free(result);
        } else {
+               errno = ECHANNEL;
                return_val = -1;
        }
 
@@ -486,7 +505,6 @@ void* sbrk(ptrdiff_t incr)
  */
 char *send_message(char *message, int len)
 {
-
        syscall_id_t this_call_id = *((syscall_id_t*)message);
 
        if (write_to_channel(message, len) != len)
@@ -501,151 +519,86 @@ char *send_message(char *message, int len)
                return NULL;
 
        char* return_msg = NULL;
-       int extra_sp = 0;
+       char* errno_pos = NULL;
+       int extra_space = (response_value == -1) ? sizeof(int) : 0;
+
 
        // TODO: Make these sizes an array we index into, and only have this code once.
        // TODO: Will have a flag that tells us we have a variable length response (right now only for read case)
        // TODO: Default clause with error handling.
        switch (this_call_id) {
-               case OPEN_ID:
-                       if ((return_msg = 
-                            (char*)malloc(OPEN_RETURN_MESSAGE_FIXED_SIZE)) 
-                            == NULL)
-                               return NULL;
-
-                       break;
-
+               case OPEN_ID:           
                case CLOSE_ID:
-                       if ((return_msg = 
-                            (char*)malloc(CLOSE_RETURN_MESSAGE_FIXED_SIZE)) 
-                            == NULL)
-                               return NULL;
-
-                       break;
-
-               case READ_ID:
-                       extra_sp = (response_value > 0) ? response_value : 0;
-                       if ((return_msg 
-                            = (char*)malloc(READ_RETURN_MESSAGE_FIXED_SIZE 
-                                             + extra_sp)) 
-                            == NULL)
-                               return NULL;
-
-
-                       if ((response_value != -1) 
-                            && (read_from_channel(return_msg + sizeof(int), 
-                                                  response_value, NO_PEEK) 
-                            == -1))
-                               return NULL;
-
-                       break;
-
-               case WRITE_ID:
-                       if ((return_msg = 
-                            (char*)malloc(WRITE_RETURN_MESSAGE_FIXED_SIZE)) 
-                            == NULL)
-                               return NULL;
-
-                       break;
-
-
+               case WRITE_ID:  
                case LSEEK_ID:
-                       if ((return_msg = 
-                            (char*)malloc(LSEEK_RETURN_MESSAGE_FIXED_SIZE)) 
-                            == NULL)
-                               return NULL;
-
-                       break;
-
                case ISATTY_ID:
-                       if ((return_msg = 
-                            (char*)malloc(ISATTY_RETURN_MESSAGE_FIXED_SIZE)) 
-                            == NULL)
-                               return NULL;
-
-                       break;
-
                case UNLINK_ID:
-                       extra_sp = (response_value != -1) ? 0 : sizeof(int);
-                       if ((return_msg = 
-                            (char*)malloc(UNLINK_RETURN_MESSAGE_FIXED_SIZE 
-                                           + extra_sp)) 
-                            == NULL)
-                               return NULL;
-
-
-                       if ((response_value == -1) 
-                            && ((read_from_channel(return_msg + sizeof(int), 
-                                                   sizeof(int), NO_PEEK)) 
-                            == -1))
-                               return NULL;
-
-                       break;
-
                case LINK_ID:
-                       extra_sp = (response_value != -1) ? 0 : sizeof(int);
-                       if ((return_msg = 
-                            (char*)malloc(LINK_RETURN_MESSAGE_FIXED_SIZE 
-                                          + extra_sp)) 
-                            == NULL)
-                               return NULL;
-
-
-                       if ((response_value == -1) 
-                            && ((read_from_channel(return_msg + sizeof(int), 
-                                                   sizeof(int), NO_PEEK)) 
-                            == -1))
-                               return NULL;
-
-                       break;
-
+                        return_msg = (char*)malloc(sizeof(int) + extra_space);
+                       if (return_msg == NULL)
+                                return NULL;
+
+                       errno_pos = return_msg + sizeof(int);
+                        if ((response_value == -1)
+                            && (-1 == read_from_channel(errno_pos,
+                                                        sizeof(int), 
+                                                        NO_PEEK))) {
+                               free(return_msg);
+                                return NULL;
+                       }
+
+                        break;
+
+                case STAT_ID:
                case FSTAT_ID:
-                       extra_sp = (response_value != -1) ? 0 : sizeof(int);
-                       if ((return_msg = 
-                            (char*)malloc(FSTAT_RETURN_MESSAGE_FIXED_SIZE 
-                                          + extra_sp)) 
-                            == NULL)
-                               return NULL;
-
-                       if (read_from_channel(return_msg + sizeof(int), 
-                                              sizeof(struct stat), NO_PEEK) 
-                            == -1)
-                               return NULL;
-
-                       if ((response_value == -1) 
-                            && ((read_from_channel(return_msg 
-                                                    + sizeof(int) 
-                                                    + sizeof(struct stat),
-                                                   sizeof(int), NO_PEEK)) 
-                            == -1))
+                       return_msg = (char*)malloc(sizeof(int) 
+                                                    + sizeof(struct stat)
+                                                    + extra_space);
+                        if (return_msg == NULL)
+                                return NULL;
+
+                       if (-1 == read_from_channel(return_msg + sizeof(int),
+                                                    sizeof(struct stat), 
+                                                    NO_PEEK)) {
+                               free(return_msg);
+                                return NULL;
+                       }
+
+                        errno_pos = return_msg + sizeof(int) 
+                                               + sizeof(struct stat);
+
+                        if ((response_value == -1)
+                            && (-1 == read_from_channel(errno_pos,
+                                                  sizeof(int), NO_PEEK))) {
+                               free(return_msg);
                                return NULL;
+                       }
 
                        break;
+               
+               case READ_ID:
+                       if (response_value > 0)
+                               extra_space = response_value;
+                       else
+                               extra_space = extra_space;
 
-               case STAT_ID:
-                       extra_sp = (response_value != -1) ? 0 : sizeof(int);
-                       if ((return_msg = 
-                            (char*)malloc(STAT_RETURN_MESSAGE_FIXED_SIZE 
-                                          + extra_sp)) 
-                            == NULL)
-                               return NULL;
+                       return_msg = (char*)malloc(sizeof(int) + extra_space);
 
-                       if (read_from_channel(return_msg + sizeof(int), 
-                                              sizeof(struct stat), NO_PEEK) 
-                            == -1)
+                       if (return_msg == NULL)
                                return NULL;
 
-                       if ((response_value == -1) 
-                            && (read_from_channel(return_msg 
-                                                   + sizeof(int) 
-                                                   + sizeof(struct stat), 
-                                                  sizeof(int), NO_PEEK) 
-                            == -1))
-                               return NULL;
+                       if (-1 == read_from_channel(return_msg + sizeof(int),
+                                                    extra_space,
+                                                    NO_PEEK)) {
+                                free(return_msg);
+                                return NULL;
+                        }
 
                        break;
+
        }
 
+       // Copy response value in place
        memcpy(return_msg, &response_value, sizeof(int));
 
        return return_msg;
@@ -699,6 +652,7 @@ int stat(char *file, struct stat *st)
                free(result);
 
        } else {
+               errno = ECHANNEL;
                return_val = -1;
        }
 
@@ -755,10 +709,9 @@ int unlink(char *name)
                if (return_val == -1) errno = *(((int *)result) + 1);
                free(result);
        } else {
-               return_val = -1;
                errno = ECHANNEL;
+               return_val = -1;
        }
-
        return return_val;
 }
 
@@ -815,8 +768,10 @@ ssize_t write(int file, void *ptr, size_t len) {
 
        if (result != NULL) {
                return_val = *((int *)result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
                free(result);
        } else {
+               errno = ECHANNEL;
                return_val = -1;
        }