xref: /AOO41X/main/shell/source/unix/sysshell/recently_used_file.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_shell.hxx"
30 
31 #ifndef INCLUDED_RECENTLY_USED_FILE
32 #include "recently_used_file.hxx"
33 #endif
34 #include <rtl/ustring.hxx>
35 #include <osl/process.h>
36 #include <osl/security.hxx>
37 #include <osl/thread.h>
38 #include <osl/file.hxx>
39 
40 #include <sys/file.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 
44 #include <unistd.h>
45 
46 const rtl::OUString RECENTLY_USED_FILE_NAME = rtl::OUString::createFromAscii(".recently-used");
47 const rtl::OUString SLASH = rtl::OUString::createFromAscii("/");
48 
49 namespace /* private */ {
50 
51 inline void ensure_final_slash(/*inout*/ rtl::OUString& path)
52 {
53     if ((path.getLength() > 0) &&
54 		(SLASH.pData->buffer[0] != path.pData->buffer[path.getLength() - 1]))
55         path += SLASH;
56 }
57 
58 } // namespace private
59 
60 //------------------------------------------------
61 recently_used_file::recently_used_file() :
62     file_(NULL)
63 {
64     osl::Security sec;
65     rtl::OUString homedir_url;
66 
67     if (sec.getHomeDir(homedir_url))
68     {
69 		rtl::OUString homedir;
70 		osl::FileBase::getSystemPathFromFileURL(homedir_url, homedir);
71 
72         rtl::OUString rufn = homedir;
73         ensure_final_slash(rufn);
74         rufn += RECENTLY_USED_FILE_NAME;
75 
76         rtl::OString tmp =
77             rtl::OUStringToOString(rufn, osl_getThreadTextEncoding());
78 
79         file_ = fopen(tmp.getStr(), "r+");
80 
81         /* create if not exist */
82         if (NULL == file_) {
83             mode_t umask_ = umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
84             file_ = fopen(tmp.getStr(), "w+");
85             umask(umask_);
86         }
87 
88         if (NULL == file_)
89             throw "I/O error opening ~/.recently-used";
90 
91         if (lockf(fileno(file_), F_LOCK, 0) != 0)
92         {
93             fclose(file_);
94             throw "Cannot lock ~/.recently-used";
95         }
96     }
97     else
98         throw "Cannot determine user home directory";
99 }
100 
101 //------------------------------------------------
102 recently_used_file::~recently_used_file()
103 {
104 	lockf(fileno(file_), F_ULOCK, 0);
105     fclose(file_);
106 }
107 
108 //------------------------------------------------
109 void recently_used_file::reset() const
110 {
111     rewind(file_);
112 }
113 
114 //------------------------------------------------
115 void recently_used_file::truncate(off_t length)
116 {
117     if (ftruncate(fileno(file_), length) == -1)
118         throw "I/O error: ftruncate failed";
119 }
120 
121 //------------------------------------------------
122 size_t recently_used_file::read(char* buffer, size_t size) const
123 {
124 	size_t	r = fread(reinterpret_cast<void*>(buffer), sizeof(char), size, file_);
125 
126 	if ((r < size) && ferror(file_))
127 		throw "I/O error: read failed";
128 
129     return r;
130 }
131 
132 //----------------------------
133 void recently_used_file::write(const char* buffer, size_t size) const
134 {
135 	if (size != fwrite(reinterpret_cast<const void*>(buffer), sizeof(char), size, file_))
136 		throw "I/O error: write failed";
137 }
138 
139 //----------------------------
140 bool recently_used_file::eof() const
141 {
142 	return feof(file_);
143 }
144 
145 
146 
147 
148