source: branches/win64/lisp-kernel/windows-calls.c @ 9334

Last change on this file since 9334 was 9334, checked in by andreas, 11 years ago

Implementation of pipe() for Windows.

File size: 4.3 KB
Line 
1/*
2   Copyright (C) 2008, Clozure Associates and contributors,
3   This file is part of Clozure CL. 
4
5   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public
6   License , known as the LLGPL and distributed with Clozure CL as the
7   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
8   which is distributed with Clozure CL as the file "LGPL".  Where these
9   conflict, the preamble takes precedence. 
10
11   Clozure CL is referenced in the preamble as the "LIBRARY."
12
13   The LLGPL is also available online at
14   http://opensource.franz.com/preamble.html
15*/
16
17/*
18   These aren't really system calls; they're just C runtime functions
19   that (a) are built in to the lisp, so they can be called early
20   in the cold load, before the FFI is initialized and (b) return negated
21   error code on failure, so that it's not necessary to separately
22   fetch errno.
23
24   It's reasonable to consider replacing these things with wrappers
25   around native functionality (ReadFile, etc.) someday.
26
27   The order of the entries in windows_syscall_table[] should match
28   the order of syscall indices defined in
29   "ccl:library;x86-win64-syscalls.lisp".
30
31   One last time: these aren't really system calls.
32*/
33
34#include <io.h>
35#include <unistd.h>
36#include <sys/fcntl.h>
37#include <errno.h>
38#include <sys/stat.h>
39#include <windows.h>
40#include <psapi.h>
41#include <dirent.h>
42
43#define WSYSCALL_RETURN(form) \
44  do { \
45    int __result = form; \
46\
47    if (__result < 0){ \
48      return -errno; \
49    } \
50    return __result; \
51  } while (0)
52
53
54#if 1
55__int64
56windows_open(wchar_t *path, int flag, int mode)
57{
58  WSYSCALL_RETURN(_wopen(path, flag, mode));
59}
60#else
61__int64
62windows_open(char *path, int flag, int mode)
63{
64  WSYSCALL_RETURN(_open(path, flag, mode));
65}
66#endif
67__int64
68windows_close(int fd)
69{
70  WSYSCALL_RETURN(_close(fd));
71}
72
73__int64
74windows_read(int fd, void *buf, unsigned int count)
75{
76  WSYSCALL_RETURN(_read(fd, buf, count));
77}
78
79__int64
80windows_write(int fd, void *buf, unsigned int count)
81{
82  WSYSCALL_RETURN( _write(fd, buf, count));
83}
84
85__int64
86windows_fchmod(int fd, int mode)
87{
88  return -ENOSYS;
89}
90
91__int64
92windows_lseek(int fd, _off64_t offset, int whence)
93{
94  WSYSCALL_RETURN(lseek64(fd, offset, whence));
95}
96
97__int64
98windows_stat(wchar_t *path, struct _stat64 *buf)
99{
100  WSYSCALL_RETURN(_wstat64(path,buf));
101}
102
103__int64
104windows_fstat(int fd, struct _stat64 *buf)
105{
106  WSYSCALL_RETURN(_fstat64(fd,buf));
107}
108
109
110__int64
111windows_ftruncate(int fd, _off64_t new_size)
112{
113  /* Note that _ftruncate only allows 32-bit length */
114  WSYSCALL_RETURN(ftruncate(fd,(off_t)new_size));
115}
116
117_WDIR *
118windows_opendir(wchar_t *path)
119{
120  return _wopendir(path);
121}
122
123struct _wdirent *
124windows_readdir(_WDIR *dir)
125{
126  return _wreaddir(dir);
127}
128
129__int64
130windows_closedir(_WDIR *dir)
131{
132  WSYSCALL_RETURN(_wclosedir(dir));
133}
134
135__int64
136windows_pipe(int fd[2])
137{
138  HANDLE input, output;
139  SECURITY_ATTRIBUTES sa;
140
141  sa.nLength= sizeof(SECURITY_ATTRIBUTES);
142  sa.lpSecurityDescriptor = NULL;
143  sa.bInheritHandle = TRUE;
144
145  if (!CreatePipe(&input, &output, &sa, 0))
146    {
147      wperror("CreatePipe");
148      return -1;
149    }
150  fd[0] = _open_osfhandle((intptr_t)input, 0);
151  fd[1] = _open_osfhandle((intptr_t)output, 0);
152  return 0;
153}
154
155void *
156windows_syscall_table[] = {
157  windows_open,
158  windows_close,
159  windows_read,
160  windows_write,
161  windows_fchmod,
162  windows_lseek,
163  windows_stat,
164  windows_fstat,
165  windows_ftruncate,
166  windows_opendir,
167  windows_readdir,
168  windows_closedir,
169  windows_pipe
170};
171
172HMODULE *modules = NULL;
173DWORD cbmodules = 0;
174
175void *
176windows_find_symbol(void *handle, char *name)
177{
178  if (handle == ((void *)-2L)) {
179    handle = NULL;
180  }
181  if (handle != NULL) {
182    return GetProcAddress(handle, name);
183  } else {
184    DWORD cbneeded,  have, i;
185
186    if (cbmodules == 0) {
187      cbmodules = 16 * sizeof(HANDLE);
188      modules = LocalAlloc(LPTR, cbmodules);
189    }
190   
191    while (1) {
192      EnumProcessModules(GetCurrentProcess(),modules,cbmodules,&cbneeded);
193      if (cbmodules >= cbneeded) {
194        break;
195      }
196      cbmodules = cbneeded;
197      modules = LocalReAlloc(modules,cbmodules,0);
198    }
199    have = cbneeded/sizeof(HANDLE);
200
201    for (i = 0; i < have; i++) {
202      void *addr = GetProcAddress(modules[i],name);
203
204      if (addr) {
205        return addr;
206      }
207    }
208    return NULL;
209  }
210}
211
212void
213init_winsock()
214{
215  WSADATA data;
216
217  WSAStartup((2<<8)|2,&data);
218}
Note: See TracBrowser for help on using the repository browser.