source: BAORadio/libindi/libindi/libs/webcam/port.cpp @ 642

Last change on this file since 642 was 642, checked in by frichard, 12 years ago

-Alignement des antennes
-Version 0.0.9 de libindi

File size: 5.2 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#ifdef __linux__
41#if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) \
42        || defined(__powerpc__) || defined(__s390__) || defined(__s390x__)\
43        || defined(__mips__) || defined(__mc68000__) || defined(__sh__)
44#define NO_SYSIO
45#endif /* architechtures */
46#endif /* __linux__ */
47
48#ifdef __linux__
49  #if defined(NO_SYSIO)
50  #include <fcntl.h>
51  #else
52  #include <sys/io.h>
53  #endif /* NO_SYSIO */
54#elif defined(QNX)
55#include <conio.h>
56#elif defined(__FreeBSD__)
57#include <sys/types.h>
58#include <machine/cpufunc.h>
59#elif defined(BSDI)
60#include <machine/inline.h>
61#elif defined(OPENBSD)
62#include <machine/pio.h>
63#elif defined(LYNX)
64#include "lynx-io.h"
65#elif defined(SOLARIS)
66#include "solaris-io.h"
67#else
68#error Please define a platform in the Makefile
69#endif /* which OS */
70
71#include "port.h"
72
73port_t::port_t(int iport) {
74  port = -1;
75
76#ifdef LOCKING
77  if (lock(iport) == -1) {
78#ifdef DEBUG
79    fprintf(stderr, "port 0x%x already locked\n", iport);
80#endif /* DEBUG */
81    return;
82  }
83#endif /* LOCKING */
84
85#ifdef LINUX
86#ifdef NO_SYSIO
87  if ((devport = open("/dev/port", O_RDWR)) < 0) {
88    perror("open /dev/port");
89    return;
90  }
91#else
92  if (ioperm(iport, 3, 1) == -1) {
93    perror("ioperm()");
94    return;
95  }
96#endif /* NO_SYSIO */
97#elif defined(FREEBSD)
98  if ((devio = fopen("/dev/io", "r+")) == NULL) {
99    perror("fopen /dev/io");
100    return;
101  }
102#elif defined(OPENBSD)
103  if (i386_iopl(1) == -1) {
104    perror("i386_iopl");
105    return;
106  }
107#elif defined(LYNX)
108  if (io_access() < 0) {
109    perror("io_access");
110    return;
111  }
112#elif defined(SOLARIS)
113  if (openiop()) {
114    perror("openiop");
115    return;
116  }
117#endif /* which OS */
118
119  port = iport;
120  port1 = port + 1;
121  port2 = port + 2;
122  control_reg = read_control();
123}
124
125port_t::~port_t(void) {
126#ifdef LOCKING
127  unlock(port);
128#endif /* LOCKING */
129#ifdef LINUX
130#ifdef NO_SYSIO
131  if (devport >= 0)
132    close(devport);
133#else
134  if (port > 0 && geteuid() == 0)
135    if (ioperm(port, 3, 0) != 0)  // drop port permissions -- still must
136                                  // be root
137      perror("ioperm()");
138#endif /* NO_SYSIO */
139#elif defined(FREEBSD)
140  if (devio != NULL)
141    fclose(devio);
142#elif defined(SOLARIS)
143  close(iopfd);
144#endif /* which OS */
145}
146
147#ifdef LOCKING
148int port_t::lock(int portnum) {
149  char lockfile[80];
150  sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum);
151  while ((lock_fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == -1) {
152    if (errno != EEXIST) {
153      perror(lockfile);
154      return -1;
155    }
156    struct stat stat_buf;
157    if (lstat(lockfile, &stat_buf) < 0) continue;
158    if (S_ISLNK(stat_buf.st_mode) || stat_buf.st_uid != 0) {
159      if (unlink(lockfile)) {
160        if (errno == ENOENT) continue;
161        if (errno != EISDIR || (rmdir(lockfile) && errno != ENOENT)) {
162            /* known problem: if lockfile exists and is a non-empty
163               directory, we give up instead of doing an rm-r of it */
164          perror(lockfile);
165          return -1;
166        }
167      }
168      continue;
169    }
170    lock_fd = open(lockfile, O_WRONLY, 0600);
171    if (lock_fd == -1) {
172      perror(lockfile);
173      return -1;
174    }
175    break;
176  }
177
178  static struct flock lock_info;
179  lock_info.l_type = F_WRLCK;
180#ifdef LOCK_FAIL
181  if (fcntl(lock_fd, F_SETLK, &lock_info) != 0) {
182#else
183  if (fcntl(lock_fd, F_SETLKW, &lock_info) != 0) {
184#endif /* LOCK_FAIL */
185    if (errno != EAGAIN)
186      perror("fcntl");
187    return -1;
188  }
189  chown(lockfile, getuid(), getgid());
190#ifdef DEBUG
191  fprintf(stderr, "Locked port 0x%x\n", portnum);
192#endif /* DEBUG */
193  return 0;
194}
195   
196void port_t::unlock(int portnum) {
197  if (portnum == -1)
198    return;
199  close(lock_fd);    // this clears the lock
200  char lockfile[80];
201  sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum);
202  if (unlink(lockfile)) perror(lockfile);
203#ifdef DEBUG
204  fprintf(stderr, "Unlocked port 0x%x\n", portnum);
205#endif /* DEBUG */
206}
207#endif /* LOCKING */
Note: See TracBrowser for help on using the repository browser.