diff options
Diffstat (limited to 'kstars/kstars/indi/webcam/port.cpp')
-rw-r--r-- | kstars/kstars/indi/webcam/port.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/kstars/kstars/indi/webcam/port.cpp b/kstars/kstars/indi/webcam/port.cpp new file mode 100644 index 00000000..fce53a18 --- /dev/null +++ b/kstars/kstars/indi/webcam/port.cpp @@ -0,0 +1,199 @@ +/* libcqcam - shared Color Quickcam routines + * Copyright (C) 1996-1998 by Patrick Reynolds + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// I/O ports wrapper code +// This file might need tweaking if you're trying to port my code to other +// x86 Unix platforms. Code is already available for Linux, FreeBSD, and +// QNX; see the Makefile. +// +// QNX code by: Anders Arpteg <aa11ac@hik.se> +// FreeBSD code by: Patrick Reynolds <reynolds@cs.duke.edu> and Charles +// Henrich <henrich@msu.edu> + + +//#include "config.h" + +#include <stdio.h> +#include <errno.h> + +#ifdef LOCKING +#include <fcntl.h> +#include <sys/stat.h> +#endif /* LOCKING */ + +#ifdef __linux__ + #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__) + #include <fcntl.h> + #else + #include <sys/io.h> + #endif /* arm */ +#elif defined(QNX) +#include <conio.h> +#elif defined(__FreeBSD__) +#include <sys/types.h> +#include <machine/cpufunc.h> +#elif defined(BSDI) +#include <machine/inline.h> +#elif defined(OPENBSD) +#include <machine/pio.h> +#elif defined(LYNX) +#include "lynx-io.h" +#elif defined(SOLARIS) +#include "solaris-io.h" +#else +#error Please define a platform in the Makefile +#endif /* which OS */ + +#include "port.h" + +port_t::port_t(int iport) { + port = -1; + +#ifdef LOCKING + if (lock(iport) == -1) { +#ifdef DEBUG + fprintf(stderr, "port 0x%x already locked\n", iport); +#endif /* DEBUG */ + return; + } +#endif /* LOCKING */ + +#ifdef LINUX +#if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__) + if ((devport = open("/dev/port", O_RDWR)) < 0) { + perror("open /dev/port"); + return; + } +#else + if (ioperm(iport, 3, 1) == -1) { + perror("ioperm()"); + return; + } +#endif /* arm */ +#elif defined(FREEBSD) + if ((devio = fopen("/dev/io", "r+")) == NULL) { + perror("fopen /dev/io"); + return; + } +#elif defined(OPENBSD) + if (i386_iopl(1) == -1) { + perror("i386_iopl"); + return; + } +#elif defined(LYNX) + if (io_access() < 0) { + perror("io_access"); + return; + } +#elif defined(SOLARIS) + if (openiop()) { + perror("openiop"); + return; + } +#endif /* which OS */ + + port = iport; + port1 = port + 1; + port2 = port + 2; + control_reg = read_control(); +} + +port_t::~port_t(void) { +#ifdef LOCKING + unlock(port); +#endif /* LOCKING */ +#ifdef LINUX +#if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__) + if (devport >= 0) + close(devport); +#else + if (port > 0 && geteuid() == 0) + if (ioperm(port, 3, 0) != 0) // drop port permissions -- still must + // be root + perror("ioperm()"); +#endif /* arm */ +#elif defined(FREEBSD) + if (devio != NULL) + fclose(devio); +#elif defined(SOLARIS) + close(iopfd); +#endif /* which OS */ +} + +#ifdef LOCKING +int port_t::lock(int portnum) { + char lockfile[80]; + sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum); + while ((lock_fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == -1) { + if (errno != EEXIST) { + perror(lockfile); + return -1; + } + struct stat stat_buf; + if (lstat(lockfile, &stat_buf) < 0) continue; + if (S_ISLNK(stat_buf.st_mode) || stat_buf.st_uid != 0) { + if (unlink(lockfile)) { + if (errno == ENOENT) continue; + if (errno != EISDIR || (rmdir(lockfile) && errno != ENOENT)) { + /* known problem: if lockfile exists and is a non-empty + directory, we give up instead of doing an rm-r of it */ + perror(lockfile); + return -1; + } + } + continue; + } + lock_fd = open(lockfile, O_WRONLY, 0600); + if (lock_fd == -1) { + perror(lockfile); + return -1; + } + break; + } + + static struct flock lock_info; + lock_info.l_type = F_WRLCK; +#ifdef LOCK_FAIL + if (fcntl(lock_fd, F_SETLK, &lock_info) != 0) { +#else + if (fcntl(lock_fd, F_SETLKW, &lock_info) != 0) { +#endif /* LOCK_FAIL */ + if (errno != EAGAIN) + perror("fcntl"); + return -1; + } + chown(lockfile, getuid(), getgid()); +#ifdef DEBUG + fprintf(stderr, "Locked port 0x%x\n", portnum); +#endif /* DEBUG */ + return 0; +} + +void port_t::unlock(int portnum) { + if (portnum == -1) + return; + close(lock_fd); // this clears the lock + char lockfile[80]; + sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum); + if (unlink(lockfile)) perror(lockfile); +#ifdef DEBUG + fprintf(stderr, "Unlocked port 0x%x\n", portnum); +#endif /* DEBUG */ +} +#endif /* LOCKING */ |