moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kstars / kstars / indi / webcam / port.cpp
bloba3b839c9e22e15a3a3348695260195bdb825333a
1 /* libcqcam - shared Color Quickcam routines
2 * Copyright (C) 1996-1998 by Patrick Reynolds
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 // I/O ports wrapper code
21 // This file might need tweaking if you're trying to port my code to other
22 // x86 Unix platforms. Code is already available for Linux, FreeBSD, and
23 // QNX; see the Makefile.
25 // QNX code by: Anders Arpteg <aa11ac@hik.se>
26 // FreeBSD code by: Patrick Reynolds <reynolds@cs.duke.edu> and Charles
27 // Henrich <henrich@msu.edu>
30 //#include "config.h"
32 #include <stdio.h>
33 #include <errno.h>
35 #ifdef LOCKING
36 #include <fcntl.h>
37 #include <sys/stat.h>
38 #endif /* LOCKING */
40 #ifdef __linux__
41 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
42 #include <fcntl.h>
43 #else
44 #include <sys/io.h>
45 #endif /* arm */
46 #elif defined(QNX)
47 #include <conio.h>
48 #elif defined(FREEBSD)
49 #include <machine/cpufunc.h>
50 #elif defined(BSDI)
51 #include <machine/inline.h>
52 #elif defined(OPENBSD)
53 #include <machine/pio.h>
54 #elif defined(LYNX)
55 #include "lynx-io.h"
56 #elif defined(SOLARIS)
57 #include "solaris-io.h"
58 #else
59 #error Please define a platform in the Makefile
60 #endif /* which OS */
62 #include "port.h"
64 port_t::port_t(int iport) {
65 port = -1;
67 #ifdef LOCKING
68 if (lock(iport) == -1) {
69 #ifdef DEBUG
70 fprintf(stderr, "port 0x%x already locked\n", iport);
71 #endif /* DEBUG */
72 return;
74 #endif /* LOCKING */
76 #ifdef LINUX
77 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
78 if ((devport = open("/dev/port", O_RDWR)) < 0) {
79 perror("open /dev/port");
80 return;
82 #else
83 if (ioperm(iport, 3, 1) == -1) {
84 perror("ioperm()");
85 return;
87 #endif /* arm */
88 #elif defined(FREEBSD)
89 if ((devio = fopen("/dev/io", "r+")) == NULL) {
90 perror("fopen /dev/io");
91 return;
93 #elif defined(OPENBSD)
94 if (i386_iopl(1) == -1) {
95 perror("i386_iopl");
96 return;
98 #elif defined(LYNX)
99 if (io_access() < 0) {
100 perror("io_access");
101 return;
103 #elif defined(SOLARIS)
104 if (openiop()) {
105 perror("openiop");
106 return;
108 #endif /* which OS */
110 port = iport;
111 port1 = port + 1;
112 port2 = port + 2;
113 control_reg = read_control();
116 port_t::~port_t(void) {
117 #ifdef LOCKING
118 unlock(port);
119 #endif /* LOCKING */
120 #ifdef LINUX
121 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
122 if (devport >= 0)
123 close(devport);
124 #else
125 if (port > 0 && geteuid() == 0)
126 if (ioperm(port, 3, 0) != 0) // drop port permissions -- still must
127 // be root
128 perror("ioperm()");
129 #endif /* arm */
130 #elif defined(FREEBSD)
131 if (devio != NULL)
132 fclose(devio);
133 #elif defined(SOLARIS)
134 close(iopfd);
135 #endif /* which OS */
138 #ifdef LOCKING
139 int port_t::lock(int portnum) {
140 char lockfile[80];
141 sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum);
142 while ((lock_fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == -1) {
143 if (errno != EEXIST) {
144 perror(lockfile);
145 return -1;
147 struct stat stat_buf;
148 if (lstat(lockfile, &stat_buf) < 0) continue;
149 if (S_ISLNK(stat_buf.st_mode) || stat_buf.st_uid != 0) {
150 if (unlink(lockfile)) {
151 if (errno == ENOENT) continue;
152 if (errno != EISDIR || (rmdir(lockfile) && errno != ENOENT)) {
153 /* known problem: if lockfile exists and is a non-empty
154 directory, we give up instead of doing an rm-r of it */
155 perror(lockfile);
156 return -1;
159 continue;
161 lock_fd = open(lockfile, O_WRONLY, 0600);
162 if (lock_fd == -1) {
163 perror(lockfile);
164 return -1;
166 break;
169 static struct flock lock_info;
170 lock_info.l_type = F_WRLCK;
171 #ifdef LOCK_FAIL
172 if (fcntl(lock_fd, F_SETLK, &lock_info) != 0) {
173 #else
174 if (fcntl(lock_fd, F_SETLKW, &lock_info) != 0) {
175 #endif /* LOCK_FAIL */
176 if (errno != EAGAIN)
177 perror("fcntl");
178 return -1;
180 chown(lockfile, getuid(), getgid());
181 #ifdef DEBUG
182 fprintf(stderr, "Locked port 0x%x\n", portnum);
183 #endif /* DEBUG */
184 return 0;
187 void port_t::unlock(int portnum) {
188 if (portnum == -1)
189 return;
190 close(lock_fd); // this clears the lock
191 char lockfile[80];
192 sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum);
193 if (unlink(lockfile)) perror(lockfile);
194 #ifdef DEBUG
195 fprintf(stderr, "Unlocked port 0x%x\n", portnum);
196 #endif /* DEBUG */
198 #endif /* LOCKING */