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 <sys/types.h>
16 : #include <sys/stat.h>
17 : #include <fcntl.h>
18 : #include <unistd.h>
19 :
20 : #include "okssystem/File.hpp"
21 : #include "okssystem/Descriptor.hpp"
22 : #include "okssystem/exceptions.hpp"
23 :
24 : #include "ers/ers.hpp"
25 :
26 0 : int OksSystem::Descriptor::flags(bool read_mode, bool write_mode) {
27 0 : if (read_mode && write_mode) {
28 : return O_RDWR | O_CREAT;
29 : }
30 0 : if (read_mode) {
31 : return O_RDONLY;
32 : }
33 0 : if (write_mode) {
34 0 : return O_WRONLY | O_CREAT;
35 : }
36 : return 0;
37 : } // flags
38 :
39 :
40 0 : OksSystem::Descriptor::Descriptor(const File * file, int i_flags, mode_t perm) {
41 0 : ERS_ASSERT( file )
42 0 : open(file,i_flags,perm);
43 0 : } // Descriptor
44 :
45 0 : OksSystem::Descriptor::~Descriptor() {
46 0 : if (m_fd>=0) {
47 0 : close_safe();
48 : }
49 0 : } // ~Descriptor
50 :
51 0 : OksSystem::Descriptor::operator int() const throw() {
52 0 : return m_fd;
53 : } // operator int()
54 :
55 :
56 : /** Opens the descriptor
57 : * \param file pointer to the file to open
58 : * \param flags open flags
59 : * \param perm the permissions
60 : */
61 :
62 0 : void OksSystem::Descriptor::open(const File * file, int i_flags, mode_t perm) {
63 0 : ERS_ASSERT( file )
64 0 : bool alreadyExists = file->exists();
65 0 : m_fd = ::open(*file,i_flags,perm);
66 0 : m_name = file->full_name();
67 0 : if (m_fd<0) throw OksSystem::OpenFileIssue( ERS_HERE, errno, m_name.c_str() );
68 0 : if((alreadyExists == false) && ((i_flags & O_CREAT) != 0)) {
69 0 : ::fchmod(m_fd, perm);
70 : }
71 0 : } // open
72 :
73 : /** Closes the descriptor
74 : * \param file optional pointer to the file that we close (used for pretty printing potential exceptions).
75 : * \exception OksSystem::CloseFail if there is problem in the \c close okssystem call
76 : */
77 :
78 0 : void OksSystem::Descriptor::close() {
79 0 : const int status = ::close(m_fd);
80 0 : if (status<0) {
81 0 : throw OksSystem::CloseFileIssue( ERS_HERE, errno, m_name.c_str() );
82 : } //
83 0 : m_fd = -1 ;
84 0 : } // close
85 :
86 :
87 : /** Closes a descriptor safely, i.e without throwing exceptions
88 : * If there is a proble, the information is sent to the warning stream
89 : */
90 :
91 0 : void OksSystem::Descriptor::close_safe() throw() {
92 0 : const int status = ::close(m_fd);
93 0 : if (status<0) {
94 0 : ers::warning( OksSystem::CloseFileIssue( ERS_HERE, errno, m_name.c_str() ) );
95 : } // if
96 0 : } // close_safe
97 :
98 0 : int OksSystem::Descriptor::read(void* buffer, size_t number) const {
99 0 : ssize_t status = ::read(m_fd,buffer,number);
100 0 : if (status<0) throw OksSystem::ReadIssue( ERS_HERE, errno, m_name.c_str() );
101 0 : return status;
102 : } // read
103 :
104 :
105 0 : int OksSystem::Descriptor::write(const void* buffer, size_t number) const {
106 0 : ssize_t status = ::write(m_fd,buffer,number);
107 0 : if (status<0) throw OksSystem::WriteIssue( ERS_HERE, errno, m_name.c_str() );
108 0 : return status;
109 : } // write
110 :
111 0 : int OksSystem::Descriptor::fd() const throw() {
112 0 : return m_fd;
113 : }
114 :
115 : /**
116 : * \brief It flags the file descriptor to be closed after any call to the exec okssystem function.
117 : */
118 :
119 0 : void OksSystem::Descriptor::closeOnExec() {
120 :
121 0 : bool success = false;
122 0 : int storeErrno = 0;
123 :
124 0 : int oldFlags = ::fcntl(m_fd, F_GETFD);
125 0 : if(oldFlags != -1) {
126 0 : int newFlags = ::fcntl(m_fd, F_SETFD, oldFlags|FD_CLOEXEC);
127 0 : if(newFlags == -1) {
128 0 : storeErrno = errno;
129 : } else {
130 : success = true;
131 : }
132 : } else {
133 0 : storeErrno = errno;
134 : }
135 :
136 0 : if(!success) {
137 0 : std::string eMsg = "File descriptor for file " + m_name +
138 0 : " will not be closed after exec. Reason: " + std::string(::strerror(storeErrno));
139 0 : throw OksSystem::OksSystemCallIssue(ERS_HERE, storeErrno, "fcntl", eMsg.c_str());
140 0 : }
141 :
142 0 : }
|