int semaphore_fd::get() { char byte = 0; while (true) { struct pollfd pfd = {}; pfd.fd = pipe_fds[0]; pfd.events = POLLIN; int status = poll(&pfd, 1, -1); if (status == -1) { if (errno == EINTR) return -1; else throw_errno(); } status = read(pipe_fds[0], &byte, 1); if (status < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) return -1; else throw_errno(); } else { assert(status == 1); return 0; } } }
static tpie::stream_header_t get_stream_header(const std::string & path) { tpie::stream_header_t res; int fd = ::open(path.c_str(), O_RDONLY); if (fd == -1) throw_errno(); if (::read(fd, &res, sizeof(res)) != sizeof(res)) throw_errno(); ::close(fd); return res; }
void process::collect_zombies( void ) { while ( true ) { int status = 0; int ret = ::wait( &status ); if ( ret == -1 ) { if ( errno == EINTR ) continue; if ( errno == ECHILD ) { std::unique_lock<std::mutex> lock( the_mutex ); if ( the_processes.empty() ) return; else break; } throw_errno( "waiting on child processes" ); } else { std::unique_lock<std::mutex> lock( the_mutex ); auto i = the_processes.find( pid_t(ret) ); if ( i != the_processes.end() ) { i->second->update_status( status ); the_processes.erase( i ); the_condition.notify_all(); } } } }
PosixStream::PosixStream(const String& path, IO::Access access) : m_path(path) { const char* as; switch (access) { case IO::AccessRead: as = "r"; break; case IO::AccessWrite: as = "a"; break; default: as = "r+"; break; } m_file = fopen(path.c_str(), as); if (!m_file) { throw_errno(path); } Stats::IncrementCount(Stats::FileHandles); }
void ReadSelector::select() { m_pendingCancelation = false; fd_set set; FD_ZERO(&set); int maxfd = -1; for (auto iter : m_fds) { FD_SET(iter.first, &set); if (iter.first > maxfd) { maxfd = iter.first; } } if (::select(maxfd + 1, &set, nullptr, nullptr, nullptr) < 0) { throw_errno(); } for (auto iter : m_fds) { if (FD_ISSET(iter.first, &set)) { iter.second(); if (m_pendingCancelation) { return; } } } }
hime_lsize_t PosixStream::tell() { off_t pos = ftello((FILE*)m_file); if (pos == -1) throw_errno(m_path.c_str()); return pos; }
void tcp_resolve(const std::string& hostname, const std::string& service, std::vector<tcp_socket::endpoint_type>& out) { addrinfo hints; addrinfo* result = nullptr; std::memset(&hints, 0, sizeof(addrinfo)); block("address resolution started"); int r = getaddrinfo( hostname.c_str(), service.c_str(), &hints, &result); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; unblock("address resolution finished"); if (r != 0) { throw_errno("tcp_resolver::resolve"); } for(addrinfo* addr_info = result; addr_info; addr_info = addr_info->ai_next) { if(addr_info->ai_family == AF_INET) { const sockaddr_in* addr = reinterpret_cast<const sockaddr_in*>(addr_info->ai_addr); boost::asio::ip::address_v4 a(ntohl(addr->sin_addr.s_addr)); out.emplace_back(a, ntohs(addr->sin_port)); } } }
uint32_t timer_add(timer * self, timer_callback * cb) { if (unlikely(self == NULL)) throw_unexpected(TIMER_NULL); if (access(path, F_OK) != 0) throw_errno(errno); uint32_t wd = inotify_add_timer(self->fd, path, events); if (unlikely((int)wd == -1)) throw_errno(errno); if (cb != NULL) vcetor_put(&self->callbacks, wd, cb); return wd; }
hime_lsize_t PosixStream::size() { struct stat st; int fd = fileno((FILE*)m_file); if (fstat(fd, &st) != 0) throw_errno(m_path.c_str()); return st.st_size; }
void RDMAServerSocket::listen(int backlog) { if (rdma_listen(id.get(), backlog)) throw_errno("rdma_listen"); log_info() << "server listening on " << inet_ntoa(id->route.addr.src_sin.sin_addr) << ":" << ntohs(id->route.addr.src_sin.sin_port) << " " << id.get() << " " << (void*) this; }
hime_lsize_t PosixStream::seek(hime_lpos_t offset, IO::SeekOrigin org) { static int whence[] = { SEEK_SET, SEEK_CUR, SEEK_END }; if (fseeko((FILE*)m_file, offset, whence[org]) != 0) throw_errno(m_path.c_str()); return tell(); }
uint32_t watch_add(watch_t * self, const char *path, uint32_t events, watch_callback_t * cb) { if (unlikely(self == NULL)) throw_unexpected(WATCH_NULL); if (access(path, F_OK) != 0) throw_errno(errno); uint32_t wd = inotify_add_watch(self->fd, path, events); if (unlikely((int)wd == -1)) throw_errno(errno); if (cb != NULL) array_put(&self->callbacks, wd, cb, 1); return wd; }
void Server::prepareSignals() { sigset_t sigmask; sigemptyset(&sigmask); sigaddset(&sigmask, SIGINT); sigaddset(&sigmask, SIGTERM); sigaddset(&sigmask, SIGPIPE); sigaddset(&sigmask, SIGCHLD); if (sigprocmask(SIG_BLOCK, &sigmask, nullptr) < 0) { throw_errno(); } m_sigfd = signalfd(-1, &sigmask, SFD_CLOEXEC | SFD_NONBLOCK); if (m_sigfd < 0) { throw_errno(); } }
void process::set_error( const std::string &err_file ) { _stderr.reset(); if ( _fderr >= 0 ) ::close( _fderr ); _fderr = ::open( err_file.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0644 ); if ( _fderr < 0 ) throw_errno( "opening process error ({0})", err_file ); }
void process::set_output( const std::string &out_file ) { _stdout.reset(); if ( _fdout >= 0 ) ::close( _fdout ); _fdout = ::open( out_file.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0644 ); if ( _fdout < 0 ) throw_errno( "opening process output ({0})", out_file ); }
void process::set_input( const std::string &in_file ) { _stdin.reset(); if ( _fdin >= 0 ) ::close( _fdin ); _fdin = ::open( in_file.c_str(), O_RDONLY ); if ( _fdin < 0 ) throw_errno( "opening process input ({0})", in_file ); }
void dispatch_remove(dispatch_t * self, int fd) { if (unlikely(self == NULL)) throw_unexpected(DISPATCH_NULL); if (unlikely(epoll_ctl(self->fd, EPOLL_CTL_DEL, fd, NULL))) throw_errno(errno); array_status(&self->events, fd, false); }
void watch_remove(watch_t * self, uint32_t wd) { if (unlikely(self == NULL)) throw_unexpected(WATCH_NULL); int rc = inotify_rm_watch(self->fd, wd); if (unlikely(rc == -1)) throw_errno(errno); array_status(&self->callbacks, wd, false); }
void timer_remove(timer * self, uint32_t wd) { if (unlikely(self == NULL)) throw_unexpected(TIMER_NULL); int rc = inotify_rm_timer(self->fd, wd); if (unlikely(rc == -1)) throw_errno(errno); array_status(&self->callbacks, wd, false); }
void lines_to_file(char **lines, const char *path) { important_check(lines); scope { FILE *file = kga_fopen(path, "w"); for (size_t i = 0, n = array_length(lines); i < n; i++) { important_check(lines[i]); if (fprintf(file, "%s\n", lines[i]) < 0) { throw_errno(); }; }; }; };
void socket::bind( uint32_t host, uint16_t port ) { precondition( _socket >= 0, "invalid socket" ); struct sockaddr_in local; ::memset( &local, 0, sizeof(local) ); local.sin_family = AF_INET; local.sin_addr.s_addr = htonl( host ); local.sin_port = htons( port ); if ( ::bind( _socket, reinterpret_cast<struct sockaddr *>( &local ), sizeof(local) ) == -1 ) throw_errno( "socking binding to {0}:{1}", host, port ); }
void Server::accept(int listenfd) { struct sockaddr_in cliaddr; socklen_t clilen = sizeof(cliaddr); int fd = accept4(listenfd, (struct sockaddr *)&cliaddr, &clilen, SOCK_CLOEXEC); if (fd < 0) { throw_errno(); } VncTunnel *tunnel = new VncTunnel(m_vncManager, m_greeterManager, m_controlManager, fd); std::thread(&VncTunnel::start, tunnel).detach(); }
int semaphore::try_get() { int status = sem_trywait(&sem); if (status == -1) { if (errno == EAGAIN || errno == EINTR) return -1; else throw_errno(); } else return 0; }
void semaphore_fd::put() { char byte = 0; int status; do { status = write(pipe_fds[1], &byte, 1); if (status < 0 && errno != EINTR) { throw_errno(); } } while (status < 0); }
Node* PosixNode::open(const FileName& child) { String cn = m_path; cn += "/"; cn += child.str(); struct stat st; if (::stat(cn.c_str(), &st) != 0) throw_errno(cn); PosixNode* node = new PosixNode(child, cn); return node; }
int semaphore::get() { int status = sem_wait(&sem); if (status == -1) { if (errno == EINTR) return -1; else throw_errno(); } else return 0; }
void watch_init(watch_t * self) { if (unlikely(self == NULL)) throw_unexpected(WATCH_NULL); if (self->fd != -1) close(self->fd), self->fd = -1; self->fd = inotify_init1(IN_CLOEXEC); if (unlikely(self->fd == -1)) throw_errno(errno); array_init(&self->callbacks, sizeof(watch_callback_t), WATCH_PAGE_SIZE); }
PosixIterator::PosixIterator(const String& path) { m_path = path; m_more = false; m_dir = opendir(path.c_str()); if (!m_dir) { if (errno == ENOTDIR) return; throw_errno(path.c_str()); } }
void timer_init(timer * self, int clock) { if (unlikely(self == NULL)) throw_unexpected(TIMER_NULL); if (self->fd != -1) close(self->fd), self->fd = -1; self->fd = timerfd_create(clock, TFD_CLOEXEC); if (unlikely(self->fd == -1)) throw_errno(errno); vector_init(&self->callbacks, "callbacks", sizeof(timer_callback), TIMER_PAGE_SIZE); }
void Server::handleSignal() { struct signalfd_siginfo siginfo; ssize_t ret = read(m_sigfd, &siginfo, sizeof(siginfo)); if (ret != sizeof(siginfo)) { throw_errno(); } switch (siginfo.ssi_signo) { case SIGINT: case SIGTERM: m_run = false; break; case SIGCHLD: // Clean any waiting child processes. while (pid_t pid = waitpid(-1, NULL, WNOHANG)) { if (pid == 0 || (pid < 0 && errno == ECHILD)) { // No (more) children to take care of. break; } if (pid < 0) { throw_errno(); } m_vncManager.childDied(pid); m_greeterManager.childDied(pid); } break; case SIGPIPE: // Ignoring SIGPIPEs of greeters. // TODO: Any other SIGPIPEs we could potentially get? break; } }