kstars
port.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <stdio.h>
00033 #include <errno.h>
00034
00035 #ifdef LOCKING
00036 #include <fcntl.h>
00037 #include <sys/stat.h>
00038 #endif
00039
00040 #ifdef __linux__
00041 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
00042 #include <fcntl.h>
00043 #else
00044 #include <sys/io.h>
00045 #endif
00046 #elif defined(QNX)
00047 #include <conio.h>
00048 #elif defined(__FreeBSD__)
00049 #include <sys/types.h>
00050 #include <machine/cpufunc.h>
00051 #elif defined(BSDI)
00052 #include <machine/inline.h>
00053 #elif defined(OPENBSD)
00054 #include <machine/pio.h>
00055 #elif defined(LYNX)
00056 #include "lynx-io.h"
00057 #elif defined(SOLARIS)
00058 #include "solaris-io.h"
00059 #else
00060 #error Please define a platform in the Makefile
00061 #endif
00062
00063 #include "port.h"
00064
00065 port_t::port_t(int iport) {
00066 port = -1;
00067
00068 #ifdef LOCKING
00069 if (lock(iport) == -1) {
00070 #ifdef DEBUG
00071 fprintf(stderr, "port 0x%x already locked\n", iport);
00072 #endif
00073 return;
00074 }
00075 #endif
00076
00077 #ifdef LINUX
00078 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
00079 if ((devport = open("/dev/port", O_RDWR)) < 0) {
00080 perror("open /dev/port");
00081 return;
00082 }
00083 #else
00084 if (ioperm(iport, 3, 1) == -1) {
00085 perror("ioperm()");
00086 return;
00087 }
00088 #endif
00089 #elif defined(FREEBSD)
00090 if ((devio = fopen("/dev/io", "r+")) == NULL) {
00091 perror("fopen /dev/io");
00092 return;
00093 }
00094 #elif defined(OPENBSD)
00095 if (i386_iopl(1) == -1) {
00096 perror("i386_iopl");
00097 return;
00098 }
00099 #elif defined(LYNX)
00100 if (io_access() < 0) {
00101 perror("io_access");
00102 return;
00103 }
00104 #elif defined(SOLARIS)
00105 if (openiop()) {
00106 perror("openiop");
00107 return;
00108 }
00109 #endif
00110
00111 port = iport;
00112 port1 = port + 1;
00113 port2 = port + 2;
00114 control_reg = read_control();
00115 }
00116
00117 port_t::~port_t(void) {
00118 #ifdef LOCKING
00119 unlock(port);
00120 #endif
00121 #ifdef LINUX
00122 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
00123 if (devport >= 0)
00124 close(devport);
00125 #else
00126 if (port > 0 && geteuid() == 0)
00127 if (ioperm(port, 3, 0) != 0)
00128
00129 perror("ioperm()");
00130 #endif
00131 #elif defined(FREEBSD)
00132 if (devio != NULL)
00133 fclose(devio);
00134 #elif defined(SOLARIS)
00135 close(iopfd);
00136 #endif
00137 }
00138
00139 #ifdef LOCKING
00140 int port_t::lock(int portnum) {
00141 char lockfile[80];
00142 sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum);
00143 while ((lock_fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == -1) {
00144 if (errno != EEXIST) {
00145 perror(lockfile);
00146 return -1;
00147 }
00148 struct stat stat_buf;
00149 if (lstat(lockfile, &stat_buf) < 0) continue;
00150 if (S_ISLNK(stat_buf.st_mode) || stat_buf.st_uid != 0) {
00151 if (unlink(lockfile)) {
00152 if (errno == ENOENT) continue;
00153 if (errno != EISDIR || (rmdir(lockfile) && errno != ENOENT)) {
00154
00155
00156 perror(lockfile);
00157 return -1;
00158 }
00159 }
00160 continue;
00161 }
00162 lock_fd = open(lockfile, O_WRONLY, 0600);
00163 if (lock_fd == -1) {
00164 perror(lockfile);
00165 return -1;
00166 }
00167 break;
00168 }
00169
00170 static struct flock lock_info;
00171 lock_info.l_type = F_WRLCK;
00172 #ifdef LOCK_FAIL
00173 if (fcntl(lock_fd, F_SETLK, &lock_info) != 0) {
00174 #else
00175 if (fcntl(lock_fd, F_SETLKW, &lock_info) != 0) {
00176 #endif
00177 if (errno != EAGAIN)
00178 perror("fcntl");
00179 return -1;
00180 }
00181 chown(lockfile, getuid(), getgid());
00182 #ifdef DEBUG
00183 fprintf(stderr, "Locked port 0x%x\n", portnum);
00184 #endif
00185 return 0;
00186 }
00187
00188 void port_t::unlock(int portnum) {
00189 if (portnum == -1)
00190 return;
00191 close(lock_fd);
00192 char lockfile[80];
00193 sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum);
00194 if (unlink(lockfile)) perror(lockfile);
00195 #ifdef DEBUG
00196 fprintf(stderr, "Unlocked port 0x%x\n", portnum);
00197 #endif
00198 }
00199 #endif