CS 3733 Operating Systems, Fall 2002 Assignment 1 Comments

The assignment was graded on a basis of 30 points.

  1. If it says "see me" on the front of your assignment, it does not (necessarily) mean that you are in trouble, just that means that either you or I did not understand what you did.
  2. Circled entries in your index indicate you should look for comments.
  3. Remember that inlin is not a string, and string functions should only be used with strings.
  4. parse_initial should not have to do any dynamic memory allocation.
  5. Do not exit from command_logger on error, use return.
  6. EOF is not a character, and is never stored in an array of characters.
  7. You should limit the number of mallocs and reallocs. command_logger should not have to do more than one malloc and no reallocs. Idea: First find the length of inlin. This gives an upper bound on the size of the buffer needed, slightly more than twice the length of inlin. Remember than inlin is not a string and its length is determined by the position of the newline.
  8. The number 33 should not appear anywhere in your code. Use:
    #define INVALID_MSG "Line does not contain 3 tokens.\n"
    int invalid_msg_length;
    invalid_msg_length = strlen(INVALID_MSG);

    Avoid using other such "magic numbers"
  9. You should not have any lint warnings of the form: xxx implicitly declared to ...
  10. If you do more than one malloc, be sure to free the first one if the second one produces and error.
  11. command_logger may not assume a maximum size for the input line.
  12. Instead of write(fd,"abc",3) use write(fd,"abc",strlen("abc"));
  13. command_logger in part 4 must use only one write.
    Do not check for a return value of -1, check that the return value is equal to the number of bytes you wanted to write.
  14. Each variable should be declared on a separate line.
  15. Test for errors on write and malloc
  16. For command_logger it is an error if not all bytes are written with a single write.
  17. Use realloc instead of reinventing it yourself.
  18. You don't need any reallocs at all. Find the length of inlin and do one malloc that is large enough.
  19. You may not access memory past the newline in inlin.
  20. It is invalid to do something like:
    sprintf(buf,"%sxxxx",buf);
    strcat(buf,buf);

    Keep in mind that if copying takes place between objects that overlap, the behavior is undedfned.
  21. Your code must be maintainable by others.
    Avoid using a large number of variables whose meaing is not obvious.
  22. Avoid using strncat(x,y,strlen(y). Use strcat.
  23. Be careful not to do
    ptr = realloc(ptr,xxx)
    If this returns an error, you can no longer access or free the old memory.


Outline of parse_initial:

ptr = inlin;
ptr = skip_white_space(ptr);
if (ptr == NULL) return -1;
*commandp = ptr;
ptr = skip_to_white_space(ptr);
if (ptr == NULL) return -1;
*ptr = 0;
ptr++;
ptr = skip_white_space(ptr);
if (ptr == NULL) return -1;
*pathp = ptr;
ptr = skip_to_white_space(ptr);
if (ptr == NULL) return -1;
*ptr = 0;
ptr++;
ptr = skip_white_space(ptr);
if (ptr == NULL) return -1;
*protocolp = ptr;
ptr = skip_token(ptr);
if (white_space(*ptr)) {
   make sure no more tokens, don't change ptr.
}
*ptr = 0;
if (strncmp(*pathp,"http://",7) == 0) {
   handle server
}
return 0;


Outline of command_logger:

#define COMMAND "Command: "
#define SERVER "Server: "
#define PORT "Port: "
#define PATH "Path: "
#define PROTOCOL "Protocol: "
#define BADGET "Line is not a valid GET command."
#define ALL_OVERHEAD 100

len = get_line_length(inlin);
buf = (char *)malloc(2*len+ALL_OVERHEAD);
if (buf == NULL) return -1;
memcpy(buf,inlin,len);
if (parse__initial(inlin,&command,&server,&path,&protocol) == -1)
   len = copy_line(buf,len,BADGET,NULL);
else {
       len = copy_line(buf,len,COMMAND,command);
       len = copy_line(buf,len,SERVER,server);
       len = copy_line(buf,len,PORT,port);
       len = copy_line(buf,len,PATH,path);
       len = copy_line(buf,len,PROTOCOL,protocol);
   }
   ret = write(fd,buf,len);
   free(buf);
   if (ret == len) return 0;
   return -1;
}

copy_line(char *buf, int buflen, char *name, char *value)
copies the string name into the array at buf+buflen and then appends
the string value if it is not NULL.  Terminate with a newline.
Return the new length.