ssize_t write(int fd, const user_ptr<void> _buf, size_t count) { shared_ptr<file> f; int ret = get_fd(fd, f); if (unlikely(ret != 0)) return ret; if (unlikely((f->oflags & O_ACCMODE) == O_RDONLY)) return -EACCES; auto buf = (const char*) _buf.get(); if (unlikely(!buf || !_buf.check_region(buf, buf + count))) return -EFAULT; return f->write(buf, count); }
void add_new_user(user_ptr user) { rw_mutex.lock(); users.push_back(user); rw_mutex.unlock(); #ifdef DEBUG std::cout << "User connected" << std::endl; #endif user->accept_message_size(); }
void on_user_leave(user_ptr user) { rw_mutex.lock(); auto pos = std::find_if(users.begin(), users.end(), [user](user_ptr &ptr) { return ptr.get() == user.get(); }); if (pos != users.end()) { users.erase(pos); } rw_mutex.unlock(); #ifdef DEBUG std::cout << "User leaved" << std::endl; #endif }
int open(const user_ptr<char> _path, int flags, mode_t mode) { const auto p = process::get_current_proc(); if (unlikely(!p)) return -EFAULT; if (unlikely(p->fd_table.next_fd >= int(process::PROC_MAX_FDS))) return -EMFILE; int fd = p->fd_table.next_fd; auto path = _path.get(); if (unlikely(!path)) return -EFAULT; // TODO check string auto nd = p->root_sb->walk(path); // TODO handle O_CREAT if (!nd) return -ENOENT; else if (S_ISDIR(nd->ind->mode) && ((flags & O_WRONLY) || (flags & O_RDWR))) return -EISDIR; shared_ptr<file> f; int ret = nd->open(f); if (unlikely(ret != 0)) return ret; f->oflags = flags; if (int(p->fd_table.fds.size()) > fd) p->fd_table.fds[fd] = f; else { ASSERTH(p->fd_table.fds.size() == size_t(fd)); p->fd_table.fds.push_back(f); } // search for the next free fd for (p->fd_table.next_fd++; p->fd_table.next_fd < int(p->fd_table.fds.size()) && p->fd_table.fds[p->fd_table.next_fd]; p->fd_table.next_fd++) ; return fd; }
int lseek(int fd, user_ptr<off_t> _poffset, int whence) { off_t* const poffset = _poffset.get(); if (unlikely(!poffset)) return -EFAULT; int ret; shared_ptr<file> f; ret = get_fd(fd, f); if (unlikely(ret != 0)) return ret; off_t pos = f->position; switch (whence) { case SEEK_SET: pos = *poffset; break; case SEEK_CUR: pos += *poffset; break; case SEEK_END: pos = f->nd->ind->size + *poffset; break; default: return -EINVAL; } ret = f->seek(pos); // update new position if (likely(!ret)) *poffset = pos; return ret; }
void execute_command(std::string cmd, user_ptr user_to_send_result) { command_executor.submit([user_to_send_result, cmd]() { Message result; result.set_type(Message::MESSAGE); result.set_author(CHAT_SERVER_AUTOR); std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose); char buffer[128]; std::string result_str; if (pipe) { while (!feof(pipe.get())) { if (fgets(buffer, 128, pipe.get()) == NULL) { break; } result_str += buffer; if (result_str.back() == '\n') { result_str.pop_back(); result.add_text(std::move(result_str)); result_str.clear(); } } if (result_str.size()) { result.add_text(result_str); } } else { result.add_text("Command '" + cmd + "'' execution failed!"); } user_to_send_result->deliver_message(serialize_message(result)); }); }
bool ignore_manager::is_ignored(user_ptr user, user_ptr ignored_user) const { return is_ignored(user->get_session_id(), ignored_user->get_session_id()); }