24.01.2014 Views

Codice

Codice

Codice

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

232 volume VI os16<br />

Script e sorgenti del kernel 233<br />

«<br />

«<br />

820227 | start = inode_directory->size;<br />

820228 | //<br />

820229 | // Prepare the buffer with the link.<br />

820230 | //<br />

820231 | dir->ino = inode_new->ino;<br />

820232 | strncpy (dir->name, path_name, NAME_MAX);<br />

820233 | inode_new->links++;<br />

820234 | inode_new->changed = 1;<br />

820235 | //<br />

820236 | // Append the buffer to the directory.<br />

820237 | //<br />

820238 | size_written = inode_file_write (inode_directory, start, buffer,<br />

820239 | (sizeof (directory_t)));<br />

820240 | if (size_written != (sizeof (directory_t)))<br />

820241 | {<br />

820242 | //<br />

820243 | // Problem updating the directory: release it and return.<br />

820244 | //<br />

820245 | inode_put (inode_directory);<br />

820246 | errset (EUNKNOWN);<br />

820247 | return (NULL);<br />

820248 | }<br />

820249 | //<br />

820250 | // Close access to the directory inode and save the other inode,<br />

820251 | // with updated link count.<br />

820252 | //<br />

820253 | inode_put (inode_directory);<br />

820254 | inode_save (inode_new);<br />

820255 | //<br />

820256 | // Return successfully.<br />

820257 | //<br />

820258 | return (inode_new);<br />

820259 |}<br />

104.4.40 kernel/fs/path_link.c<br />

Si veda la sezione 103.3.38.<br />

830001 |#include <br />

830002 |#include <br />

830003 |#include <br />

830004 |//----------------------------------------------------------------------<br />

830005 |int<br />

830006 |path_link (pid_t pid, const char *path_old, const char *path_new)<br />

830007 |{<br />

830008 | proc_t *ps;<br />

830009 | inode_t *inode_old;<br />

830010 | inode_t *inode_new;<br />

830011 | char path_new_full[PATH_MAX];<br />

830012 | //<br />

830013 | // Get process.<br />

830014 | //<br />

830015 | ps = proc_reference (pid);<br />

830016 | //<br />

830017 | // Try to get the old path inode.<br />

830018 | //<br />

830019 | inode_old = path_inode (pid, path_old);<br />

830020 | if (inode_old == NULL)<br />

830021 | {<br />

830022 | //<br />

830023 | // Cannot get the inode: ‘errno’ is already set by<br />

830024 | // ‘path_inode()’.<br />

830025 | //<br />

830026 | errset (errno);<br />

830027 | return (-1);<br />

830028 | }<br />

830029 | //<br />

830030 | // The inode is available and checks are done: arrange to get a<br />

830031 | // packed full path name and then the destination directory path.<br />

830032 | //<br />

830033 | path_full (path_new, ps->path_cwd, path_new_full);<br />

830034 | //<br />

830035 | //<br />

830036 | //<br />

830037 | inode_new = path_inode_link (pid, path_new_full, inode_old,<br />

830038 | (mode_t) 0);<br />

830039 | if (inode_new == NULL)<br />

830040 | {<br />

830041 | inode_put (inode_old);<br />

830042 | return (-1);<br />

830043 | }<br />

830044 | if (inode_new != inode_old)<br />

830045 | {<br />

830046 | inode_put (inode_new);<br />

830047 | inode_put (inode_old);<br />

830048 | errset (EUNKNOWN); // Unknown error.<br />

830049 | return (-1);<br />

830050 | }<br />

830051 | //<br />

830052 | // Inode data is already updated by ‘path_inode_link()’: just put<br />

830053 | // it and return. Please note that only one is put, because it is<br />

830054 | // just the same of the other.<br />

830055 | //<br />

830056 | inode_put (inode_new);<br />

830057 | return (0);<br />

830058 |}<br />

104.4.41 kernel/fs/path_mkdir.c<br />

Si veda la sezione 103.3.39.<br />

840001 |#include <br />

840002 |#include <br />

840003 |#include <br />

840004 |#include <br />

840005 |#include <br />

840006 |//----------------------------------------------------------------------<br />

840007 |int<br />

840008 |path_mkdir (pid_t pid, const char *path, mode_t mode)<br />

840009 |{<br />

840010 | proc_t *ps;<br />

840011 | inode_t *inode_directory;<br />

840012 | inode_t *inode_parent;<br />

840013 | int status;<br />

840014 | char path_directory[PATH_MAX];<br />

840015 | char path_copy[PATH_MAX];<br />

840016 | char *path_parent;<br />

840017 | ssize_t size_written;<br />

840018 | //<br />

840019 | struct {<br />

840020 | ino_t inode_1;<br />

840021 | char name_1[NAME_MAX];<br />

840022 | ino_t inode_2;<br />

840023 | char name_2[NAME_MAX];<br />

840024 | } directory;<br />

840025 | //<br />

840026 | // Get process.<br />

840027 | //<br />

840028 | ps = proc_reference (pid);<br />

840029 | //<br />

840030 | // Correct the mode with the umask.<br />

840031 | //<br />

840032 | mode &= ~ps->umask;<br />

840033 | //<br />

840034 | // Inside ‘mode’, the file type is fixed. No check is made.<br />

840035 | //<br />

840036 | mode &= 00777;<br />

840037 | mode |= S_IFDIR;<br />

840038 | //<br />

840039 | // The full path and the directory path is needed.<br />

840040 | //<br />

840041 | status = path_full (path, ps->path_cwd, path_directory);<br />

840042 | if (status < 0)<br />

840043 | {<br />

840044 | return (-1);<br />

840045 | }<br />

840046 | strncpy (path_copy, path_directory, PATH_MAX);<br />

840047 | path_copy[PATH_MAX-1] = 0;<br />

840048 | path_parent = dirname (path_copy);<br />

840049 | //<br />

840050 | // Check if something already exists with the same name. The scan<br />

840051 | // is done with kernel privileges.<br />

840052 | //<br />

840053 | inode_directory = path_inode ((uid_t) 0, path_directory);<br />

840054 | if (inode_directory != NULL)<br />

840055 | {<br />

840056 | //<br />

840057 | // The file already exists. Put inode and return an error.<br />

840058 | //<br />

840059 | inode_put (inode_directory);<br />

840060 | errset (EEXIST); // File exists.<br />

840061 | return (-1);<br />

840062 | }<br />

840063 | //<br />

840064 | // Try to locate the directory that should contain this one.<br />

840065 | //<br />

840066 | inode_parent = path_inode (pid, path_parent);<br />

840067 | if (inode_parent == NULL)<br />

840068 | {<br />

840069 | //<br />

840070 | // Cannot locate the directory: return an error. The variable<br />

840071 | // ‘errno’ should already be set by ‘path_inode()’.<br />

840072 | //<br />

840073 | errset (errno);<br />

840074 | return (-1);<br />

840075 | }<br />

840076 | //<br />

840077 | // Try to create the node: should fail if the user does not have<br />

840078 | // enough permissions.<br />

840079 | //<br />

840080 | inode_directory = path_inode_link (pid, path_directory, NULL,<br />

840081 | mode);<br />

840082 | if (inode_directory == NULL)<br />

840083 | {<br />

840084 | //<br />

840085 | // Sorry: cannot create the inode! The variable ‘errno’ should<br />

840086 | // already be set by ‘path_inode_link()’.<br />

840087 | //<br />

840088 | errset (errno);<br />

840089 | return (-1);<br />

840090 | }<br />

840091 | //<br />

840092 | // Fill records for ‘.’ and ‘..’.<br />

840093 | //<br />

840094 | directory.inode_1 = inode_directory->ino;<br />

840095 | strncpy (directory.name_1, ".", (size_t) 3);<br />

840096 | directory.inode_2 = inode_parent->ino;<br />

840097 | strncpy (directory.name_2, "..", (size_t) 3);<br />

840098 | //<br />

840099 | // Write data.<br />

840100 | //<br />

840101 | size_written = inode_file_write (inode_directory, (off_t) 0,<br />

840102 | &directory, (sizeof directory));<br />

840103 | if (size_written != (sizeof directory))<br />

840104 | {<br />

840105 | return (-1);<br />

840106 | }<br />

840107 | //<br />

840108 | // Fix directory inode links.<br />

840109 | //<br />

840110 | inode_directory->links = 2;<br />

840111 | inode_directory->time = k_time (NULL);<br />

840112 | inode_directory->changed = 1;<br />

840113 | //<br />

840114 | // Fix parent directory inode links.<br />

840115 | //<br />

840116 | inode_parent->links++;<br />

840117 | inode_parent->time = k_time (NULL);<br />

840118 | inode_parent->changed = 1;<br />

840119 | //<br />

840120 | // Save and put the inodes.<br />

840121 | //<br />

840122 | inode_save (inode_parent);<br />

840123 | inode_save (inode_directory);<br />

840124 | inode_put (inode_parent);<br />

840125 | inode_put (inode_directory);<br />

840126 | //<br />

840127 | // Return.<br />

840128 | //<br />

840129 | return (0);

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!