1 /* wrapsock.c provides access to socket related system calls.
3 Copyright (C) 2008-2022 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
30 #define EXPORT(FUNC) m2iso ## _wrapsock_ ## FUNC
31 #define IMPORT(MODULE,FUNC) m2iso ## _ ## MODULE ## _ ## FUNC
32 #define M2EXPORT(FUNC) m2iso ## _M2_wrapsock_ ## FUNC
33 #define M2LIBNAME "m2iso"
35 /* This module should be rewritten to use C++. */
37 typedef void (*proc_con
) (int, char **, char **);
38 typedef void (*proc_dep
) (void);
40 extern void m2iso_M2RTS_RequestDependant (const char *modulename
, const char *libname
, const char *dependancy
);
41 extern void m2iso_M2RTS_RegisterModule (const char *modulename
, const char *libname
,
42 proc_con init
, proc_con fini
, proc_dep dependencies
);
44 #if defined(HAVE_SYS_TYPES_H)
45 #include "sys/types.h"
48 #if defined(HAVE_SYS_SOCKET_H)
49 #include "sys/socket.h"
52 #if defined(HAVE_NETINET_IN_H)
53 #include "netinet/in.h"
56 #if defined(HAVE_NETDB_H)
60 #if defined(HAVE_UNISTD_H)
64 #if defined(HAVE_SIGNAL_H)
68 #if defined(HAVE_SYS_ERRNO_H)
69 #include "sys/errno.h"
72 #if defined(HAVE_ERRNO_H)
76 #if defined(HAVE_MALLOC_H)
80 #if defined(HAVE_MALLOC_H)
84 #if defined(HAVE_STRING_H)
88 #if defined(HAVE_STDLIB_H)
92 #include "ChanConsts.h"
94 #define MAXHOSTNAME 1024
97 #if defined(HAVE_NETINET_IN_H)
101 char hostname
[MAXHOSTNAME
];
103 struct sockaddr_in sa
;
107 char pbChar
[MAXPBBUF
];
110 static openResults
clientConnect (clientInfo
*c
);
112 /* clientOpen - returns an ISO Modula-2 OpenResult. It attempts to
113 connect to: hostname:portNo. If successful then the data
114 structure, c, will have its fields initialized. */
117 EXPORT(clientOpen
) (clientInfo
*c
, char *hostname
, unsigned int length
,
120 /* remove SIGPIPE which is raised on the server if the client is killed. */
121 signal (SIGPIPE
, SIG_IGN
);
123 c
->hp
= gethostbyname (hostname
);
127 memset ((void *)&c
->sa
, 0, sizeof (c
->sa
));
128 c
->sa
.sin_family
= AF_INET
;
129 memcpy ((void *)&c
->sa
.sin_addr
, (void *)c
->hp
->h_addr
, c
->hp
->h_length
);
131 c
->sa
.sin_port
= htons (portNo
);
133 /* Open a TCP socket (an Internet stream socket) */
135 c
->sockFd
= socket (c
->hp
->h_addrtype
, SOCK_STREAM
, 0);
136 return clientConnect (c
);
139 /* clientOpenIP - returns an ISO Modula-2 OpenResult. It attempts to
140 connect to: ipaddress:portNo. If successful then the data
141 structure, c, will have its fields initialized. */
144 EXPORT(clientOpenIP
) (clientInfo
*c
, unsigned int ip
, int portNo
)
146 /* remove SIGPIPE which is raised on the server if the client is killed. */
147 signal (SIGPIPE
, SIG_IGN
);
149 memset ((void *)&c
->sa
, 0, sizeof (c
->sa
));
150 c
->sa
.sin_family
= AF_INET
;
151 memcpy ((void *)&c
->sa
.sin_addr
, (void *)&ip
, sizeof (ip
));
153 c
->sa
.sin_port
= htons (portNo
);
155 /* Open a TCP socket (an Internet stream socket) */
157 c
->sockFd
= socket (PF_INET
, SOCK_STREAM
, 0);
158 return clientConnect (c
);
161 /* clientConnect - returns an ISO Modula-2 OpenResult once a connect
162 has been performed. If successful the clientInfo will include the
163 file descriptor ready for read/write operations. */
166 clientConnect (clientInfo
*c
)
168 if (connect (c
->sockFd
, (struct sockaddr
*)&c
->sa
, sizeof (c
->sa
)) < 0)
174 /* getClientPortNo - returns the portNo from structure, c. */
177 EXPORT(getClientPortNo
) (clientInfo
*c
)
182 /* getClientHostname - fills in the hostname of the server the to
183 which the client is connecting. */
186 EXPORT(getClientHostname
) (clientInfo
*c
, char *hostname
, unsigned int high
)
188 strncpy (hostname
, c
->hostname
, high
+ 1);
191 /* getClientSocketFd - returns the sockFd from structure, c. */
194 EXPORT(getClientSocketFd
) (clientInfo
*c
)
199 /* getClientIP - returns the sockFd from structure, s. */
202 EXPORT(getClientIP
) (clientInfo
*c
)
205 printf("client ip = %s\n", inet_ntoa (c
->sa
.sin_addr
.s_addr
));
207 return c
->sa
.sin_addr
.s_addr
;
210 /* getPushBackChar returns true if a pushed back character is
214 EXPORT(getPushBackChar
) (clientInfo
*c
, char *ch
)
219 *ch
= c
->pbChar
[c
->hasChar
];
225 /* setPushBackChar returns true if it is able to push back a
229 EXPORT(setPushBackChar
) (clientInfo
*c
, char ch
)
231 if (c
->hasChar
== MAXPBBUF
)
233 c
->pbChar
[c
->hasChar
] = ch
;
238 /* getSizeOfClientInfo - returns the sizeof (opaque data type). */
241 EXPORT(getSizeOfClientInfo
) (void)
243 return sizeof (clientInfo
);
249 /* GNU Modula-2 linking hooks. */
252 M2EXPORT(init
) (int, char **, char **)
257 M2EXPORT(fini
) (int, char **, char **)
266 void __attribute__((__constructor__
))
267 M2EXPORT(ctor
) (void)
269 m2iso_M2RTS_RegisterModule ("wrapsock", M2LIBNAME
,
270 M2EXPORT(init
), M2EXPORT(fini
),