Skip to content

Commit d35d0a6

Browse files
committed
Provide minimal support for Windows (fix #146)
Make both platform-dependant 'gio-unix-2.0' and 'gio-windows-2.0' dependencies optional and use features accordingly via 'GIO_UNIX' and 'GIO_WINDOWS' definitions. For FastCGI, gracefully fallback with no fd-based async I/O. Add basic cross files to target 32 and 64 bit targets.
1 parent b4edfb9 commit d35d0a6

11 files changed

Lines changed: 121 additions & 10 deletions

‎cross/i686-w64-mingw32.txt‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[binaries]
2+
c = '/usr/bin/i686-w64-mingw32-gcc'
3+
strip = '/usr/bin/i686-w64-mingw32-strip'
4+
pkgconfig = '/usr/bin/i686-w64-mingw32-pkg-config'
5+
6+
[host_machine]
7+
system = 'windows'
8+
cpu_family = 'x86'
9+
cpu = 'i686'
10+
endian = 'little'

‎cross/x86_64-w64-mingw32.txt‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[binaries]
2+
c = '/usr/bin/x86_64-w64-mingw32-gcc'
3+
strip = '/usr/bin/x86_64-w64-mingw32-strip'
4+
pkgconfig = '/usr/bin/x86_64-w64-mingw32-pkg-config'
5+
6+
[host_machine]
7+
system = 'windows'
8+
cpu_family = 'x86'
9+
cpu = 'x86_64'
10+
endian = 'little'

‎meson.build‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,30 @@ endif
2222
glib = dependency('glib-2.0', version: '>=2.40')
2323
gobject = dependency('gobject-2.0', version: '>=2.40')
2424
gio = dependency('gio-2.0', version: '>=2.40')
25-
gio_unix = dependency('gio-unix-2.0', version: '>=2.40')
25+
gio_unix = dependency('gio-unix-2.0', version: '>=2.40', required: false)
26+
gio_windows = dependency('gio-windows-2.0', version: '>=2.40', required: false)
2627
gmodule = dependency('gmodule-2.0', version: '>=2.40')
2728
soup = dependency('libsoup-2.4', version: '>=2.44')
2829

2930
vala_defines = []
3031

32+
if meson.get_compiler('c').has_function('fork')
33+
vala_defines += '--define=HAVE_FORK'
34+
endif
35+
3136
# provide 'OutputStream.write_all_async'
3237
if gio.version().version_compare('>=2.44')
3338
vala_defines += '--define=GIO_2_44'
3439
endif
3540

41+
if gio_unix.found()
42+
vala_defines += '--define=GIO_UNIX'
43+
endif
44+
45+
if gio_windows.found()
46+
vala_defines += '--define=GIO_WINDOWS'
47+
endif
48+
3649
# new 'Soup.Server' API
3750
if soup.version().version_compare('>=2.48')
3851
vala_defines += '--define=SOUP_2_48'

‎src/vsgi/meson.build‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ vsgi_sources = files(
2020
'vsgi-socket-server.vala',
2121
'vsgi-tee-output-stream.vala')
2222
vsgi_lib = library('vsgi-' + api_version, vsgi_sources,
23-
dependencies: [glib, gobject, gio, gio_unix, gmodule, soup],
23+
dependencies: [glib, gobject, gio, gio_unix, gio_windows, gmodule, soup],
2424
vala_args: ['--pkg=posix'] + vala_defines,
2525
link_args: '-Wl,-rpath,$$ORIGIN/servers',
2626
install: true,
@@ -33,9 +33,19 @@ install_headers(meson.current_build_dir() + '/vsgi-@0@.h'.format(api_version), s
3333
install_data(meson.current_build_dir() + '/vsgi-@0@.vapi'.format(api_version), install_dir: 'share/vala/vapi')
3434
install_data('vsgi-@0@.deps'.format(api_version), install_dir: 'share/vala/vapi')
3535

36+
vsgi_requires_private = ['gmodule-2.0']
37+
38+
if gio_unix.found ()
39+
vsgi_requires_private += 'gio-unix-2.0'
40+
endif
41+
42+
if gio_windows.found()
43+
vsgi_requires_private += 'gio-windows-2.0'
44+
endif
45+
3646
pkgconfig = import('pkgconfig')
3747
pkgconfig.generate(requires: 'glib-2.0 gobject-2.0 gio-2.0 libsoup-2.4',
38-
requires_private: 'gio-unix-2.0 gmodule-2.0',
48+
requires_private: vsgi_requires_private,
3949
libraries: vsgi_lib,
4050
version: meson.project_version(),
4151
name: 'VSGI',

‎src/vsgi/servers/meson.build‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ shared_library('vsgi-http', ['vsgi-http.vala'],
55
install_dir: '@0@/vsgi-@1@/servers'.format(get_option('libdir'), api_version))
66

77
shared_library('vsgi-cgi', 'vsgi-cgi.vala',
8-
dependencies: [glib, gobject, gio, gio_unix, soup, vsgi],
8+
dependencies: [glib, gobject, gio, gio_unix, gio_windows, soup, vsgi],
99
vala_args: vala_defines,
1010
install: true,
1111
install_dir: '@0@/vsgi-@1@/servers'.format(get_option('libdir'), api_version))
1212

1313
fcgi = meson.get_compiler('c').find_library('fcgi', required: false)
1414
if fcgi.found()
1515
shared_library('vsgi-fastcgi', 'vsgi-fastcgi.vala',
16-
dependencies: [glib, gobject, gio, gio_unix, soup, vsgi, fcgi],
16+
dependencies: [glib, gobject, gio, gio_unix, gio_windows, soup, vsgi, fcgi],
1717
vala_args: ['--pkg=fcgi', '--vapidir=' + meson.current_source_dir()] + vala_defines,
1818
install: true,
1919
install_dir: '@0@/vsgi-@1@/servers'.format(get_option('libdir'), api_version))

‎src/vsgi/servers/vsgi-cgi.vala‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,18 @@ namespace VSGI.CGI {
7070
}
7171

7272
Idle.add (() => {
73+
#if GIO_UNIX
7374
var connection = new Connection (this,
7475
new UnixInputStream (stdin.fileno (), true),
7576
new UnixOutputStream (stdout.fileno (), true));
77+
#elif GIO_WINDOWS
78+
// TODO: obtain I/O handles
79+
var connection = new Connection (this,
80+
new Win32InputStream (null, true),
81+
new Win32OutputStream (null, true));
82+
#else
83+
// TODO: find an alternative
84+
#endif
7685

7786
var req = new Request (connection, Environ.@get ());
7887
var res = new Response (req);

‎src/vsgi/servers/vsgi-fastcgi.vala‎

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,25 @@ namespace VSGI.FastCGI {
5555
return "Unknown error code '%d'".printf (error);
5656
}
5757

58-
private class StreamInputStream : UnixInputStream {
58+
private class StreamInputStream :
59+
#if GIO_UNIX
60+
UnixInputStream
61+
#else
62+
InputStream
63+
#endif
64+
{
5965

6066
public unowned global::FastCGI.Stream @in { construct; get; }
6167

68+
#if GIO_UNIX
6269
public StreamInputStream (int fd, global::FastCGI.Stream @in) {
6370
Object (fd: fd, close_fd: false, @in: @in);
6471
}
72+
#else
73+
public StreamInputStream (global::FastCGI.Stream @in) {
74+
Object (@in: @in);
75+
}
76+
#endif
6577

6678
public override ssize_t read (uint8[] buffer, Cancellable? cancellable = null) throws IOError {
6779
var read = this.in.read (buffer);
@@ -84,15 +96,27 @@ namespace VSGI.FastCGI {
8496
}
8597
}
8698

87-
private class StreamOutputStream : UnixOutputStream {
99+
private class StreamOutputStream :
100+
#if GIO_UNIX
101+
UnixOutputStream
102+
#else
103+
OutputStream
104+
#endif
105+
{
88106

89107
public unowned global::FastCGI.Stream @out { construct; get; }
90108

91109
public unowned global::FastCGI.Stream err { construct; get; }
92110

111+
#if GIO_UNIX
93112
public StreamOutputStream (int fd, global::FastCGI.Stream @out, global::FastCGI.Stream err) {
94113
Object (fd: fd, close_fd: false, @out: @out, err: err);
95114
}
115+
#else
116+
public StreamOutputStream (global::FastCGI.Stream @out, global::FastCGI.Stream err) {
117+
Object (@out: @out, err: err);
118+
}
119+
#endif
96120

97121
public override ssize_t write (uint8[] buffer, Cancellable? cancellable = null) throws IOError {
98122
var written = this.out.put_str (buffer);
@@ -191,7 +215,10 @@ namespace VSGI.FastCGI {
191215
if (address == null) {
192216
fd = global::FastCGI.LISTENSOCK_FILENO;
193217
_uris.append (new Soup.URI ("fcgi+fd://%d/".printf (fd)));
194-
} else if (address is UnixSocketAddress) {
218+
}
219+
220+
#if GIO_UNIX
221+
else if (address is UnixSocketAddress) {
195222
var socket_address = address as UnixSocketAddress;
196223

197224
fd = global::FastCGI.open_socket (socket_address.path, backlog);
@@ -201,7 +228,10 @@ namespace VSGI.FastCGI {
201228
}
202229

203230
_uris.append (new Soup.URI ("fcgi+unix://%s/".printf (socket_address.path)));
204-
} else if (address is InetSocketAddress) {
231+
}
232+
#endif
233+
234+
else if (address is InetSocketAddress) {
205235
var inet_address = address as InetSocketAddress;
206236

207237
if (inet_address.get_family () == SocketFamily.IPV6) {
@@ -311,8 +341,13 @@ namespace VSGI.FastCGI {
311341

312342
yield;
313343

344+
#if GIO_UNIX
314345
this._input_stream = new StreamInputStream (fd, request.in);
315346
this._output_stream = new StreamOutputStream (fd, request.out, request.err);
347+
#else
348+
this._input_stream = new StreamInputStream (request.in);
349+
this._output_stream = new StreamOutputStream (request.out, request.err);
350+
#endif
316351

317352
return true;
318353
}

‎src/vsgi/vsgi-application.vala‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,11 @@ public class VSGI.Application : GLib.Application {
147147
// socket path
148148
if (sockets != null) {
149149
foreach (var socket in sockets.get_bytestring_array ()) {
150+
#if GIO_UNIX
150151
server.listen (new UnixSocketAddress (socket));
152+
#elif GIO_WINDOWS
153+
// TODO: find an alternative
154+
#endif
151155
}
152156
}
153157

@@ -205,12 +209,16 @@ public class VSGI.Application : GLib.Application {
205209
// keep the process (and workers) alive
206210
hold ();
207211

212+
#if GIO_UNIX
208213
// release on 'SIGTERM'
209214
Unix.signal_add (ProcessSignal.TERM, () => {
210215
release ();
211216
server.stop ();
212217
return false;
213218
}, Priority.LOW);
219+
#elif GIO_WINDOWS
220+
// TODO: find an alternative
221+
#endif
214222

215223
return 0;
216224
}

‎src/vsgi/vsgi-server.vala‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,15 @@ namespace VSGI {
140140
*/
141141
[Version (since = "0.3")]
142142
public virtual Pid fork () throws Error {
143+
#if HAVE_FORK
143144
var pid = Posix.fork ();
144145
if (pid == -1) {
145146
throw new SpawnError.FORK (strerror (errno));
146147
}
147148
return pid;
149+
#else
150+
return 0;
151+
#endif
148152
}
149153

150154
/**

‎src/vsgi/vsgi-socket-server.vala‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,14 @@ public abstract class VSGI.SocketServer : Server {
7474
effective_inet_address.get_address ().to_string (),
7575
effective_inet_address.get_port ())));
7676
}
77-
} else if (effective_address is UnixSocketAddress) {
77+
}
78+
79+
#if GIO_UNIX
80+
else if (effective_address is UnixSocketAddress) {
7881
var effective_unix_address = effective_address as UnixSocketAddress;
7982
_uris.append (new Soup.URI ("%s+unix://%s/".printf (scheme, effective_unix_address.get_path ())));
8083
}
84+
#endif
8185
}
8286
}
8387

0 commit comments

Comments
 (0)