source: BAORadio/libindi/v1.0.1/libs/webcam/port.cpp @ 614

Last change on this file since 614 was 490, checked in by campagne, 14 years ago

import libindi (JEC)

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