Res initialize glitch
[ntk/apt.git] / apt-pkg / contrib / fileutl.cc
CommitLineData
578bfd0a
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
f55a958f 3// $Id: fileutl.cc,v 1.2 1998/07/04 05:57:41 jgg Exp $
578bfd0a
AL
4/* ######################################################################
5
6 File Utilities
7
8 CopyFile - Buffered copy of a single file
9 GetLock - dpkg compatible lock file manipulation (fcntl)
10
11 This source is placed in the Public Domain, do with it what you will
12 It was originally written by Jason Gunthorpe.
13
14 ##################################################################### */
15 /*}}}*/
16// Include Files /*{{{*/
f55a958f 17#include <pkglib/fileutl.h>
578bfd0a
AL
18#include <pkglib/error.h>
19
20#include <unistd.h>
21#include <sys/stat.h>
22#include <sys/fcntl.h>
23#include <sys/types.h>
24 /*}}}*/
25
26// CopyFile - Buffered copy of a file /*{{{*/
27// ---------------------------------------------------------------------
28/* The caller is expected to set things so that failure causes erasure */
29bool CopyFile(File From,File To)
30{
31 if (From.IsOpen() == false || To.IsOpen() == false)
32 return false;
33
34 // Buffered copy between fds
35 unsigned char *Buf = new unsigned char[64000];
36 long Size;
37 while ((Size = read(From.Fd(),Buf,64000)) > 0)
38 {
39 if (To.Write(Buf,Size) == false)
40 {
41 delete [] Buf;
42 return false;
43 }
44 }
45
46 delete [] Buf;
47 return true;
48}
49 /*}}}*/
50// GetLock - Gets a lock file /*{{{*/
51// ---------------------------------------------------------------------
52/* This will create an empty file of the given name and lock it. Once this
53 is done all other calls to GetLock in any other process will fail with
54 -1. The return result is the fd of the file, the call should call
55 close at some time. */
56int GetLock(string File,bool Errors)
57{
58 int FD = open(File.c_str(),O_RDWR | O_CREAT | O_TRUNC,0640);
59 if (FD < 0)
60 {
61 if (Errors == true)
62 _error->Errno("open","Could not open lock file %s",File.c_str());
63 return -1;
64 }
65
66 // Aquire a write lock
67 struct flock fl;
68 fl.l_type= F_WRLCK;
69 fl.l_whence= SEEK_SET;
70 fl.l_start= 0;
71 fl.l_len= 1;
72 if (fcntl(FD,F_SETLK,&fl) == -1)
73 {
74 if (Errors == true)
75 _error->Errno("open","Could not get lock %s",File.c_str());
76 close(FD);
77 return -1;
78 }
79
80 return FD;
81}
82 /*}}}*/
83// FileExists - Check if a file exists /*{{{*/
84// ---------------------------------------------------------------------
85/* */
86bool FileExists(string File)
87{
88 struct stat Buf;
89 if (stat(File.c_str(),&Buf) != 0)
90 return false;
91 return true;
92}
93 /*}}}*/
94// SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/
95// ---------------------------------------------------------------------
96/* We return / on failure. */
97string SafeGetCWD()
98{
99 // Stash the current dir.
100 char S[300];
101 S[0] = 0;
102 if (getcwd(S,sizeof(S)) == 0)
103 return "/";
104 return S;
105}
106 /*}}}*/
107
108// File::File - Open a file /*{{{*/
109// ---------------------------------------------------------------------
110/* The most commonly used open mode combinations are given with Mode */
111File::File(string FileName,OpenMode Mode, unsigned long Perms)
112{
113 Flags = 0;
114 switch (Mode)
115 {
116 case ReadOnly:
117 iFd = open(FileName.c_str(),O_RDONLY);
118 break;
119
120 case WriteEmpty:
121 unlink(FileName.c_str());
122 iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms);
123 break;
124
125 case WriteExists:
126 iFd = open(FileName.c_str(),O_RDWR);
127 break;
128 }
129
130 if (iFd < 0)
131 _error->Errno("open","Could not open file %s",FileName.c_str());
132 else
133 this->FileName = FileName;
134}
135 /*}}}*/
136// File::~File - Closes the file /*{{{*/
137// ---------------------------------------------------------------------
138/* If the proper modes are selected then we close the Fd and possibly
139 unlink the file on error. */
140File::~File()
141{
142 Close();
143}
144 /*}}}*/
145// File::Read - Read a bit of the file /*{{{*/
146// ---------------------------------------------------------------------
147/* */
148bool File::Read(void *To,unsigned long Size)
149{
150 if (read(iFd,To,Size) != (signed)Size)
151 {
152 Flags |= Fail;
153 return _error->Errno("read","Read error");
154 }
155
156 return true;
157}
158 /*}}}*/
159// File::Write - Write to the file /*{{{*/
160// ---------------------------------------------------------------------
161/* */
162bool File::Write(void *From,unsigned long Size)
163{
164 if (write(iFd,From,Size) != (signed)Size)
165 {
166 Flags |= Fail;
167 return _error->Errno("write","Write error");
168 }
169
170 return true;
171}
172 /*}}}*/
173// File::Seek - Seek in the file /*{{{*/
174// ---------------------------------------------------------------------
175/* */
176bool File::Seek(unsigned long To)
177{
178 if (lseek(iFd,To,SEEK_SET) != (signed)To)
179 {
180 Flags |= Fail;
181 return _error->Error("Unable to seek to %u",To);
182 }
183
184 return true;
185}
186 /*}}}*/
187// File::Size - Return the size of the file /*{{{*/
188// ---------------------------------------------------------------------
189/* */
190unsigned long File::Size()
191{
192 struct stat Buf;
193 if (fstat(iFd,&Buf) != 0)
194 return _error->Errno("fstat","Unable to determine the file size");
195 return Buf.st_size;
196}
197 /*}}}*/
198// File::Close - Close the file if the close flag is set /*{{{*/
199// ---------------------------------------------------------------------
200/* */
201bool File::Close()
202{
203 bool Res = true;
204 if ((Flags & AutoClose) == AutoClose)
205 if (close(iFd) != 0)
206 Res &= _error->Errno("close","Problem closing the file");
207
208 if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail &&
209 FileName.empty() == false)
210 if (unlink(FileName.c_str()) != 0)
211 Res &= _error->Warning("unlnk","Problem unlinking the file");
212 return Res;
213}
214 /*}}}*/