/* * Set the position of the device. * * Returns: true on succes * false on error */ bool DEVICE::update_pos(DCR *dcr) { boffset_t pos; bool ok = true; if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad device call. Device not open\n")); Emsg1(M_FATAL, 0, "%s", errmsg); return false; } if (is_fifo() || is_vtl()) { return true; } file = 0; file_addr = 0; pos = lseek(dcr, (boffset_t)0, SEEK_CUR); if (pos < 0) { berrno be; dev_errno = errno; Pmsg1(000, _("Seek error: ERR=%s\n"), be.bstrerror()); Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.bstrerror()); ok = false; } else { file_addr = pos; block_num = (uint32_t)pos; file = (uint32_t)(pos >> 32); } return ok; }
/* * Reposition the device to file, block * * Returns: false on failure * true on success */ bool DEVICE::reposition(DCR *dcr, uint32_t rfile, uint32_t rblock) { if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to reposition. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } if (is_fifo() || is_vtl()) { return true; } boffset_t pos = (((boffset_t)rfile) << 32) | rblock; Dmsg1(100, "===== lseek to %d\n", (int)pos); if (lseek(dcr, pos, SEEK_SET) == (boffset_t)-1) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.bstrerror()); return false; } file = rfile; block_num = rblock; file_addr = pos; return true; }
/* * "The l in the name lseek() derives from the fact that the * offset argument and the return value were both originally * typed as long. Early UNIX implementations provided a seek() * system call, which typed these values as int" --M. Kerrisk */ int64_t sys_lseek(int fd, uint64_t offset, uint whence) { struct file *file; struct inode *inode; uint64_t offset_base; int error = 0; file = unrolled_lookup(¤t->fdtable, fd); if (file == NULL) return -EBADF; assert(file->inum > 0); if (is_fifo(file->inum) || is_socket(file->inum)) return -ESPIPE; inode = inode_get(file->inum); spin_lock(&file->lock); switch (whence) { case SEEK_SET: offset_base = 0; break; case SEEK_CUR: offset_base = file->offset; break; case SEEK_END: offset_base = inode->size_low; break; default: error = -EINVAL; goto out; } if ((offset_base + offset) < offset_base) { error = -EOVERFLOW; goto out; } file->offset = offset_base + offset; out: spin_unlock(&file->lock); return error ? error : (int64_t)file->offset; }
/* * Rewind the device. * * Returns: true on success * false on failure */ bool DEVICE::rewind(DCR *dcr) { Dmsg3(400, "rewind res=%d fd=%d %s\n", num_reserved(), m_fd, print_name()); /* * Remove EOF/EOT flags */ clear_bit(ST_EOT, state); clear_bit(ST_EOF, state); clear_bit(ST_WEOT, state); block_num = file = 0; file_size = 0; file_addr = 0; if (m_fd < 0) { return false; } if (is_fifo() || is_vtl()) { return true; } if (lseek(dcr, (boffset_t)0, SEEK_SET) < 0) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.bstrerror()); return false; } return true; }
struct gpu_object *nvrm_get_parent_fifo(struct gpu_object *obj) { while (obj) { if (is_fifo(obj, 0)) return obj; obj = obj->parent_object; } return NULL; }
// is f a pipe? cache a result to speed things up bool OS::is_pipe(FILE *f) { static bool lastAns; static FILE *last= NULL; static int fd= -1; if (f == last && fileno(f) == fd) return lastAns; last = f; fd= fileno(f); struct stat st_buf; if (fstat(fd, &st_buf)) fatal("fstat failed"); lastAns= is_fifo(st_buf.st_mode); return lastAns; }
int container_daemon_stop(char *sessiondir) { FILE *comm; FILE *test_daemon_fp; int daemon_fd; message(DEBUG, "Called container_daemon_stop(%s)\n", sessiondir); message(VERBOSE, "Checking if daemon is currently running for this container\n"); if ( is_file(joinpath(sessiondir, "daemon.pid")) < 0 ) { message(ERROR, "Daemon process is not running\n"); return(0); } message(DEBUG, "Opening daemon.pid for reading\n"); if ( ( test_daemon_fp = fopen(joinpath(sessiondir, "daemon.pid"), "r") ) == NULL ) { // Flawfinder: ignore message(ERROR, "Could not open daemon pid file %s: %s\n", joinpath(sessiondir, "daemon.pid"), strerror(errno)); ABORT(255); } message(DEBUG, "Testing to see if daemon process is still active\n"); daemon_fd = fileno(test_daemon_fp); if ( flock(daemon_fd, LOCK_SH | LOCK_NB) == 0 ) { message(INFO, "No active container daemon active\n"); return(0); } message(DEBUG, "Connecting to daemon.comm FIFO\n"); if ( is_fifo(joinpath(sessiondir, "daemon.comm")) < 0 ) { message(ERROR, "Container daemon COMM not available\n"); ABORT(255); } message(VERBOSE, "Opening daemon.comm for writing\n"); if ( ( comm = fopen(joinpath(sessiondir, "daemon.comm"), "w") ) == NULL ) { //Flawfinder: ignore message(ERROR, "Could not open fifo for writing %s: %s\n", joinpath(sessiondir, "daemon.comm"), strerror(errno)); ABORT(255); } message(VERBOSE, "Sending stop command to daemon process\n"); fputs("stop", comm); fclose(comm); message(DEBUG, "Return container_daemon_stop(%s) = 0\n", sessiondir); return(0); }
struct gpu_object *nvrm_get_fifo(struct gpu_object *obj, uint64_t gpu_addr, int strict) { struct gpu_object *last = NULL; while (obj) { if (is_fifo(obj, 0)) last = obj; if (is_fifo_and_addr_belongs(obj, gpu_addr)) return obj; if (obj->class_ == NVRM_DEVICE_0) { struct gpu_object *fifo = nvrm_find_object_by_func(obj, is_fifo_and_addr_belongs, gpu_addr); if (!fifo && !strict) // fallback, for traces without ioctl_create args { fifo = nvrm_find_object_by_func(obj, is_fifo, 0); struct gpu_object *dev = nvrm_get_device(obj); int fifos = 0; if (dev && dev->class_data) fifos = nvrm_dev(dev)->fifos; static int warned = 0; if (fifos > 1 && !warned) { int chipset = nvrm_get_chipset(dev); if (chipset > 0x80 || chipset == 0x50) mmt_error("This trace may not be decoded accurately because there are multiple fifo objects " "and ioctl_creates for some of them were not captured with argument data%s\n", ""); else mmt_error("This trace may not be decoded accurately because there are multiple fifo objects " "and USER buffer detection is not implemented yet%s\n", ""); warned = 1; } } return fifo; } obj = obj->parent_object; } return last; }
/* * Open the device with the operating system and * initialize buffer pointers. * * Returns: true on success * false on error * * Note, for a tape, the VolName is the name we give to the * volume (not really used here), but for a file, the * VolName represents the name of the file to be created/opened. * In the case of a file, the full name is the device name * (archive_name) with the VolName concatenated. */ bool DEVICE::open(DCR *dcr, int omode) { int preserve = 0; if (is_open()) { if (openmode == omode) { return true; } else { Dmsg1(200, "Close fd=%d for mode change in open().\n", m_fd); d_close(m_fd); clear_opened(); preserve = state & (ST_LABEL|ST_APPEND|ST_READ); } } if (dcr) { dcr->setVolCatName(dcr->VolumeName); VolCatInfo = dcr->VolCatInfo; /* structure assign */ } state &= ~(ST_NOSPACE|ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF); label_type = B_BACULA_LABEL; if (is_tape() || is_fifo()) { open_tape_device(dcr, omode); } else if (is_ftp()) { open_device(dcr, omode); } else { Dmsg1(100, "call open_file_device mode=%s\n", mode_to_str(omode)); open_file_device(dcr, omode); } state |= preserve; /* reset any important state info */ Dmsg2(100, "preserve=0x%x fd=%d\n", preserve, m_fd); Dmsg7(100, "open dev: fd=%d dev=%p dcr=%p vol=%s type=%d dev_name=%s mode=%s\n", m_fd, getVolCatName(), this, dcr, dev_type, print_name(), mode_to_str(omode)); return m_fd >= 0; }
/* This is the function which is called to display all files and * directories, and it's where the magic happens. We are called with * full stat and extended attributes for each file, so there is no * penalty for displaying anything in those structures. However if we * need other things (eg. checksum) we may have to go back to the * appliance and then there can be a very large penalty. */ static int show_file (const char *dir, const char *name, const struct guestfs_stat *stat, const struct guestfs_xattr_list *xattrs, void *unused) { const char *filetype; CLEANUP_FREE char *path = NULL, *csum = NULL, *link = NULL; /* Display the basic fields. */ output_start_line (); if (is_reg (stat->mode)) filetype = "-"; else if (is_dir (stat->mode)) filetype = "d"; else if (is_chr (stat->mode)) filetype = "c"; else if (is_blk (stat->mode)) filetype = "b"; else if (is_fifo (stat->mode)) filetype = "p"; else if (is_lnk (stat->mode)) filetype = "l"; else if (is_sock (stat->mode)) filetype = "s"; else filetype = "u"; output_string (filetype); output_int64_perms (stat->mode & 07777); output_int64_size (stat->size); /* Display extra fields when enabled. */ if (enable_uids) { output_int64_uid (stat->uid); output_int64_uid (stat->gid); } if (enable_times) { output_int64_time (stat->atime); output_int64_time (stat->mtime); output_int64_time (stat->ctime); } if (enable_extra_stats) { output_int64_dev (stat->dev); output_int64 (stat->ino); output_int64 (stat->nlink); output_int64_dev (stat->rdev); output_int64 (stat->blocks); } /* Disabled for now -- user would definitely want these to be interpreted. if (enable_xattrs) output_xattrs (xattrs); */ path = full_path (dir, name); if (checksum && is_reg (stat->mode)) { csum = guestfs_checksum (g, checksum, path); if (!csum) exit (EXIT_FAILURE); output_string (csum); } output_string (path); if (is_lnk (stat->mode)) /* XXX Fix this for NTFS. */ link = guestfs_readlink (g, path); if (link) output_string_link (link); output_end_line (); return 0; }
inline bool is_fifo(const path& p, std::error_code& ec) noexcept { return is_fifo(detail::status(p, &ec)); }
inline bool is_fifo(const path& p) { return is_fifo(detail::status(p)); }
static void output_file (guestfs_h *g, struct file *file) { const char *filetype; size_t i; CLEANUP_FREE char *link = NULL; if (is_reg (file->stat->st_mode)) filetype = "-"; else if (is_dir (file->stat->st_mode)) filetype = "d"; else if (is_chr (file->stat->st_mode)) filetype = "c"; else if (is_blk (file->stat->st_mode)) filetype = "b"; else if (is_fifo (file->stat->st_mode)) filetype = "p"; else if (is_lnk (file->stat->st_mode)) filetype = "l"; else if (is_sock (file->stat->st_mode)) filetype = "s"; else filetype = "u"; output_string (filetype); output_int64_perms (file->stat->st_mode & 07777); output_int64_size (file->stat->st_size); /* Display extra fields when enabled. */ if (enable_uids) { output_int64_uid (file->stat->st_uid); output_int64_uid (file->stat->st_gid); } if (enable_times) { if (atime) output_int64_time (file->stat->st_atime_sec, file->stat->st_atime_nsec); output_int64_time (file->stat->st_mtime_sec, file->stat->st_mtime_nsec); output_int64_time (file->stat->st_ctime_sec, file->stat->st_ctime_nsec); } if (enable_extra_stats) { output_int64_dev (file->stat->st_dev); output_int64 (file->stat->st_ino); output_int64 (file->stat->st_nlink); output_int64_dev (file->stat->st_rdev); output_int64 (file->stat->st_blocks); } if (file->csum) output_string (file->csum); output_string (file->path); if (is_lnk (file->stat->st_mode)) { /* XXX Fix this for NTFS. */ link = guestfs_readlink (g, file->path); if (link) output_string_link (link); } if (enable_xattrs) { for (i = 0; i < file->xattrs->len; ++i) { output_string (file->xattrs->val[i].attrname); output_binary (file->xattrs->val[i].attrval, file->xattrs->val[i].attrval_len); } } }