Specify permissions (0644) when creating the program image file
[remote/remote-mci.git] / mcs / FileDescriptor.cc
bloba5a76de78717b9385262489f66c7c7919cfe189d
1 #include "FileDescriptor.h"
2 #include "macros.h"
4 namespace remote { namespace mcs {
6 void FileDescriptor::serviceLoop()
8 unsigned int i, instanceCount;
9 int f;
10 filedescriptorsbyfd_t::iterator fileDescriptorIterator;
11 // register the timeout handler
12 signal( SIGALRM, timeoutHandler );
13 ignoreBrokenPipeSignals();
17 instanceCount = instances.size();
18 pollfd fdmap[instanceCount];
19 FileDescriptor::buildPollMap(fdmap);
20 if ( poll(fdmap,instanceCount,-1) < 0)
22 __THROW__("Error in poll!");
25 try
27 // look for activity on any sockets
28 for ( i = 0; i < instanceCount; i++ )
30 if ( fdmap[i].revents )
32 f = fdmap[i].fd;
33 fileDescriptorIterator = instances.find(f);
34 if (fileDescriptorIterator != instances.end())
36 fileDescriptorIterator->second->handleEvent(fdmap[i].revents);
41 catch (remote::protocols::MMSException e)
43 clearTimeout();
44 log("Exception: %s\n",e.what());
45 fileDescriptorIterator->second->clearTimeout();
46 fileDescriptorIterator->second->destroy(false);
49 while( true );
52 FileDescriptor::FileDescriptor(int p_fd)
54 clearTimeout();
55 fd = p_fd;
56 log("Opened fd %i\n",fd);
57 instances[fd] = this;
60 void FileDescriptor::buildPollMap(pollfd* map)
62 int j = 0;
63 filedescriptorsbyfd_t::iterator i;
64 for (i = instances.begin(); i != instances.end(); i++)
66 map[j].fd = i->second->fd;
67 map[j].events = POLLMSG|POLLRDBAND|POLLRDNORM|POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
68 map[j].revents = 0;
69 j++;
74 FileDescriptor::~FileDescriptor()
76 if (close(fd) != 0)
78 int err = errno;
79 switch (err)
81 case EBADF:
82 log("close(%i) - %i isn’t a valid open file descriptor.\n",fd,fd);
83 break;
84 case EINTR:
85 log("close(%i) - The close() call was interrupted by a signal.\n",fd);
86 break;
87 case EIO:
88 log("close(%i) - An I/O error occurred.\n",fd);
89 break;
90 default:
91 log("close(%i) - Unknown error %i occured\n",fd,err);
94 else
96 log("Closed fd %i\n",fd);
98 instances.erase(fd);
101 void FileDescriptor::destroy(bool silent)
103 delete this;
107 void FileDescriptor::setTimeout(int secs)
109 itimerval timeout;
110 // stop the timer
111 timeout.it_interval.tv_sec = 0;
112 timeout.it_interval.tv_usec = 0;
113 timeout.it_value.tv_sec = secs;
114 timeout.it_value.tv_usec = 0;
115 if (setitimer(ITIMER_REAL, &timeout, NULL))
117 __THROW__ ("Timer set error\n");
119 currentFd = fd;
122 void FileDescriptor::clearTimeout()
124 itimerval timeout;
125 // stop the timer
126 timeout.it_interval.tv_sec = 0;
127 timeout.it_interval.tv_usec = 0;
128 timeout.it_value.tv_sec = 0;
129 timeout.it_value.tv_usec = 0;
130 if (setitimer(ITIMER_REAL, &timeout, NULL))
132 __THROW__ ("Timer clear error\n");
134 currentFd = -1;
138 RETSIGTYPE FileDescriptor::timeoutHandler(int sig)
140 log( "Timeout occured!\n");
141 close(currentFd); // this should generate an exception
144 void FileDescriptor::ignoreBrokenPipeSignals()
146 struct sigaction act;
147 act.sa_handler = SIG_IGN;
148 act.sa_flags = 0;
150 sigaction(SIGPIPE,&act,NULL);
153 filedescriptorsbyfd_t FileDescriptor::instances;
154 int FileDescriptor::currentFd = -1;