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>
41 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
48 #elif defined(FREEBSD)
49 #include <machine/cpufunc.h>
51 #include <machine/inline.h>
52 #elif defined(OPENBSD)
53 #include <machine/pio.h>
56 #elif defined(SOLARIS)
57 #include "solaris-io.h"
59 #error Please define a platform in the Makefile
64 port_t::port_t(int iport
) {
68 if (lock(iport
) == -1) {
70 fprintf(stderr
, "port 0x%x already locked\n", iport
);
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");
83 if (ioperm(iport
, 3, 1) == -1) {
88 #elif defined(FREEBSD)
89 if ((devio
= fopen("/dev/io", "r+")) == NULL
) {
90 perror("fopen /dev/io");
93 #elif defined(OPENBSD)
94 if (i386_iopl(1) == -1) {
99 if (io_access() < 0) {
103 #elif defined(SOLARIS)
108 #endif /* which OS */
113 control_reg
= read_control();
116 port_t::~port_t(void) {
121 #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)
125 if (port
> 0 && geteuid() == 0)
126 if (ioperm(port
, 3, 0) != 0) // drop port permissions -- still must
130 #elif defined(FREEBSD)
133 #elif defined(SOLARIS)
135 #endif /* which OS */
139 int port_t::lock(int portnum
) {
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
) {
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 */
161 lock_fd
= open(lockfile
, O_WRONLY
, 0600);
169 static struct flock lock_info
;
170 lock_info
.l_type
= F_WRLCK
;
172 if (fcntl(lock_fd
, F_SETLK
, &lock_info
) != 0) {
174 if (fcntl(lock_fd
, F_SETLKW
, &lock_info
) != 0) {
175 #endif /* LOCK_FAIL */
180 chown(lockfile
, getuid(), getgid());
182 fprintf(stderr
, "Locked port 0x%x\n", portnum
);
187 void port_t::unlock(int portnum
) {
190 close(lock_fd
); // this clears the lock
192 sprintf(lockfile
, "/tmp/LOCK.qcam.0x%x", portnum
);
193 if (unlink(lockfile
)) perror(lockfile
);
195 fprintf(stderr
, "Unlocked port 0x%x\n", portnum
);