Welcome to mirror list, hosted at ThFree Co, Russian Federation.

transport_sockets.cc « cygserver « winsup - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a3a98b3e5516ea97a5cb14631983df07a355fb44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* cygserver_transport_sockets.cc

   Copyright 2001, 2002 Red Hat Inc.

   Written by Robert Collins <rbtcollins@hotmail.com>

   This file is part of Cygwin.

   This software is a copyrighted work licensed under the terms of the
   Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
   details. */

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <windows.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "wincap.h"
#include "cygwin/cygserver_transport.h"
#include "cygwin/cygserver_transport_sockets.h"

/* to allow this to link into cygwin and the .dll, a little magic is needed. */
#ifndef __OUTSIDE_CYGWIN__
#include "winsup.h"
extern "C" int
cygwin_socket (int af, int type, int protocol);
extern "C" int
cygwin_connect (int fd,
		const struct sockaddr *name,
		int namelen);
extern "C" int
cygwin_accept (int fd, struct sockaddr *peer, int *len);
extern "C" int
cygwin_listen (int fd, int backlog);
extern "C" int
cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen);

#else
#define cygwin_accept(A,B,C)  ::accept(A,B,C)
#define cygwin_socket(A,B,C)  ::socket(A,B,C)
#define cygwin_listen(A,B)    ::listen(A,B)
#define cygwin_bind(A,B,C)    ::bind(A,B,C)
#define cygwin_connect(A,B,C) ::connect(A,B,C)
#define debug_printf printf
#endif

transport_layer_sockets::transport_layer_sockets (int newfd): fd(newfd)
{
  /* This may not be needed in this constructor - it's only used
   * when creating a connection via bind or connect
   */
  sockdetails.sa_family = AF_UNIX;
  strcpy (sockdetails.sa_data, "/tmp/cygdaemo");
  sdlen = strlen(sockdetails.sa_data) + sizeof(sockdetails.sa_family);
};

transport_layer_sockets::transport_layer_sockets (): fd (-1)
{
  sockdetails.sa_family = AF_UNIX;
  strcpy (sockdetails.sa_data, "/tmp/cygdaemo");
  sdlen = strlen(sockdetails.sa_data) + sizeof(sockdetails.sa_family);
}

void
transport_layer_sockets::listen ()
{
  /* we want a thread pool based approach. */
  if ((fd = cygwin_socket (AF_UNIX, SOCK_STREAM,0)) < 0)
    printf ("Socket not created error %d\n", errno);
  if (cygwin_bind(fd, &sockdetails, sdlen))
    printf ("Bind doesn't like you. Tsk Tsk. Bind said %d\n", errno);
  if (cygwin_listen(fd, 5) < 0)
    printf ("And the OS just isn't listening, all it says is %d\n", errno);
}

class transport_layer_sockets *
transport_layer_sockets::accept ()
{
  /* FIXME: check we have listened */
  int new_fd;

  if ((new_fd = cygwin_accept(fd, &sockdetails, &sdlen)) < 0)
    {
      printf ("Nup, could' accept. %d\n",errno);
      return NULL;
    }

  transport_layer_sockets *new_conn = new transport_layer_sockets (new_fd);

  return new_conn;

}

void
transport_layer_sockets::close()
{
  /* FIXME - are we open? */
  ::close (fd);
}

ssize_t
transport_layer_sockets::read (char *buf, size_t len)
{
  /* FIXME: are we open? */
  return ::read (fd, buf, len);
}

ssize_t
transport_layer_sockets::write (char *buf, size_t len)
{
  /* FIXME: are we open? */
  return ::write (fd, buf, len);
}

bool
transport_layer_sockets::connect ()
{
  /* are we already connected? */
  if (fd != -1)
    return false;
  fd = cygwin_socket (AF_UNIX, SOCK_STREAM, 0);
  if (cygwin_connect (fd, &sockdetails, sdlen) < 0)
    {
      debug_printf("client connect failure %d\n", errno);
      ::close (fd);
      return false;
    }
  return true;
}