Line data Source code
1 : // DUNE DAQ modification notice:
2 : // This file has been modified from the original ATLAS system source for the DUNE DAQ project.
3 : // Fork baseline commit: system-00-00-20 (2020-09-25).
4 : // Renamed since fork: yes (from src/Descriptor.cxx to src/Descriptor.cpp).
5 :
6 : /*
7 : * Descriptor.cxx
8 : * OksSystem
9 : *
10 : * Created by Matthias Wiesmann on 08.02.05.
11 : * Copyright 2005 CERN. All rights reserved.
12 : *
13 : */
14 :
15 : #include <fcntl.h>
16 : #include <sys/stat.h>
17 : #include <sys/types.h>
18 : #include <unistd.h>
19 :
20 : #include "okssystem/Descriptor.hpp"
21 : #include "okssystem/File.hpp"
22 : #include "okssystem/exceptions.hpp"
23 :
24 : #include "ers/ers.hpp"
25 :
26 : int
27 0 : OksSystem::Descriptor::flags(bool read_mode, bool write_mode)
28 : {
29 0 : if (read_mode && write_mode) {
30 : return O_RDWR | O_CREAT;
31 : }
32 0 : if (read_mode) {
33 : return O_RDONLY;
34 : }
35 0 : if (write_mode) {
36 0 : return O_WRONLY | O_CREAT;
37 : }
38 : return 0;
39 : } // flags
40 :
41 0 : OksSystem::Descriptor::Descriptor(const File* file, int i_flags, mode_t perm)
42 : {
43 0 : ERS_ASSERT(file)
44 0 : open(file, i_flags, perm);
45 0 : } // Descriptor
46 :
47 0 : OksSystem::Descriptor::~Descriptor()
48 : {
49 0 : if (m_fd >= 0) {
50 0 : close_safe();
51 : }
52 0 : } // ~Descriptor
53 :
54 0 : OksSystem::Descriptor::operator int() const throw()
55 : {
56 0 : return m_fd;
57 : } // operator int()
58 :
59 : /** Opens the descriptor
60 : * \param file pointer to the file to open
61 : * \param flags open flags
62 : * \param perm the permissions
63 : */
64 :
65 : void
66 0 : OksSystem::Descriptor::open(const File* file, int i_flags, mode_t perm)
67 : {
68 0 : ERS_ASSERT(file)
69 0 : bool alreadyExists = file->exists();
70 0 : m_fd = ::open(*file, i_flags, perm);
71 0 : m_name = file->full_name();
72 0 : if (m_fd < 0)
73 0 : throw OksSystem::OpenFileIssue(ERS_HERE, errno, m_name.c_str());
74 0 : if ((alreadyExists == false) && ((i_flags & O_CREAT) != 0)) {
75 0 : ::fchmod(m_fd, perm);
76 : }
77 0 : } // open
78 :
79 : /** Closes the descriptor
80 : * \param file optional pointer to the file that we close (used for pretty printing potential exceptions).
81 : * \exception OksSystem::CloseFail if there is problem in the \c close okssystem call
82 : */
83 :
84 : void
85 0 : OksSystem::Descriptor::close()
86 : {
87 0 : const int status = ::close(m_fd);
88 0 : if (status < 0) {
89 0 : throw OksSystem::CloseFileIssue(ERS_HERE, errno, m_name.c_str());
90 : } //
91 0 : m_fd = -1;
92 0 : } // close
93 :
94 : /** Closes a descriptor safely, i.e without throwing exceptions
95 : * If there is a proble, the information is sent to the warning stream
96 : */
97 :
98 : void
99 0 : OksSystem::Descriptor::close_safe() throw()
100 : {
101 0 : const int status = ::close(m_fd);
102 0 : if (status < 0) {
103 0 : ers::warning(OksSystem::CloseFileIssue(ERS_HERE, errno, m_name.c_str()));
104 : } // if
105 0 : } // close_safe
106 :
107 : int
108 0 : OksSystem::Descriptor::read(void* buffer, size_t number) const
109 : {
110 0 : ssize_t status = ::read(m_fd, buffer, number);
111 0 : if (status < 0)
112 0 : throw OksSystem::ReadIssue(ERS_HERE, errno, m_name.c_str());
113 0 : return status;
114 : } // read
115 :
116 : int
117 0 : OksSystem::Descriptor::write(const void* buffer, size_t number) const
118 : {
119 0 : ssize_t status = ::write(m_fd, buffer, number);
120 0 : if (status < 0)
121 0 : throw OksSystem::WriteIssue(ERS_HERE, errno, m_name.c_str());
122 0 : return status;
123 : } // write
124 :
125 : int
126 0 : OksSystem::Descriptor::fd() const throw()
127 : {
128 0 : return m_fd;
129 : }
130 :
131 : /**
132 : * \brief It flags the file descriptor to be closed after any call to the exec okssystem function.
133 : */
134 :
135 : void
136 0 : OksSystem::Descriptor::closeOnExec()
137 : {
138 :
139 0 : bool success = false;
140 0 : int storeErrno = 0;
141 :
142 0 : int oldFlags = ::fcntl(m_fd, F_GETFD);
143 0 : if (oldFlags != -1) {
144 0 : int newFlags = ::fcntl(m_fd, F_SETFD, oldFlags | FD_CLOEXEC);
145 0 : if (newFlags == -1) {
146 0 : storeErrno = errno;
147 : } else {
148 : success = true;
149 : }
150 : } else {
151 0 : storeErrno = errno;
152 : }
153 :
154 0 : if (!success) {
155 0 : std::string eMsg = "File descriptor for file " + m_name +
156 0 : " will not be closed after exec. Reason: " + std::string(::strerror(storeErrno));
157 0 : throw OksSystem::OksSystemCallIssue(ERS_HERE, storeErrno, "fcntl", eMsg.c_str());
158 0 : }
159 0 : }
|