1 //------------------------------------------------------------------------------
2 // emTmpFile.h
3 //
4 // Copyright (C) 2006-2008,2016,2020 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20 
21 #ifndef emTmpFile_h
22 #define emTmpFile_h
23 
24 #ifndef emModel_h
25 #include <emCore/emModel.h>
26 #endif
27 
28 #ifndef emMiniIpc_h
29 #include <emCore/emMiniIpc.h>
30 #endif
31 
32 
33 //==============================================================================
34 //================================= emTmpFile ==================================
35 //==============================================================================
36 
37 class emTmpFile : public emUncopyable {
38 
39 public:
40 
41 	// An object of this class can invent and hold the path of a temporary
42 	// file (or directory). The file (or directory tree) is deleted
43 	// automatically by the destructor. But the file is not created by this.
44 
45 	emTmpFile();
46 		// Construct with an empty path.
47 
48 	emTmpFile(emRootContext & rootContext, const char * postfix=NULL);
49 		// Like Setup.
50 
51 	emTmpFile(const emString & customPath);
52 		// Like SetupCustomPath.
53 
54 	~emTmpFile();
55 		// Like Discard.
56 
57 	void TrySetup(emRootContext & rootContext, const char * postfix=NULL);
58 	void Setup(emRootContext & rootContext, const char * postfix=NULL);
59 		// Invent and set a new path for a temporary file or directory,
60 		// which does not yet exist. Before that, Discard is called.
61 		// On error, the first version throws an emException, and the
62 		// second version calls emFatalError.
63 		//
64 		// *** DANGER ***
65 		// The path is invented via an emTmpFileMaster. Please read the
66 		// comments on emTmpFileMaster::TryInventPath.
67 		//
68 		// Arguments:
69 		//   rootContext - The root context. The context must live
70 		//                 longer than this emTmpFile object.
71 		//   postfix     - A postfix to be added to the end of the path
72 		//                 (file name suffix), or NULL.
73 
74 	void SetupCustomPath(const emString & customPath);
75 		// Like Setup, but use the given path.
76 
77 	const emString & GetPath() const;
78 		// Get the path of the temporary file.
79 
80 	void Discard();
81 		// If the path is not empty, the file or directory tree is
82 		// deleted, and the path is set empty.
83 
84 private:
85 
86 	emString Path;
87 };
88 
GetPath()89 inline const emString & emTmpFile::GetPath() const
90 {
91 	return Path;
92 }
93 
94 
95 //==============================================================================
96 //============================== emTmpFileMaster ===============================
97 //==============================================================================
98 
99 class emTmpFileMaster : public emModel {
100 
101 public:
102 
103 	// Class for a central instance inventing temporary file paths, and for
104 	// cleaning up.
105 
106 	static emRef<emTmpFileMaster> Acquire(emRootContext & rootContext);
107 		// Acquire the emTmpFileMaster.
108 
109 	emString TryInventPath(const char * postfix=NULL);
110 		// Invent a path for a temporary file or directory which does
111 		// not yet exist. The path ends with the given postfix, and it
112 		// lies in a special directory which is created solely for this
113 		// emTmpFileMaster. That directory and all its contents are
114 		// deleted on destruction of this emTmpFileMaster (= destruction
115 		// of root context). If that deletion does not take place
116 		// because of a program crash or so, the deletion is performed
117 		// at the next call to TryInventPath(..) if it is a process
118 		// run by the same user on the same host. An emMiniIpcServer is
119 		// managed to find out whether the emTmpFileMaster for a
120 		// directory still exists.
121 		//
122 		// *** DANGER ***
123 		// If it ever fails to access the emMiniIpcServer of an existing
124 		// emTmpFileMaster from any process of the same user and host
125 		// for some reason, the files are deleted falsely. Therefore,
126 		// the temporary files should not be too valuable! And besides,
127 		// no one else should ever create a file in the directory, than
128 		// those who use a path invented with this method.
129 
130 protected:
131 
132 	emTmpFileMaster(emContext & context, const emString & name);
133 
134 	virtual ~emTmpFileMaster();
135 
136 private:
137 
138 	static emString GetCommonPath();
139 	void TryDeleteDeadDirectories();
140 	void TryStartOwnDirectory();
141 
142 	class IpcServerClass : public emMiniIpcServer {
143 	public:
144 		IpcServerClass(emScheduler & scheduler);
145 	protected:
146 		virtual void OnReception(int argc, const char * const argv[]);
147 	};
148 
149 	IpcServerClass IpcServer;
150 	emString DirPath;
151 	unsigned FileNameCounter;
152 	static const char * DirNameEnding;
153 };
154 
155 
156 #endif
157