~l3on/ubuntu/lucid/apt/fix-917845

« back to all changes in this revision

Viewing changes to apt-pkg/contrib/mmap.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jason Gunthorpe
  • Date: 2001-08-18 17:21:59 UTC
  • Revision ID: james.westby@ubuntu.com-20010818172159-85f7g43wdzi9dwb5
Tags: 0.5.4
* M68k config.guess patch. Closes: #88913
* Bi-yearly test on OpenBSD and Solaris
* Doc updates. Closes: #89121, #89854, #99671, #98353, #95823, #93057,
        #97520, #102867, #101071, #102421, #101565, #98272, #106914,
        #105606, #105377
* Various cosmetic code updates. Closes: #89066, #89066, #89152
* Add "pre-auto" as an option for DSelect::Clean (run autoclean after
  update).
* More patches from Alfredo for Vendors and more SHA-1 stuff
* Fix for AJ's 'desire to remove perl-5.005' and possibly other
  similar situations. Closes: #56708, #59432
* no_proxy and ftp. Closes: #89671
* Philippe Batailler's man page patches.
* Fix for display bug. Closes: #92033, #93652, #98468
* Use more than 16bits for the dep ID. Some people ran out..
  Closes: #103020, #97809, #102951, #99974, #107362, #107395, #107362,
          #106911, #107395, #108968
* Reordered some things to make dante and FTP happier. Closes: #92757
* James R. Van Zandt's guide.sgml updates. Closes: #90027
* apt-ftparchive copes with no uncompressed package files + contents.
* French man pages from philippe batailler - well sort of. They 
  don't build yet..
* run-parts. Closes: #94286
* 'apt-cache policy' preferences debug tool.
* Whatever. Closes: #89762
* libstdc++ and HURD. Closes: #92025
* More apt-utils verbage. Closes: #86954
* Fliped comparision operator. Closes: #94618
* Used the right copyright file. Closes: #65691
* Randolph's G++3 patches. 
* Fixed no_proxy tokanizing. Closes: #100046
* Strip Config-Version when copying status to available. Closes: #97520
* Segfault with missing source files. Closes: #100325
* EINTR check. Closes: #102293
* Various changes to the locking metholodgy for --print-uris. 
  Closes: #100590
* Lame LD_LIBRARY_PATH thing. Closes: #98928
* apt-cache search searchs provide names too now. Closes: #98695
* Checksum and long lines problem. Closes: #106591
* .aptignr and empty files are just a warning. Closes: #97364  

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode: cpp; mode: fold -*-
 
2
// Description                                                          /*{{{*/
 
3
// $Id: mmap.cc,v 1.22 2001/05/27 05:19:30 jgg Exp $
 
4
/* ######################################################################
 
5
   
 
6
   MMap Class - Provides 'real' mmap or a faked mmap using read().
 
7
 
 
8
   MMap cover class.
 
9
 
 
10
   Some broken versions of glibc2 (libc6) have a broken definition
 
11
   of mmap that accepts a char * -- all other systems (and libc5) use
 
12
   void *. We can't safely do anything here that would be portable, so
 
13
   libc6 generates warnings -- which should be errors, g++ isn't properly
 
14
   strict.
 
15
   
 
16
   The configure test notes that some OS's have broken private mmap's
 
17
   so on those OS's we can't use mmap. This means we have to use
 
18
   configure to test mmap and can't rely on the POSIX
 
19
   _POSIX_MAPPED_FILES test.
 
20
   
 
21
   ##################################################################### */
 
22
                                                                        /*}}}*/
 
23
// Include Files                                                        /*{{{*/
 
24
#ifdef __GNUG__
 
25
#pragma implementation "apt-pkg/mmap.h"
 
26
#endif 
 
27
 
 
28
#define _BSD_SOURCE
 
29
#include <apt-pkg/mmap.h>
 
30
#include <apt-pkg/error.h>
 
31
 
 
32
#include <apti18n.h>
 
33
 
 
34
#include <sys/mman.h>
 
35
#include <sys/stat.h>
 
36
#include <unistd.h>
 
37
#include <fcntl.h>
 
38
                                                                        /*}}}*/
 
39
 
 
40
// MMap::MMap - Constructor                                             /*{{{*/
 
41
// ---------------------------------------------------------------------
 
42
/* */
 
43
MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
 
44
                     Base(0)
 
45
{
 
46
   if ((Flags & NoImmMap) != NoImmMap)
 
47
      Map(F);
 
48
}
 
49
                                                                        /*}}}*/
 
50
// MMap::MMap - Constructor                                             /*{{{*/
 
51
// ---------------------------------------------------------------------
 
52
/* */
 
53
MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0),
 
54
                     Base(0)
 
55
{
 
56
}
 
57
                                                                        /*}}}*/
 
58
// MMap::~MMap - Destructor                                             /*{{{*/
 
59
// ---------------------------------------------------------------------
 
60
/* */
 
61
MMap::~MMap()
 
62
{
 
63
   Close();
 
64
}
 
65
                                                                        /*}}}*/
 
66
// MMap::Map - Perform the mapping                                      /*{{{*/
 
67
// ---------------------------------------------------------------------
 
68
/* */
 
69
bool MMap::Map(FileFd &Fd)
 
70
{
 
71
   iSize = Fd.Size();
 
72
   
 
73
   // Set the permissions.
 
74
   int Prot = PROT_READ;
 
75
   int Map = MAP_SHARED;
 
76
   if ((Flags & ReadOnly) != ReadOnly)
 
77
      Prot |= PROT_WRITE;
 
78
   if ((Flags & Public) != Public)
 
79
      Map = MAP_PRIVATE;
 
80
   
 
81
   if (iSize == 0)
 
82
      return _error->Error(_("Can't mmap an empty file"));
 
83
   
 
84
   // Map it.
 
85
   Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0);
 
86
   if (Base == (void *)-1)
 
87
      return _error->Errno("mmap",_("Couldn't make mmap of %lu bytes"),iSize);
 
88
 
 
89
   return true;
 
90
}
 
91
                                                                        /*}}}*/
 
92
// MMap::Close - Close the map                                          /*{{{*/
 
93
// ---------------------------------------------------------------------
 
94
/* */
 
95
bool MMap::Close(bool DoSync)
 
96
{
 
97
   if ((Flags & UnMapped) == UnMapped || Base == 0 || iSize == 0)
 
98
      return true;
 
99
   
 
100
   if (DoSync == true)
 
101
      Sync();
 
102
   
 
103
   if (munmap((char *)Base,iSize) != 0)
 
104
      _error->Warning("Unable to munmap");
 
105
   
 
106
   iSize = 0;
 
107
   Base = 0;
 
108
   return true;
 
109
}
 
110
                                                                        /*}}}*/
 
111
// MMap::Sync - Syncronize the map with the disk                        /*{{{*/
 
112
// ---------------------------------------------------------------------
 
113
/* This is done in syncronous mode - the docs indicate that this will 
 
114
   not return till all IO is complete */
 
115
bool MMap::Sync()
 
116
{   
 
117
   if ((Flags & UnMapped) == UnMapped)
 
118
      return true;
 
119
   
 
120
#ifdef _POSIX_SYNCHRONIZED_IO   
 
121
   if ((Flags & ReadOnly) != ReadOnly)
 
122
      if (msync((char *)Base,iSize,MS_SYNC) != 0)
 
123
         return _error->Errno("msync","Unable to write mmap");
 
124
#endif   
 
125
   return true;
 
126
}
 
127
                                                                        /*}}}*/
 
128
// MMap::Sync - Syncronize a section of the file to disk                /*{{{*/
 
129
// ---------------------------------------------------------------------
 
130
/* */
 
131
bool MMap::Sync(unsigned long Start,unsigned long Stop)
 
132
{
 
133
   if ((Flags & UnMapped) == UnMapped)
 
134
      return true;
 
135
   
 
136
#ifdef _POSIX_SYNCHRONIZED_IO
 
137
   unsigned long PSize = sysconf(_SC_PAGESIZE);
 
138
   if ((Flags & ReadOnly) != ReadOnly)
 
139
      if (msync((char *)Base+(int)(Start/PSize)*PSize,Stop - Start,MS_SYNC) != 0)
 
140
         return _error->Errno("msync","Unable to write mmap");
 
141
#endif   
 
142
   return true;
 
143
}
 
144
                                                                        /*}}}*/
 
145
 
 
146
// DynamicMMap::DynamicMMap - Constructor                               /*{{{*/
 
147
// ---------------------------------------------------------------------
 
148
/* */
 
149
DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) : 
 
150
             MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace)
 
151
{
 
152
   if (_error->PendingError() == true)
 
153
      return;
 
154
   
 
155
   unsigned long EndOfFile = Fd->Size();
 
156
   if (EndOfFile > WorkSpace)
 
157
      WorkSpace = EndOfFile;
 
158
   else
 
159
   {
 
160
      Fd->Seek(WorkSpace);
 
161
      char C = 0;
 
162
      Fd->Write(&C,sizeof(C));
 
163
   }
 
164
   
 
165
   Map(F);
 
166
   iSize = EndOfFile;
 
167
}
 
168
                                                                        /*}}}*/
 
169
// DynamicMMap::DynamicMMap - Constructor for a non-file backed map     /*{{{*/
 
170
// ---------------------------------------------------------------------
 
171
/* This is just a fancy malloc really.. */
 
172
DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) :
 
173
             MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace)
 
174
{
 
175
   if (_error->PendingError() == true)
 
176
      return;
 
177
   
 
178
   Base = new unsigned char[WorkSpace];
 
179
   memset(Base,0,WorkSpace);
 
180
   iSize = 0;
 
181
}
 
182
                                                                        /*}}}*/
 
183
// DynamicMMap::~DynamicMMap - Destructor                               /*{{{*/
 
184
// ---------------------------------------------------------------------
 
185
/* We truncate the file to the size of the memory data set */
 
186
DynamicMMap::~DynamicMMap()
 
187
{
 
188
   if (Fd == 0)
 
189
   {
 
190
      delete [] (unsigned char *)Base;
 
191
      return;
 
192
   }
 
193
   
 
194
   unsigned long EndOfFile = iSize;
 
195
   iSize = WorkSpace;
 
196
   Close(false);
 
197
   ftruncate(Fd->Fd(),EndOfFile);
 
198
}  
 
199
                                                                        /*}}}*/
 
200
// DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space   /*{{{*/
 
201
// ---------------------------------------------------------------------
 
202
/* This allocates a block of memory aligned to the given size */
 
203
unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln)
 
204
{
 
205
   unsigned long Result = iSize;
 
206
   if (Aln != 0)
 
207
      Result += Aln - (iSize%Aln);
 
208
   
 
209
   iSize = Result + Size;
 
210
   
 
211
   // Just in case error check
 
212
   if (Result + Size > WorkSpace)
 
213
   {
 
214
      _error->Error("Dynamic MMap ran out of room");
 
215
      return 0;
 
216
   }
 
217
 
 
218
   return Result;
 
219
}
 
220
                                                                        /*}}}*/
 
221
// DynamicMMap::Allocate - Pooled aligned allocation                    /*{{{*/
 
222
// ---------------------------------------------------------------------
 
223
/* This allocates an Item of size ItemSize so that it is aligned to its
 
224
   size in the file. */
 
225
unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
 
226
{   
 
227
   // Look for a matching pool entry
 
228
   Pool *I;
 
229
   Pool *Empty = 0;
 
230
   for (I = Pools; I != Pools + PoolCount; I++)
 
231
   {
 
232
      if (I->ItemSize == 0)
 
233
         Empty = I;
 
234
      if (I->ItemSize == ItemSize)
 
235
         break;
 
236
   }
 
237
 
 
238
   // No pool is allocated, use an unallocated one
 
239
   if (I == Pools + PoolCount)
 
240
   {
 
241
      // Woops, we ran out, the calling code should allocate more.
 
242
      if (Empty == 0)
 
243
      {
 
244
         _error->Error("Ran out of allocation pools");
 
245
         return 0;
 
246
      }
 
247
      
 
248
      I = Empty;
 
249
      I->ItemSize = ItemSize;
 
250
      I->Count = 0;
 
251
   }
 
252
   
 
253
   // Out of space, allocate some more
 
254
   if (I->Count == 0)
 
255
   {
 
256
      I->Count = 20*1024/ItemSize;
 
257
      I->Start = RawAllocate(I->Count*ItemSize,ItemSize);
 
258
   }   
 
259
 
 
260
   I->Count--;
 
261
   unsigned long Result = I->Start;
 
262
   I->Start += ItemSize;  
 
263
   return Result/ItemSize;
 
264
}
 
265
                                                                        /*}}}*/
 
266
// DynamicMMap::WriteString - Write a string to the file                /*{{{*/
 
267
// ---------------------------------------------------------------------
 
268
/* Strings are not aligned to anything */
 
269
unsigned long DynamicMMap::WriteString(const char *String,
 
270
                                       unsigned long Len)
 
271
{
 
272
   unsigned long Result = iSize;
 
273
   // Just in case error check
 
274
   if (Result + Len > WorkSpace)
 
275
   {
 
276
      _error->Error("Dynamic MMap ran out of room");
 
277
      return 0;
 
278
   }   
 
279
   
 
280
   if (Len == (unsigned long)-1)
 
281
      Len = strlen(String);
 
282
   iSize += Len + 1;
 
283
   memcpy((char *)Base + Result,String,Len);
 
284
   ((char *)Base)[Result + Len] = 0;
 
285
   return Result;
 
286
}
 
287
                                                                        /*}}}*/