Statistics
| Branch: | Tag: | Revision:

dvbd / src / unixserversocket.cpp @ 59be6a47

History | View | Annotate | Download (2.5 KB)

1
/*
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
  mode_t oldMask = umask(007);
47
  while (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
48
    if (errno == EADDRINUSE) {
49
      // Possibly old socket
50
      if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) >= 0) {
51
        close(fd);
52
        std::cerr << "Fatal error: dvbd already running on socket " << filename << std::endl;
53
        exit(1);
54
      }
55
      else 
56
        unlink(filename.c_str());
57
    }
58
    else {
59
      // Some other error
60
      std::cerr << "Fatal error: failed to bind socket to " << filename << "\n"
61
              << strerror(errno) << std::endl;
62
      exit(1);
63
    }
64
  }
65

    
66
  if (listen(fd, 5) < 0) {
67
    std::cerr << "Fatal error: failed to listen on socket " << filename << "\n"
68
              << strerror(errno) << std::endl;
69
    exit(1);
70
  }
71

    
72
  umask(oldMask);
73
}
74

    
75
void UnixServerSocket::setNonBlocking()
76
{
77
  long flags = fcntl(fd, F_GETFL, 0); 
78
  flags |= O_NONBLOCK;
79
  fcntl(fd, F_SETFL, flags);
80
}
81

    
82

    
83
UnixServerSocket::~UnixServerSocket()
84
{
85
  close(fd);
86
  unlink(filename.c_str());
87
}
88

    
89
void UnixServerSocket::addSelectFDs(Select &s) const
90
{
91
  s.addReadFD(fd);
92
}
93

    
94
bool UnixServerSocket::isReady(const Select &s) const
95
{
96
  return s.readyToRead(fd);
97
}
98
  
99
int UnixServerSocket::accept()
100
{
101
  return ::accept(fd, NULL, 0);
102
}