Exemple #1
0
/* Writes up to size bytes from buffer to the file open with descriptor fd,
   and returns the actual number written (may be less than size if EOF is 
   reached), or -1 if no file is open as fd or the write fails for another
   reason.  Writing to 1 will print to standard output */
static int 
sys_write (int fd, const void *buffer, unsigned size) 
{
  int written;
  struct file_fd *ffd;
  
  check_ptr (buffer);
  
  switch (fd) {
  case 0:
    return 0;
  case 1:
    putbuf ((char *) buffer, size);
    return size;
  case 2:
    return 0;
  default:
    ffd = get_file_fd (fd);
    if (ffd == NULL)
      return 0;
    
    lock_acquire (&fs_lock);
    written = file_write (ffd->file, buffer, size);
    lock_release (&fs_lock);
    return written;
  }
}
Exemple #2
0
/* Reads up to size bytes from the file open with descriptor fd into buffer,
   and returns the actual number of bytes read (may be less than size if EOF
   is reached), or -1 if no file is open as fd, or the read fails for any
   other reason.  Calling read with fd = 0 will read input from standard input,
   blocking until size bytes have been read */
static int
sys_read (int fd, void *buffer, unsigned size)
{
  check_ptr (buffer);
  
  unsigned read;
  struct file_fd *ffd;
  char *char_buffer = buffer;

  switch (fd) {
  case 0:
    for (read = 0; read < size; read++) {
      char_buffer[read] = input_getc ();
    }
    return read;
  case 1:
    return -1;
  case 2:
    return -1;
  default:
    ffd = get_file_fd (fd);
    if (ffd == NULL)
      return -1;
    lock_acquire (&fs_lock);
    read = file_read (ffd->file, buffer, size);
    lock_release (&fs_lock);
    return read;
  }
}
Exemple #3
0
void prepare_files(run_param* run, int * input_fd, int * output_fd, int * code_fd)
{
    get_file_fd(run->problem_id, input_fd, INPUT_DIR, "test.in", O_RDONLY);
    *output_fd = open("out.out", O_WRONLY|O_CREAT, S_IRWXU| S_IRWXG| S_IRWXO);
    ftruncate(*output_fd, 0);
    syslog(LOG_DEBUG, "prob num : %d.",run->problem_id);
    syslog(LOG_DEBUG, "code file : %s.",code_file_name[run->lang]);
    *code_fd = open(code_file_name[run->lang], O_WRONLY|O_CREAT);
    ftruncate(*code_fd, 0);
};
Exemple #4
0
/* Moves the current pointer of the file open as fd to position bytes ahead of
   the start of the file.  Does nothing if no file is open as fd */
static void 
sys_seek (int fd, unsigned position)
{
  struct file_fd *ffd;
  
  ffd = get_file_fd (fd);
  if (ffd == NULL)
    return;
  lock_acquire (&fs_lock);
  file_seek (ffd->file, position);
  lock_release (&fs_lock);
}
Exemple #5
0
/* Returns the size in bytes of the file with descriptor fd.
   If no file is open with descriptor fd or if the filesize could not be
   read for any other reason, returns -1 */
static int
sys_filesize (int fd)
{
  struct file_fd *ffd = get_file_fd (fd);
  int length;

  if (ffd == NULL)
    return -1;

  lock_acquire (&fs_lock);
  length = file_length (ffd->file);
  lock_release (&fs_lock);

  return length;
}
Exemple #6
0
/* Closes the file open with file descriptor fd, or does nothing if no
   such file exists */
static void
sys_close (int fd) 
{ 
  struct file_fd *ffd = get_file_fd (fd);
 
  if (ffd == NULL)
    return;
  else {
    list_remove (&ffd->elem);
    
    lock_acquire (&fs_lock);
    file_close (ffd->file);
    lock_release (&fs_lock);

    free (ffd);
  }
}
Exemple #7
0
/* Returns the number of bytes ahead of the start of the file the current 
   pointer is for the file open as fd, or -1 if no file is open as fd or the
   tell fails for any other reason */
static unsigned
sys_tell (int fd)
{
  unsigned next_byte;
  struct file_fd *ffd;

  ffd = get_file_fd (fd);

  if (ffd == NULL)
    // Proper error value?
    return -1;

  lock_acquire (&fs_lock);
  next_byte = file_tell (ffd->file);
  lock_release (&fs_lock);

  return next_byte;
}
int exec_cmd_node(cmd_node_t* cmd_node, client_node_t* client) {

    int pipe_count = cmd_node->pipe_count;
    int pid = -1;
    int input_pipe_fd = -1;
    int output_pipe_fd = -1;

    if(strcmp(cmd_node->cmd, "printenv") == 0) {
        char* env_name = cmd_node->args[1];
        if(env_name != NULL) {
            char* env_val = getenv(env_name);
            printf("%s=%s\n", env_name, env_val);
            fflush(stdout);
        }
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    } else if(strcmp(cmd_node->cmd, "setenv") == 0) {
        char* env_name = cmd_node->args[1];
        char* env_val = cmd_node->args[2];
        set_env_to_client_node(client, env_name, env_val);
        setenv(env_name, env_val, 1);
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    } else if(strcmp(cmd_node->cmd, "exit") == 0) {
        char exit_msg[64];
        bzero(exit_msg, 64);
        sprintf(exit_msg, "*** User '%s' left. ***\n", client->name);
        broad_cast(client, exit_msg);
        // clean message queues
        mq_clean(client->id);
        // remove global pipes
        remove_global_pipe(client->id, client->id, 0);
        // remove client from client list
        remove_client_node(client);
        // return logout status
        return -4;
    } else if(strcmp(cmd_node->cmd, "who") == 0) {
        who(client);
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    } else if(strcmp(cmd_node->cmd, "tell") == 0) {
        int r = tell(client, cmd_node->args[1], cmd_node->args[2]);
        if(r == -1) {
            printf("*** Error: user #%s does not exist yet. ***\n", cmd_node->args[1]);
            fflush(stdout);
        } else {
            decrease_all_pipe_node(client->pipe_list);
        }
        return 0;
    } else if(strcmp(cmd_node->cmd, "yell") == 0) {
        char message[11000];
        sprintf(message, "*** %s yelled ***: %s\n", client->name, cmd_node->args[1]);
        bzero(message, 11000);
        broad_cast(client, message);
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    } else if(strcmp(cmd_node->cmd, "name") == 0) {
        char* name = cmd_node->args[1];
        if(check_name_exist(name) == 1) {
            printf("*** User '%s' already exists. ***\n", name);
            fflush(stdout);
        } else {
            set_client_name(client->id, name);
            strcpy(client->name, name);
            char msg[40];
            bzero(msg, 40);
            sprintf(msg, "*** User from %s/%d is named '%s'. ***\n", client->ip, client->port, client->name);
            broad_cast(client, msg);
            fflush(stdout);
        }
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    }

    decrease_all_pipe_node(client->pipe_list);

    // get this process input source
    pipe_node_t* in_pipe_node = find_pipe_node_by_count(client->pipe_list, 0);
    if(in_pipe_node != NULL) {
        input_pipe_fd = in_pipe_node->in_fd;
        if(fcntl(in_pipe_node->out_fd, F_GETFD) != -1) {
            close(in_pipe_node->out_fd);
        }
        in_pipe_node->count--;
    }
    if(cmd_node->pipe_from_user == 1) {
        char data[2048];
        bzero(data, 2048);
        int r = pull_global_pipe_data(cmd_node->from_user_id, client->id, data);
        if(r == -1) {
            inscrease_all_pipe_node(client->pipe_list);
            return -2;
        }
        int g_pipe[2];
        pipe(g_pipe);
        write(g_pipe[1], r.msg, strlen(r.msg));
        close(g_pipe[1]);
        input_pipe_fd = g_pipe[0];
    }
    int tmp_global_pipe[2];

    // get this process output source
    pipe_node_t* out_pipe_node = find_pipe_node_by_count(client->pipe_list, pipe_count);
    if(out_pipe_node != NULL) {
        output_pipe_fd = out_pipe_node->out_fd;
    } else if(cmd_node->pipe_to_file == 1){
        output_pipe_fd = get_file_fd(cmd_node->filename);
    } else if(cmd_node->pipe_to_user == 1) {
        if(is_client_available(cmd_node->to_user_id) != 1) {
            printf("*** Error: user #%d does not exist yet. ***\n", cmd_node->to_user_id);
            fflush(stdout);
            close_unused_fd(client);
            return 0;
        } else if(is_global_pipe_exist(client->id, cmd_node->to_user_id) == 1) {
            close_unused_fd(client);
            return -3;
        }
        // global pipe
        // create global pipe node
        pipe(tmp_global_pipe);
        output_pipe_fd = tmp_global_pipe[1];

        // broad cast message
        // *** (name) (#<client id>) just piped '(command line)' to (receiver's name) (#<receiver's client_id>) ***
        char* msg_temp = "*** %s (#%d) just piped '%s' to %s (#%d) ***\n";
        char msg[128];
        bzero(msg, 128);
        char to_client_name[30];
        get_client_name(cmd_node->to_user_id, to_client_name);
        sprintf(msg, msg_temp, client->name, client->id, last_line, to_client_name, cmd_node->to_user_id);
        broad_cast(client, msg);
        fflush(stdout);
    } else if(cmd_node->pipe_count != 0) {
        int new_pipe_fd[2];
        pipe(new_pipe_fd);
        out_pipe_node = malloc(sizeof(pipe_node_t));
        out_pipe_node->count = cmd_node->pipe_count;
        out_pipe_node->in_fd = new_pipe_fd[0];
        out_pipe_node->out_fd = new_pipe_fd[1];
        out_pipe_node->next_node = NULL;
        insert_pipe_node(&(client->pipe_list), out_pipe_node);

        output_pipe_fd = new_pipe_fd[1];
    }


    pid = fork();
    if(pid == 0) {
        if(input_pipe_fd != -1) {
            // not use stdin
            close(0);
            dup(input_pipe_fd);
            close(input_pipe_fd);
        }

        // out
        if(out_pipe_node != NULL) {
            close(1);
            dup(out_pipe_node->out_fd);
            close(out_pipe_node->out_fd);
        } else if(cmd_node->pipe_to_file == 1) {
            close(1);
            dup(output_pipe_fd);
            close(output_pipe_fd);
        } else if(cmd_node->pipe_to_user == 1) {
            close(1);
            close(2);
            dup(output_pipe_fd);
            dup(output_pipe_fd);
            close(output_pipe_fd);
        } else {
            dup2(client->client_sc_fd, 1);
        }
        execvp(cmd_node->cmd, cmd_node->args);
        exit(-1);

    } else if(pipe_count != 0) {
        int status;
        wait(&status);
        // waitpid(pid, &status, 0);
        if(WEXITSTATUS(status) != 0){
            inscrease_all_pipe_node(client->pipe_list);
            return -1;
        } else {
            if(input_pipe_fd != -1) {
                close(input_pipe_fd);
            }
        }
    } else {
        int status;
        wait(&status);
        // waitpid(pid, &status, 0);
        if(WEXITSTATUS(status) != 0){
            inscrease_all_pipe_node(client->pipe_list);
            return -1;
        } else {
            if(in_pipe_node != NULL) {
                close(in_pipe_node->out_fd);
                in_pipe_node->count--;
            }
            if(cmd_node->pipe_to_user == 1) {
                if(fcntl(output_pipe_fd, F_GETFD) != -1) {
                    close(output_pipe_fd);
                }
                char buffer[2048];
                bzero(buffer, 2048);
                read(tmp_global_pipe[0], buffer, 2048);
                //printf("[DBG] Buffer:\n");
                //printf("%s\n", buffer);
                add_global_pipe(client->id, cmd_node->to_user_id, buffer);
                close(tmp_global_pipe[0]);
            }
            close_unused_fd(client);
        }
    }
    if(cmd_node->pipe_from_user == 1) {
        char* msg_tmp = "*** %s (#%d) just received from %s (#%d) by '%s' ***\n";
        char msg[100];
        bzero(msg, 100);
        char from_client_name[30];
        get_client_name(cmd_node->from_user_id, from_client_name);
        sprintf(msg, msg_tmp, client->name, client->id, from_client_name, cmd_node->from_user_id, last_line);
        broad_cast(client, msg);
        remove_global_pipe(cmd_node->from_user_id, client->id, 1);
    }
    return 0;
}