static void qemu_char_open(Chardev *chr, ChardevBackend *backend, bool *be_opened, Error **errp) { ChardevClass *cc = CHARDEV_GET_CLASS(chr); /* Any ChardevCommon member would work */ ChardevCommon *common = backend ? backend->u.null.data : NULL; if (common && common->has_logfile) { int flags = O_WRONLY | O_CREAT; if (common->has_logappend && common->logappend) { flags |= O_APPEND; } else { flags |= O_TRUNC; } chr->logfd = qemu_open(common->logfile, flags, 0666); if (chr->logfd < 0) { error_setg_errno(errp, errno, "Unable to open logfile %s", common->logfile); return; } } if (cc->open) { cc->open(chr, backend, be_opened, errp); } }
static void write_pidfile(void) { int pidfd; char pidstr[32]; pidfd = qemu_open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR); if (pidfd == -1) { error_report("Cannot open pid file, %s", strerror(errno)); exit(EXIT_FAILURE); } if (lockf(pidfd, F_TLOCK, 0)) { error_report("Cannot lock pid file, %s", strerror(errno)); goto fail; } if (ftruncate(pidfd, 0)) { error_report("Failed to truncate pid file"); goto fail; } snprintf(pidstr, sizeof(pidstr), "%d\n", getpid()); if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) { error_report("Failed to write pid file"); goto fail; } return; fail: unlink(pidfile); close(pidfd); exit(EXIT_FAILURE); }
static int raw_create(const char *filename, QEMUOptionParameter *options) { int fd; int result = 0; int64_t total_size = 0; /* Read out options */ while (options && options->name) { if (!strcmp(options->name, BLOCK_OPT_SIZE)) { total_size = options->value.n / BDRV_SECTOR_SIZE; } options++; } fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (fd < 0) { result = -errno; } else { if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) { result = -errno; } if (qemu_close(fd) != 0) { result = -errno; } } return result; }
static int floppy_probe_device(const char *filename) { int fd, ret; int prio = 0; struct floppy_struct fdparam; struct stat st; if (strstart(filename, "/dev/fd", NULL) && !strstart(filename, "/dev/fdset/", NULL)) { prio = 50; } fd = qemu_open(filename, O_RDONLY | O_NONBLOCK); if (fd < 0) { goto out; } ret = fstat(fd, &st); if (ret == -1 || !S_ISBLK(st.st_mode)) { goto outc; } /* Attempt to detect via a floppy specific ioctl */ ret = ioctl(fd, FDGETPRM, &fdparam); if (ret >= 0) prio = 100; outc: qemu_close(fd); out: return prio; }
static int rtc_start_timer(struct qemu_alarm_timer *t) { int rtc_fd; unsigned long current_rtc_freq = 0; TFR(rtc_fd = qemu_open("/dev/rtc", O_RDONLY)); if (rtc_fd < 0) return -1; ioctl(rtc_fd, RTC_IRQP_READ, ¤t_rtc_freq); if (current_rtc_freq != RTC_FREQ && ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) { fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n" "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n" "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n"); goto fail; } if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) { fail: close(rtc_fd); return -1; } enable_sigio_timer(rtc_fd); t->priv = (void *)(long)rtc_fd; return 0; }
static bool ga_open_pidfile(const char *pidfile) { int pidfd; char pidstr[32]; pidfd = qemu_open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR); if (pidfd == -1 || lockf(pidfd, F_TLOCK, 0)) { g_critical("Cannot lock pid file, %s", strerror(errno)); if (pidfd != -1) { close(pidfd); } return false; } if (ftruncate(pidfd, 0)) { g_critical("Failed to truncate pid file"); goto fail; } snprintf(pidstr, sizeof(pidstr), "%d\n", getpid()); if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) { g_critical("Failed to write pid file"); goto fail; } /* keep pidfile open & locked forever */ return true; fail: unlink(pidfile); close(pidfd); return false; }
int qemu_create_pidfile(const char *filename) { char buffer[128]; int len; int fd; fd = qemu_open(filename, O_RDWR | O_CREAT, 0600); if (fd == -1) { return -1; } #ifndef __ANDROID__ if (lockf(fd, F_TLOCK, 0) == -1) { close(fd); return -1; } len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", getpid()); if (write(fd, buffer, len) != len) { close(fd); return -1; } #endif // __ANDROID__ /* keep pidfile open & locked forever */ return 0; }
static int hdev_create(const char *filename, QEMUOptionParameter *options) { int fd; int ret = 0; struct stat stat_buf; int64_t total_size = 0; /* Read out options */ while (options && options->name) { if (!strcmp(options->name, "size")) { total_size = options->value.n / BDRV_SECTOR_SIZE; } options++; } fd = qemu_open(filename, O_WRONLY | O_BINARY); if (fd < 0) return -errno; if (fstat(fd, &stat_buf) < 0) ret = -errno; else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode)) ret = -ENODEV; else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE) ret = -ENOSPC; qemu_close(fd); return ret; }
static int cdrom_probe_device(const char *filename) { int fd, ret; int prio = 0; struct stat st; fd = qemu_open(filename, O_RDONLY | O_NONBLOCK); if (fd < 0) { goto out; } ret = fstat(fd, &st); if (ret == -1 || !S_ISBLK(st.st_mode)) { goto outc; } /* Attempt to detect via a CDROM specific ioctl */ ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); if (ret >= 0) prio = 100; outc: qemu_close(fd); out: return prio; }
static int raw_open_common(BlockDriverState *bs, QDict *options, int bdrv_flags, int open_flags) { BDRVRawState *s = bs->opaque; QemuOpts *opts; Error *local_err = NULL; const char *filename; int fd, ret; opts = qemu_opts_create_nofail(&raw_runtime_opts); qemu_opts_absorb_qdict(opts, options, &local_err); if (error_is_set(&local_err)) { qerror_report_err(local_err); error_free(local_err); ret = -EINVAL; goto fail; } filename = qemu_opt_get(opts, "filename"); ret = raw_normalize_devicepath(&filename); if (ret != 0) { goto fail; } s->open_flags = open_flags; raw_parse_flags(bdrv_flags, &s->open_flags); s->fd = -1; fd = qemu_open(filename, s->open_flags, 0644); if (fd < 0) { ret = -errno; if (ret == -EROFS) { ret = -EACCES; } goto fail; } s->fd = fd; #ifdef CONFIG_LINUX_AIO if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) { qemu_close(fd); ret = -errno; goto fail; } #endif s->has_discard = 1; #ifdef CONFIG_XFS if (platform_test_xfs_fd(s->fd)) { s->is_xfs = 1; } #endif ret = 0; fail: qemu_opts_del(opts); return ret; }
int qmp_chardev_open_file_source(char *src, int flags, Error **errp) { int fd = -1; TFR(fd = qemu_open(src, flags, 0666)); if (fd == -1) { error_setg_file_open(errp, errno, src); } return fd; }
static void rng_random_opened(RngBackend *b, Error **errp) { RndRandom *s = RNG_RANDOM(b); if (s->filename == NULL) { error_set(errp, QERR_INVALID_PARAMETER_VALUE, "filename", "a valid filename"); } else { s->fd = qemu_open(s->filename, O_RDONLY | O_NONBLOCK); if (s->fd == -1) { error_setg_file_open(errp, errno, s->filename); } } }
/* * Unless path or file descriptor set has been provided by user, * determine the sysfs cancel file following kernel documentation * in Documentation/ABI/stable/sysfs-class-tpm. * From /dev/tpm0 create /sys/class/misc/tpm0/device/cancel */ static int tpm_passthrough_open_sysfs_cancel(TPMBackend *tb) { TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); int fd = -1; char *dev; char path[PATH_MAX]; if (tb->cancel_path) { fd = qemu_open(tb->cancel_path, O_WRONLY); if (fd < 0) { error_report("Could not open TPM cancel path : %s", strerror(errno)); } return fd; } dev = strrchr(tpm_pt->tpm_dev, '/'); if (dev) { dev++; if (snprintf(path, sizeof(path), "/sys/class/misc/%s/device/cancel", dev) < sizeof(path)) { fd = qemu_open(path, O_WRONLY); if (fd >= 0) { tb->cancel_path = g_strdup(path); } else { error_report("tpm_passthrough: Could not open TPM cancel " "path %s : %s", path, strerror(errno)); } } } else { error_report("tpm_passthrough: Bad TPM device path %s", tpm_pt->tpm_dev); } return fd; }
static void floppy_eject(BlockDriverState *bs, bool eject_flag) { BDRVRawState *s = bs->opaque; int fd; if (s->fd >= 0) { qemu_close(s->fd); s->fd = -1; } fd = qemu_open(bs->filename, s->open_flags | O_NONBLOCK); if (fd >= 0) { if (ioctl(fd, FDEJECT, 0) < 0) perror("FDEJECT"); qemu_close(fd); } }
static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb) { TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); const char *value; value = qemu_opt_get(opts, "cancel-path"); if (value) { tb->cancel_path = g_strdup(value); } value = qemu_opt_get(opts, "path"); if (!value) { value = TPM_PASSTHROUGH_DEFAULT_DEVICE; } tpm_pt->tpm_dev = g_strdup(value); tb->path = g_strdup(tpm_pt->tpm_dev); tpm_pt->tpm_fd = qemu_open(tpm_pt->tpm_dev, O_RDWR); if (tpm_pt->tpm_fd < 0) { error_report("Cannot access TPM device using '%s': %s\n", tpm_pt->tpm_dev, strerror(errno)); goto err_free_parameters; } if (tpm_passthrough_test_tpmdev(tpm_pt->tpm_fd)) { error_report("'%s' is not a TPM device.\n", tpm_pt->tpm_dev); goto err_close_tpmdev; } return 0; err_close_tpmdev: qemu_close(tpm_pt->tpm_fd); tpm_pt->tpm_fd = -1; err_free_parameters: g_free(tb->path); tb->path = NULL; g_free(tpm_pt->tpm_dev); tpm_pt->tpm_dev = NULL; return 1; }
int qemu_create_pidfile(const char *filename) { char buffer[128]; int len; #ifndef _WIN32 int fd; fd = qemu_open(filename, O_RDWR | O_CREAT, 0600); if (fd == -1) return -1; if (lockf(fd, F_TLOCK, 0) == -1) return -1; len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); if (write(fd, buffer, len) != len) return -1; #else HANDLE file; DWORD flags; OVERLAPPED overlap; BOOL ret; /* Open for writing with no sharing. */ file = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) return -1; flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY; overlap.hEvent = 0; /* Lock 1 byte. */ ret = LockFileEx(file, flags, 0, 0, 1, &overlap); if (ret == 0) return -1; /* Write PID to file. */ len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len, &overlap, NULL); if (ret == 0) return -1; #endif return 0; }
static int hdev_open(BlockDriverState *bs, const char *filename, int flags) { BDRVRawState *s = bs->opaque; #if defined(__APPLE__) && defined(__MACH__) if (strstart(filename, "/dev/cdrom", NULL)) { kern_return_t kernResult; io_iterator_t mediaIterator; char bsdPath[ MAXPATHLEN ]; int fd; kernResult = FindEjectableCDMedia( &mediaIterator ); kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) ); if ( bsdPath[ 0 ] != '\0' ) { strcat(bsdPath,"s0"); /* some CDs don't have a partition 0 */ fd = qemu_open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); if (fd < 0) { bsdPath[strlen(bsdPath)-1] = '1'; } else { qemu_close(fd); } filename = bsdPath; } if ( mediaIterator ) IOObjectRelease( mediaIterator ); } #endif s->type = FTYPE_FILE; #if defined(__linux__) { char resolved_path[ MAXPATHLEN ], *temp; temp = realpath(filename, resolved_path); if (temp && strstart(temp, "/dev/sg", NULL)) { bs->sg = 1; } } #endif return raw_open_common(bs, filename, flags, 0); }
/* Note: we do not have a reliable method to detect if the floppy is present. The current method is to try to open the floppy at every I/O and to keep it opened during a few hundreds of ms. */ static int fd_open(BlockDriverState *bs) { BDRVRawState *s = bs->opaque; int last_media_present; if (s->type != FTYPE_FD) return 0; last_media_present = (s->fd >= 0); if (s->fd >= 0 && (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) { qemu_close(s->fd); s->fd = -1; #ifdef DEBUG_FLOPPY printf("Floppy closed\n"); #endif } if (s->fd < 0) { if (s->fd_got_error && (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) { #ifdef DEBUG_FLOPPY printf("No floppy (open delayed)\n"); #endif return -EIO; } s->fd = qemu_open(bs->filename, s->open_flags & ~O_NONBLOCK); if (s->fd < 0) { s->fd_error_time = get_clock(); s->fd_got_error = 1; if (last_media_present) s->fd_media_changed = 1; #ifdef DEBUG_FLOPPY printf("No floppy\n"); #endif return -EIO; } #ifdef DEBUG_FLOPPY printf("Floppy opened\n"); #endif } if (!last_media_present) s->fd_media_changed = 1; s->fd_open_time = get_clock(); s->fd_got_error = 0; return 0; }
int qemu_create_pidfile(const char *filename) { char buffer[128]; int len; int fd; fd = qemu_open(filename, O_RDWR | O_CREAT, 0600); if (fd == -1) { return -1; } if (lockf(fd, F_TLOCK, 0) == -1) { return -1; } len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); if (write(fd, buffer, len) != len) { return -1; } return 0; }
static int hpet_start_timer(struct qemu_alarm_timer *t) { struct hpet_info info; int r, fd; fd = qemu_open("/dev/hpet", O_RDONLY); if (fd < 0) return -1; /* Set frequency */ r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ); if (r < 0) { fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n" "error, but for better emulation accuracy type:\n" "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n"); goto fail; } /* Check capabilities */ r = ioctl(fd, HPET_INFO, &info); if (r < 0) goto fail; /* Enable periodic mode */ r = ioctl(fd, HPET_EPI, 0); if (info.hi_flags && (r < 0)) goto fail; /* Enable interrupt */ r = ioctl(fd, HPET_IE_ON, 0); if (r < 0) goto fail; enable_sigio_timer(fd); t->priv = (void *)(long)fd; return 0; fail: close(fd); return -1; }
static int raw_open_common(BlockDriverState *bs, const char *filename, int bdrv_flags, int open_flags) { BDRVRawState *s = bs->opaque; int fd, ret; ret = raw_normalize_devicepath(&filename); if (ret != 0) { return ret; } s->open_flags = open_flags; raw_parse_flags(bdrv_flags, &s->open_flags); s->fd = -1; fd = qemu_open(filename, s->open_flags, 0644); if (fd < 0) { ret = -errno; if (ret == -EROFS) ret = -EACCES; return ret; } s->fd = fd; #ifdef CONFIG_LINUX_AIO if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) { qemu_close(fd); return -errno; } #endif s->has_discard = 1; #ifdef CONFIG_XFS if (platform_test_xfs_fd(s->fd)) { s->is_xfs = 1; } #endif return 0; }
void os_setup_post(void) { int fd = 0; if (daemonize) { if (chdir("/")) { error_report("not able to chdir to /: %s", strerror(errno)); exit(1); } TFR(fd = qemu_open("/dev/null", O_RDWR)); if (fd == -1) { exit(1); } } change_root(); change_process_uid(); if (daemonize) { uint8_t status = 0; ssize_t len; dup2(fd, 0); dup2(fd, 1); /* In case -D is given do not redirect stderr to /dev/null */ if (!qemu_logfile) { dup2(fd, 2); } close(fd); do { len = write(daemon_pipe, &status, 1); } while (len < 0 && errno == EINTR); if (len != 1) { exit(1); } } }
static int cdrom_reopen(BlockDriverState *bs) { BDRVRawState *s = bs->opaque; int fd; /* * Force reread of possibly changed/newly loaded disc, * FreeBSD seems to not notice sometimes... */ if (s->fd >= 0) qemu_close(s->fd); fd = qemu_open(bs->filename, s->open_flags, 0644); if (fd < 0) { s->fd = -1; return -EIO; } s->fd = fd; /* make sure the door isn't locked at this time */ ioctl(s->fd, CDIOCALLOW); return 0; }
static int kvm_vm_clone(KVMState *s) { struct stat stat; int fd; if (fstat(s->fd, &stat) != 0) { return -errno; } fd = qemu_open("/dev/kvm", O_RDWR); if (fd == -1) { return -errno; } if (ioctl(fd, KVM_CLONE, stat.st_rdev) == -1) { close(fd); return -errno; } return fd; }
void os_setup_post(void) { int fd = 0; if (daemonize) { uint8_t status = 0; ssize_t len; again1: len = write(fds[1], &status, 1); LOGV("%s:%s=%d, write(), len = %d", __FILE__, __func__, status, len); if (len == -1 && (errno == EINTR)) goto again1; if (len != 1) exit(1); if (chdir("/")) { perror("not able to chdir to /"); exit(1); } TFR(fd = qemu_open("/dev/null", O_RDWR)); if (fd == -1) exit(1); } change_root(); change_process_uid(); if (daemonize) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); close(fd); } }
int qemu_create_pidfile(const char *filename) { char buffer[128]; int len; #ifndef _WIN32 int fd; fd = qemu_open(filename, O_RDWR | O_CREAT, 0600); if (fd == -1) return -1; if (lockf(fd, F_TLOCK, 0) == -1) return -1; len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); if (write(fd, buffer, len) != len) return -1; #else HANDLE file; OVERLAPPED overlap; BOOL ret; memset(&overlap, 0, sizeof(overlap)); file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) return -1; len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len, &overlap, NULL); if (ret == 0) return -1; #endif return 0; }
/* * A basic test of a TPM device. We expect a well formatted response header * (error response is fine) within one second. */ static int tpm_passthrough_test_tpmdev(int fd) { struct tpm_req_hdr req = { .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND), .len = cpu_to_be32(sizeof(req)), .ordinal = cpu_to_be32(TPM_ORD_GetTicks), }; struct tpm_resp_hdr *resp; fd_set readfds; int n; struct timeval tv = { .tv_sec = 1, .tv_usec = 0, }; unsigned char buf[1024]; n = write(fd, &req, sizeof(req)); if (n < 0) { return errno; } if (n != sizeof(req)) { return EFAULT; } FD_ZERO(&readfds); FD_SET(fd, &readfds); /* wait for a second */ n = select(fd + 1, &readfds, NULL, NULL, &tv); if (n != 1) { return errno; } n = read(fd, &buf, sizeof(buf)); if (n < sizeof(struct tpm_resp_hdr)) { return EFAULT; } resp = (struct tpm_resp_hdr *)buf; /* check the header */ if (be16_to_cpu(resp->tag) != TPM_TAG_RSP_COMMAND || be32_to_cpu(resp->len) != n) { return EBADMSG; } return 0; } /* * Check whether the given base path, e.g., /sys/class/misc/tpm0/device, * is the sysfs directory of a TPM. A TPM sysfs directory should be uniquely * recognizable by the file entries 'pcrs' and 'cancel'. * Upon success 'true' is returned and the basebath buffer has '/cancel' * appended. */ static bool tpm_passthrough_check_sysfs_cancel(char *basepath, size_t bufsz) { char path[PATH_MAX]; struct stat statbuf; snprintf(path, sizeof(path), "%s/pcrs", basepath); if (stat(path, &statbuf) == -1 || !S_ISREG(statbuf.st_mode)) { return false; } snprintf(path, sizeof(path), "%s/cancel", basepath); if (stat(path, &statbuf) == -1 || !S_ISREG(statbuf.st_mode)) { return false; } strncpy(basepath, path, bufsz); return true; } /* * Unless path or file descriptor set has been provided by user, * determine the sysfs cancel file following kernel documentation * in Documentation/ABI/stable/sysfs-class-tpm. */ static int tpm_passthrough_open_sysfs_cancel(TPMBackend *tb) { int fd = -1; unsigned int idx; DIR *pnp_dir; char path[PATH_MAX]; struct dirent entry, *result; int len; if (tb->cancel_path) { fd = qemu_open(tb->cancel_path, O_WRONLY); if (fd < 0) { error_report("Could not open TPM cancel path : %s", strerror(errno)); } return fd; } snprintf(path, sizeof(path), "/sys/class/misc"); pnp_dir = opendir(path); if (pnp_dir != NULL) { while (readdir_r(pnp_dir, &entry, &result) == 0 && result != NULL) { /* * only allow /sys/class/misc/tpm%u type of paths */ if (sscanf(entry.d_name, "tpm%u%n", &idx, &len) < 1 || len <= strlen("tpm") || len != strlen(entry.d_name)) { continue; } snprintf(path, sizeof(path), "/sys/class/misc/%s/device", entry.d_name); if (!tpm_passthrough_check_sysfs_cancel(path, sizeof(path))) { continue; } fd = qemu_open(path, O_WRONLY); break; } closedir(pnp_dir); } if (fd >= 0) { tb->cancel_path = g_strdup(path); } return fd; }
static gboolean ga_channel_open(GAChannel *c, const gchar *path, GAChannelMethod method) { int ret; c->method = method; switch (c->method) { case GA_CHANNEL_VIRTIO_SERIAL: { int fd = qemu_open(path, O_RDWR | O_NONBLOCK #ifndef CONFIG_SOLARIS | O_ASYNC #endif ); if (fd == -1) { g_critical("error opening channel: %s", strerror(errno)); return false; } #ifdef CONFIG_SOLARIS ret = ioctl(fd, I_SETSIG, S_OUTPUT | S_INPUT | S_HIPRI); if (ret == -1) { g_critical("error setting event mask for channel: %s", strerror(errno)); close(fd); return false; } #endif ret = ga_channel_client_add(c, fd); if (ret) { g_critical("error adding channel to main loop"); close(fd); return false; } break; } case GA_CHANNEL_ISA_SERIAL: { struct termios tio; int fd = qemu_open(path, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd == -1) { g_critical("error opening channel: %s", strerror(errno)); return false; } tcgetattr(fd, &tio); /* set up serial port for non-canonical, dumb byte streaming */ tio.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY | IMAXBEL); tio.c_oflag = 0; tio.c_lflag = 0; tio.c_cflag |= GA_CHANNEL_BAUDRATE_DEFAULT; /* 1 available byte min or reads will block (we'll set non-blocking * elsewhere, else we have to deal with read()=0 instead) */ tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; /* flush everything waiting for read/xmit, it's garbage at this point */ tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &tio); ret = ga_channel_client_add(c, fd); if (ret) { g_critical("error adding channel to main loop"); close(fd); return false; } break; } case GA_CHANNEL_UNIX_LISTEN: { Error *local_err = NULL; int fd = unix_listen(path, NULL, strlen(path), &local_err); if (local_err != NULL) { g_critical("%s", error_get_pretty(local_err)); error_free(local_err); return false; } ga_channel_listen_add(c, fd, true); break; } default: g_critical("error binding/listening to specified socket"); return false; } return true; }
/** * \ingroup imglib * Opens one or more disk image files so that they can be read. If a file format * type is specified, this function will call the specific routine to open the file. * Otherwise, it will detect the type (it will default to raw if no specific type can * be detected). This function must be called before a disk image can be read from. * Note that the data type used to store the image paths is a TSK_TCHAR, which changes * depending on a Unix or Windows build. If you will always have UTF8, then consider * using tsk_img_open_utf8(). * * @param num_img The number of images to open (will be > 1 for split images). * @param images The path to the image files (the number of files must * be equal to num_img and they must be in a sorted order) * @param type The disk image type (can be autodetection) * @param a_ssize Size of device sector in bytes (or 0 for default) * * @return Pointer to TSK_IMG_INFO or NULL on error */ TSK_IMG_INFO * tsk_img_open(int num_img, const TSK_TCHAR * const images[], TSK_IMG_TYPE_ENUM type, unsigned int a_ssize) { TSK_IMG_INFO *img_info = NULL; // Get rid of any old error messages laying around tsk_error_reset(); if ((num_img == 0) || (images[0] == NULL)) { tsk_error_reset(); tsk_errno = TSK_ERR_IMG_NOFILE; snprintf(tsk_errstr, TSK_ERRSTR_L, "tsk_img_open"); return NULL; } if ((a_ssize > 0) && (a_ssize < 512)) { tsk_error_reset(); tsk_errno = TSK_ERR_IMG_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "sector size is less than 512 bytes (%d)", a_ssize); return NULL; } if ((a_ssize % 512) != 0) { tsk_error_reset(); tsk_errno = TSK_ERR_IMG_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "sector size is not a multiple of 512 (%d)", a_ssize); return NULL; } if (tsk_verbose) TFPRINTF(stderr, _TSK_T("tsk_img_open: Type: %d NumImg: %d Img1: %s\n"), type, num_img, images[0]); /* If no type is given, then we use the autodetection methods * In case the image file matches the signatures of multiple formats, * we try all of the embedded formats */ if (type == TSK_IMG_TYPE_DETECT) { TSK_IMG_INFO *img_set = NULL; #if HAVE_LIBAFFLIB || HAVE_LIBEWF char *set = NULL; #endif struct STAT_STR stat_buf; // we rely on tsk_errno, so make sure it is 0 tsk_error_reset(); /* Try the non-raw formats first */ #if HAVE_LIBAFFLIB if ((img_info = aff_open(images, a_ssize)) != NULL) { /* we don't allow the "ANY" when autodetect is used because * we only want to detect the tested formats. */ if (img_info->itype == TSK_IMG_TYPE_AFF_ANY) { img_info->close(img_info); } else { set = "AFF"; img_set = img_info; } } else { // If AFF is otherwise happy except for a password, stop trying to guess if (tsk_errno == TSK_ERR_IMG_PASSWD) { return NULL; } tsk_error_reset(); } #endif #if HAVE_LIBEWF if ((img_info = ewf_open(num_img, images, a_ssize)) != NULL) { if (set == NULL) { set = "EWF"; img_set = img_info; } else { img_set->close(img_set); img_info->close(img_info); tsk_error_reset(); tsk_errno = TSK_ERR_IMG_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "EWF or %s", set); return NULL; } } else { tsk_error_reset(); } #endif // if any of the non-raw formats were detected, then use it. if (img_set != NULL) return img_set; /* We'll use the raw format */ if (num_img == 1) { if ((img_info = raw_open(images[0], a_ssize)) != NULL) { return img_info; } else if (tsk_errno) { return NULL; } } else { if ((img_info = split_open(num_img, images, a_ssize)) != NULL) { return img_info; } else if (tsk_errno) { return NULL; } } /* To improve the error message, verify the file can be read. */ if (TSTAT(images[0], &stat_buf) < 0) { // special case to handle windows objects #if defined(TSK_WIN32) || defined(__CYGWIN__) if (TSTRNCMP(_TSK_T("\\\\.\\"), images[0], 4) == 0) { if (tsk_verbose) TFPRINTF(stderr, _TSK_T ("tsk_img_open: Ignoring stat error because of windows object: %s\n"), images[0]); } else { #endif tsk_error_reset(); tsk_errno = TSK_ERR_IMG_STAT; snprintf(tsk_errstr, TSK_ERRSTR_L, "%" PRIttocTSK " : %s", images[0], strerror(errno)); return NULL; #if defined(TSK_WIN32) || defined(__CYGWIN__) } #endif } tsk_errno = TSK_ERR_IMG_UNKTYPE; tsk_errstr[0] = '\0'; tsk_errstr2[0] = '\0'; return NULL; } /* * Type values * Make a local copy that we can modify the string as we parse it */ switch (type) { case TSK_IMG_TYPE_RAW_SING: /* If we have more than one image name, and raw was the only * type given, then use split */ if (num_img > 1) img_info = split_open(num_img, images, a_ssize); else img_info = raw_open(images[0], a_ssize); break; case TSK_IMG_TYPE_RAW_SPLIT: /* If only one image file is given, and only one type was * given then use raw */ if (num_img == 1) img_info = raw_open(images[0], a_ssize); else img_info = split_open(num_img, images, a_ssize); break; #if HAVE_LIBAFFLIB case TSK_IMG_TYPE_AFF_AFF: case TSK_IMG_TYPE_AFF_AFD: case TSK_IMG_TYPE_AFF_AFM: case TSK_IMG_TYPE_AFF_ANY: img_info = aff_open(images, a_ssize); break; #endif #if HAVE_LIBEWF case TSK_IMG_TYPE_EWF_EWF: img_info = ewf_open(num_img, images, a_ssize); break; #endif case TSK_IMG_TYPE_QEMU: img_info = qemu_open(images[0], a_ssize); break; default: tsk_error_reset(); tsk_errno = TSK_ERR_IMG_UNSUPTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "%d", type); return NULL; } return img_info; }
static int raw_open_common(BlockDriverState *bs, const char *filename, int bdrv_flags, int open_flags) { BDRVRawState *s = bs->opaque; int fd, ret; ret = raw_normalize_devicepath(&filename); if (ret != 0) { return ret; } s->open_flags = open_flags | O_BINARY; s->open_flags &= ~O_ACCMODE; if (bdrv_flags & BDRV_O_RDWR) { s->open_flags |= O_RDWR; } else { s->open_flags |= O_RDONLY; } /* Use O_DSYNC for write-through caching, no flags for write-back caching, * and O_DIRECT for no caching. */ if ((bdrv_flags & BDRV_O_NOCACHE)) s->open_flags |= O_DIRECT; if (!(bdrv_flags & BDRV_O_CACHE_WB)) s->open_flags |= O_DSYNC; s->fd = -1; fd = qemu_open(filename, s->open_flags, 0644); if (fd < 0) { ret = -errno; if (ret == -EROFS) ret = -EACCES; return ret; } s->fd = fd; s->aligned_buf = NULL; if ((bdrv_flags & BDRV_O_NOCACHE)) { /* * Allocate a buffer for read/modify/write cycles. Chose the size * pessimistically as we don't know the block size yet. */ s->aligned_buf_size = 32 * MAX_BLOCKSIZE; s->aligned_buf = qemu_memalign(MAX_BLOCKSIZE, s->aligned_buf_size); if (s->aligned_buf == NULL) { goto out_close; } } #ifdef CONFIG_LINUX_AIO if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) == (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) { /* We're falling back to POSIX AIO in some cases */ paio_init(); s->aio_ctx = laio_init(); if (!s->aio_ctx) { goto out_free_buf; } s->use_aio = 1; } else #endif { if (paio_init() < 0) { goto out_free_buf; } #ifdef CONFIG_LINUX_AIO s->use_aio = 0; #endif } #ifdef CONFIG_XFS if (platform_test_xfs_fd(s->fd)) { s->is_xfs = 1; } #endif return 0; out_free_buf: qemu_vfree(s->aligned_buf); out_close: close(fd); return -errno; }