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 />
«