24.01.2014 Views

Codice

Codice

Codice

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

202 volume VI os16<br />

Script e sorgenti del kernel 203<br />

«<br />

480008 |{<br />

480009 | proc_t *ps;<br />

480010 | int status;<br />

480011 | //<br />

480012 | // Get process.<br />

480013 | //<br />

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

480015 | //<br />

480016 | // Verify if ‘fdn_old’ is a valid value.<br />

480017 | //<br />

480018 | if (fdn_old < 0 ||<br />

480019 | fdn_old >= OPEN_MAX ||<br />

480020 | ps->fd[fdn_old].file == NULL)<br />

480021 | {<br />

480022 | errset (EBADF); // Bad file descriptor.<br />

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

480024 | }<br />

480025 | //<br />

480026 | // Check if ‘fd_old’ and ‘fd_new’ are the same.<br />

480027 | //<br />

480028 | if (fdn_old == fdn_new)<br />

480029 | {<br />

480030 | return (fdn_new);<br />

480031 | }<br />

480032 | //<br />

480033 | // Close ‘fdn_new’ if it is open and copy ‘fdn_old’ into it.<br />

480034 | //<br />

480035 | if (ps->fd[fdn_new].file != NULL)<br />

480036 | {<br />

480037 | status = fd_close (pid, fdn_new);<br />

480038 | if (status != 0)<br />

480039 | {<br />

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

480041 | }<br />

480042 | }<br />

480043 | ps->fd[fdn_new].fl_flags = ps->fd[fdn_old].fl_flags;<br />

480044 | ps->fd[fdn_new].fd_flags = ps->fd[fdn_old].fd_flags & ~FD_CLOEXEC;<br />

480045 | ps->fd[fdn_new].file = ps->fd[fdn_old].file;<br />

480046 | ps->fd[fdn_new].file->references++;<br />

480047 | return (fdn_new);<br />

480048 |}<br />

104.4.6 kernel/fs/fd_fcntl.c<br />

Si veda la sezione 103.3.6.<br />

490001 |#include <br />

490002 |#include <br />

490003 |#include <br />

490004 |#include <br />

490005 |//----------------------------------------------------------------------<br />

490006 |int<br />

490007 |fd_fcntl (pid_t pid, int fdn, int cmd, int arg)<br />

490008 |{<br />

490009 | proc_t *ps;<br />

490010 | inode_t *inode;<br />

490011 | int mask;<br />

490012 | //<br />

490013 | // Get process.<br />

490014 | //<br />

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

490016 | //<br />

490017 | // Verify if the file descriptor is valid.<br />

490018 | //<br />

490019 | if (ps->fd[fdn].file == NULL)<br />

490020 | {<br />

490021 | errset (EBADF); // Bad file descriptor.<br />

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

490023 | }<br />

490024 | //<br />

490025 | // Reach the inode.<br />

490026 | //<br />

490027 | inode = ps->fd[fdn].file->inode;<br />

490028 | //<br />

490029 | //<br />

490030 | //<br />

490031 | switch (cmd)<br />

490032 | {<br />

490033 | case F_DUPFD:<br />

490034 | return (fd_dup (pid, fdn, arg));<br />

490035 | break;<br />

490036 | case F_GETFD:<br />

490037 | return (ps->fd[fdn].fd_flags);<br />

490038 | break;<br />

490039 | case F_SETFD:<br />

490040 | ps->fd[fdn].fd_flags = arg;<br />

490041 | return (0);<br />

490042 | case F_GETFL:<br />

490043 | return (ps->fd[fdn].fl_flags);<br />

490044 | case F_SETFL:<br />

490045 | //<br />

490046 | // Calculate a mask with bits that are not to be set.<br />

490047 | //<br />

490048 | mask = (O_ACCMODE<br />

490049 | | O_CREAT<br />

490050 | | O_EXCL<br />

490051 | | O_NOCTTY<br />

490052 | | O_TRUNC);<br />

490053 | //<br />

490054 | // Set to zero the bits that are not to be set from<br />

490055 | // the argument.<br />

490056 | //<br />

490057 | arg = (arg & ~mask);<br />

490058 | //<br />

490059 | // Set to zero the bit that *are* to be set.<br />

490060 | //<br />

490061 | ps->fd[fdn].fl_flags &= mask;<br />

490062 | //<br />

490063 | // Set the bits, already filtered inside the argument.<br />

490064 | //<br />

490065 | ps->fd[fdn].fl_flags |= arg;<br />

490066 | //<br />

490067 | return (0);<br />

490068 | default:<br />

490069 | errset (EINVAL); // Not implemented.<br />

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

490071 | }<br />

490072 |}<br />

104.4.7 kernel/fs/fd_lseek.c<br />

Si veda la sezione 103.3.7.<br />

500001 |#include <br />

500002 |#include <br />

500003 |#include <br />

500004 |//----------------------------------------------------------------------<br />

500005 |off_t<br />

500006 |fd_lseek (pid_t pid, int fdn, off_t offset, int whence)<br />

500007 |{<br />

500008 | inode_t *inode;<br />

500009 | file_t *file;<br />

500010 | fd_t *fd;<br />

500011 | off_t test_offset;<br />

500012 | //<br />

500013 | // Get file descriptor.<br />

500014 | //<br />

500015 | fd = fd_reference (pid, &fdn);<br />

500016 | if (fd == NULL ||<br />

500017 | fd->file == NULL ||<br />

500018 | fd->file->inode == NULL )<br />

500019 | {<br />

500020 | errset (EBADF); // Bad file descriptor.<br />

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

500022 | }<br />

500023 | //<br />

500024 | // Get file table item.<br />

500025 | //<br />

500026 | file = fd->file;<br />

500027 | //<br />

500028 | // Get inode.<br />

500029 | //<br />

500030 | inode = file->inode;<br />

500031 | //<br />

500032 | // Change position depending on the ‘whence’ parameter.<br />

500033 | //<br />

500034 | if (whence == SEEK_SET)<br />

500035 | {<br />

500036 | if (offset < 0)<br />

500037 | {<br />

500038 | errset (EINVAL); // Invalid argument.<br />

500039 | return ((off_t) -1);<br />

500040 | }<br />

500041 | else<br />

500042 | {<br />

500043 | fd->file->offset = offset;<br />

500044 | }<br />

500045 | }<br />

500046 | else if (whence == SEEK_CUR)<br />

500047 | {<br />

500048 | test_offset = fd->file->offset;<br />

500049 | test_offset += offset;<br />

500050 | if (test_offset < 0)<br />

500051 | {<br />

500052 | errset (EINVAL); // Invalid argument.<br />

500053 | return ((off_t) -1);<br />

500054 | }<br />

500055 | else<br />

500056 | {<br />

500057 | fd->file->offset = test_offset;<br />

500058 | }<br />

500059 | }<br />

500060 | else if (whence == SEEK_END)<br />

500061 | {<br />

500062 | test_offset = inode->size;<br />

500063 | test_offset += offset;<br />

500064 | if (test_offset < 0)<br />

500065 | {<br />

500066 | errset (EINVAL); // Invalid argument.<br />

500067 | return ((off_t) -1);<br />

500068 | }<br />

500069 | else<br />

500070 | {<br />

500071 | fd->file->offset = test_offset;<br />

500072 | }<br />

500073 | }<br />

500074 | else<br />

500075 | {<br />

500076 | errset (EINVAL); // Invalid argument.<br />

500077 | return ((off_t) -1);<br />

500078 | }<br />

500079 | //<br />

500080 | // Return the new file position.<br />

500081 | //<br />

500082 | return (fd->file->offset);<br />

500083 |}<br />

104.4.8 kernel/fs/fd_open.c<br />

Si veda la sezione 103.3.8.<br />

510001 |#include <br />

510002 |#include <br />

510003 |#include <br />

510004 |#include <br />

510005 |//----------------------------------------------------------------------<br />

510006 |int<br />

510007 |fd_open (pid_t pid, const char *path, int oflags, mode_t mode)<br />

510008 |{<br />

510009 | proc_t *ps;<br />

510010 | inode_t *inode;<br />

510011 | int status;<br />

510012 | file_t *file;<br />

510013 | fd_t *fd;<br />

510014 | int fdn;<br />

510015 | char full_path[PATH_MAX];<br />

510016 | int perm;<br />

510017 | tty_t *tty;<br />

510018 | mode_t umask;<br />

510019 | int errno_save;<br />

«<br />

«

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

Saved successfully!

Ooh no, something went wrong!