Statistics
| Branch: | Tag: | Revision:

dvbd / unixserversocket.cpp @ bfdb7446

History | View | Annotate | Download (2.45 KB)

1 bfdb7446 jak
/*
2
  Copyright 2003 John Knottenbelt
3
  
4
  This program is free software; you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation; either version 2 of the License, or
7
  (at your option) any later version.
8
 
9
  This program 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
12
  GNU General Public License for more details.
13
 
14
  You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
*/
18
19
#include "config.h"
20
#include "unixserversocket.h"
21
#include <iostream>
22
#include <cstring>
23
#include <cstdlib>
24
#include <cerrno>
25
#include <unistd.h>
26
#include <sys/types.h>
27
#include <sys/socket.h>
28
#include <sys/un.h>
29
#include <fcntl.h>
30
31
UnixServerSocket::UnixServerSocket(const std::string &filename)
32
  : filename(filename)
33
{
34
  fd = socket(PF_UNIX, SOCK_STREAM, 0);
35
36
  if (!fd) {
37
    std::cerr << "Fatal error: failed to create socket for listening:\n"
38
              << strerror(errno) << std::endl;
39
    exit(1);
40
  }
41
42
  struct sockaddr_un addr;
43
  addr.sun_family = AF_UNIX;
44
  strcpy(addr.sun_path, filename.c_str());
45
46
  while (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
47
    if (errno == EADDRINUSE) {
48
      // Possibly old socket
49
      if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) >= 0) {
50
        close(fd);
51
        std::cerr << "Fatal error: dvbd already running on socket " << filename << std::endl;
52
        exit(1);
53
      }
54
      else 
55
        unlink(filename.c_str());
56
    }
57
    else {
58
      // Some other error
59
      std::cerr << "Fatal error: failed to bind socket to " << filename << "\n"
60
              << strerror(errno) << std::endl;
61
      exit(1);
62
    }
63
  }
64
65
  if (listen(fd, 5) < 0) {
66
    std::cerr << "Fatal error: failed to listen on socket " << filename << "\n"
67
              << strerror(errno) << std::endl;
68
    exit(1);
69
  }
70
}
71
72
void UnixServerSocket::setNonBlocking()
73
{
74
  long flags = fcntl(fd, F_GETFL, 0); 
75
  flags |= O_NONBLOCK;
76
  fcntl(fd, F_SETFL, flags);
77
}
78
79
80
UnixServerSocket::~UnixServerSocket()
81
{
82
  close(fd);
83
  unlink(filename.c_str());
84
}
85
86
void UnixServerSocket::addSelectFDs(Select &s) const
87
{
88
  s.addReadFD(fd);
89
}
90
91
bool UnixServerSocket::isReady(const Select &s) const
92
{
93
  return s.readyToRead(fd);
94
}
95
  
96
int UnixServerSocket::accept()
97
{
98
  return ::accept(fd, NULL, 0);
99
}