1 /***************************************************************************
2  *  lib/io/syscall_file.cpp
3  *
4  *  Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  *  Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de>
7  *  Copyright (C) 2008, 2010 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
8  *  Copyright (C) 2010 Johannes Singler <singler@kit.edu>
9  *
10  *  Distributed under the Boost Software License, Version 1.0.
11  *  (See accompanying file LICENSE_1_0.txt or copy at
12  *  http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #include <stxxl/bits/common/error_handling.h>
16 #include <stxxl/bits/common/mutex.h>
17 #include <stxxl/bits/config.h>
18 #include <stxxl/bits/io/iostats.h>
19 #include <stxxl/bits/io/request.h>
20 #include <stxxl/bits/io/request_interface.h>
21 #include <stxxl/bits/io/syscall_file.h>
22 #include "ufs_platform.h"
23 
24 STXXL_BEGIN_NAMESPACE
25 
serve(void * buffer,offset_type offset,size_type bytes,request::request_type type)26 void syscall_file::serve(void* buffer, offset_type offset, size_type bytes,
27                          request::request_type type)
28 {
29     scoped_mutex_lock fd_lock(fd_mutex);
30 
31     char* cbuffer = static_cast<char*>(buffer);
32 
33     stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE);
34 
35     while (bytes > 0)
36     {
37         off_t rc = ::lseek(file_des, offset, SEEK_SET);
38         if (rc < 0)
39         {
40             STXXL_THROW_ERRNO
41                 (io_error,
42                 " this=" << this <<
43                 " call=::lseek(fd,offset,SEEK_SET)" <<
44                 " path=" << filename <<
45                 " fd=" << file_des <<
46                 " offset=" << offset <<
47                 " buffer=" << cbuffer <<
48                 " bytes=" << bytes <<
49                 " type=" << ((type == request::READ) ? "READ" : "WRITE") <<
50                 " rc=" << rc);
51         }
52 
53         if (type == request::READ)
54         {
55 #if STXXL_MSVC
56             assert(bytes <= std::numeric_limits<unsigned int>::max());
57             if ((rc = ::read(file_des, cbuffer, (unsigned int)bytes)) <= 0)
58 #else
59             if ((rc = ::read(file_des, cbuffer, bytes)) <= 0)
60 #endif
61             {
62                 STXXL_THROW_ERRNO
63                     (io_error,
64                     " this=" << this <<
65                     " call=::read(fd,buffer,bytes)" <<
66                     " path=" << filename <<
67                     " fd=" << file_des <<
68                     " offset=" << offset <<
69                     " buffer=" << buffer <<
70                     " bytes=" << bytes <<
71                     " type=" << "READ" <<
72                     " rc=" << rc);
73             }
74             bytes = (size_type)(bytes - rc);
75             offset += rc;
76             cbuffer += rc;
77 
78             if (bytes > 0 && offset == this->_size())
79             {
80                 // read request extends past end-of-file
81                 // fill reminder with zeroes
82                 memset(cbuffer, 0, bytes);
83                 bytes = 0;
84             }
85         }
86         else
87         {
88 #if STXXL_MSVC
89             assert(bytes <= std::numeric_limits<unsigned int>::max());
90             if ((rc = ::write(file_des, cbuffer, (unsigned int)bytes)) <= 0)
91 #else
92             if ((rc = ::write(file_des, cbuffer, bytes)) <= 0)
93 #endif
94             {
95                 STXXL_THROW_ERRNO
96                     (io_error,
97                     " this=" << this <<
98                     " call=::write(fd,buffer,bytes)" <<
99                     " path=" << filename <<
100                     " fd=" << file_des <<
101                     " offset=" << offset <<
102                     " buffer=" << buffer <<
103                     " bytes=" << bytes <<
104                     " type=" << "WRITE" <<
105                     " rc=" << rc);
106             }
107             bytes = (size_type)(bytes - rc);
108             offset += rc;
109             cbuffer += rc;
110         }
111     }
112 }
113 
io_type() const114 const char* syscall_file::io_type() const
115 {
116     return "syscall";
117 }
118 
119 STXXL_END_NAMESPACE
120 // vim: et:ts=4:sw=4
121