Debug message fix
[sxemacs] / lisp / ffi / ffi-libc.el
1 ;;; ffi-libc.el --- FFI bindings for libc.
2
3 ;; Copyright (C) 2005-2008 by Zajcev Evgeny.
4
5 ;; Author: Zajcev Evgeny <zevlg@yandex.ru>
6 ;; Created: 2005
7 ;; Keywords: ffi
8
9 ;; This file is part of SXEmacs.
10
11 ;; SXEmacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
15
16 ;; SXEmacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
24 ;;; Synched up with: Not in FSF
25
26 ;;; Commentary:
27
28 ;;
29
30 ;;; Code:
31 (require 'ffi)
32
33 (define-ffi-type c:FILE pointer)
34
35 (define-ffi-enum c:WHENCE
36   (seek-set 0)
37   (seek-cur 1)
38   (seek-end 2))
39
40 ;;; FILE operations
41 (defconst c:errno (ffi-bind 'int "errno")
42   "Current errno value.
43 Get lisp value for it with `(ffi-get c:errno)'.")
44
45 (cffi:defcfun ("fopen" c:fopen-1) c:FILE
46   "Elisp binding to fopen(3).
47 Consider using `c:fopen' instead."
48   (filename c-string) (mode c-string))
49
50 (cffi:defcfun ("fdopen" c:fdopen) c:FILE
51   "Create stream from descriptor FD using MODE."
52   (fd int) (mode c-string))
53
54 (cffi:defcfun ("clearerr" c:clearerr) void
55   "Clear the end-of-file and error indicators for the STREAM."
56   (stream c:FILE))
57
58 (cffi:defcfun ("ferror" c:ferror-p) boolean
59   "Return non-nil if STREAM has errors.
60 Tests the error indicator for the stream pointed to by stream,
61 returning non-zero if it is set.  The error indicator can only be
62 reset by the `c:clearerr' function."
63   (stream c:FILE))
64
65 (cffi:defcfun ("feof" c:feof-p) boolean
66   "Return non-nil if STREAM has end-of-file indicator set.
67 The end-of-file indicator can only be cleared by the function
68 `c:clearerr'."
69   (stream c:FILE))
70
71 (cffi:defcfun ("fread" c:fread-1) unsigned-int
72   "Elisp binding to fread(3).
73 Consider using `c:fread' in your programs."
74   (ptr pointer) (size unsigned-int) (nmemb unsigned-int)
75   (stream c:FILE))
76
77 (defun c:fread (size stream)
78   "Read at most SIZE bytes from STREAM.
79 STREAM is object returned by call to `c:fopen' function.
80 Empty stream is returned if end-of-file indicated.
81 Error raises if some error occurs."
82   (let* ((fod (make-ffi-object (cons 'c-data size)))
83          (rsz (c:fread-1 fod 1 size stream)))
84     (if (zerop rsz)
85         (cond ((c:feof-p stream) "")
86               ((c:ferror-p stream)
87                (error 'io-error "c:fread error"
88                       (c:strerror (ffi-get c:errno))))
89               (t (error 'io-error "c:fread unknown error")))
90       (ffi-get fod :type (cons 'c-data rsz)))))
91
92 (cffi:defcfun ("fwrite" c:fwrite-1) unsigned-int
93   "Elisp binding to fwrite(3).
94 Consider using `c:fwrite' in your programs."
95   (ptr pointer) (size unsigned-int) (nmemb unsigned-int)
96   (stream c:FILE))
97
98 (defun c:fwrite (data stream)
99   "Write DATA to STREAM.
100 DATA must be an Emacs lisp string.
101 STREAM is object returned by call to `c:fopen' function."
102   (let ((fod (ffi-create-fo (cons 'c-data (length data)) data)))
103     (c:fwrite-1 fod 1 (length data) stream)))
104
105 (cffi:defcfun ("fseek" c:fseek) int
106   "Set the file position indicator for the STREAM.
107 The new position, measured in bytes, is obtained by adding OFFSET
108 bytes to the position specified by WHENCE.
109 WHENCE is one of:
110  'seek-set   - relative to the start of file.
111  'seek-cur   - relative to the current position.
112  'seek-end   - relative to the end of file."
113   (stream c:FILE) (offset long) (whence c:WHENCE))
114
115 (cffi:defcfun ("fclose" c:fclose) int
116   "Close STREAM.
117 Elisp binding to close(3)."
118   (stream c:FILE))
119
120 (cffi:defcfun ("strerror" c:strerror) c-string
121   "Emacs lisp binding to strerror(3)"
122   (error int))
123
124 (defun c:fopen (file mode)
125   "Open the FILE and associates a stream with it.
126
127 The argument MODE is a string beginning with one of the following
128 sequences (Additional characters may follow these sequences.):
129
130 ``r''   Open text file for reading.  The stream is positioned at the
131         beginning of the file.
132
133 ``r+''  Open for reading and writing.  The stream is positioned at the
134         beginning of the file.
135
136 ``w''   Truncate file to zero length or create text file for writing.
137         The stream is positioned at the beginning of the file.
138
139 ``w+''  Open for reading and writing.  The file is created if it does not
140         exist, otherwise it is truncated.  The stream is positioned at
141         the beginning of the file.
142
143 ``a''   Open for writing.  The file is created if it does not exist.  The
144         stream is positioned at the end of the file.  Subsequent writes
145         to the file will always end up at the then current end of file,
146         irrespective of any intervening fseek(3) or similar.
147
148 ``a+''  Open for reading and writing.  The file is created if it does not
149         exist.  The stream is positioned at the end of the file.  Subse-
150         quent writes to the file will always end up at the then current
151         end of file, irrespective of any intervening fseek(3) or similar.
152
153 The mode string can also include the letter ``b'' either as a third char-
154 acter or as a character between the characters in any of the two-charac-
155 ter strings described above.  This is strictly for compatibility with
156 ISO/IEC 9899:1990 (``ISO C90'') and has no effect; the ``b'' is ignored."
157   (let ((rv (c:fopen-1 file mode)))
158     (when (ffi-null-p rv)
159       (error 'file-error "c:fopen open error"
160              file (c:strerror (ffi-get c:errno))))
161     rv))
162
163 (cffi:defcfun ("dup" c:dup) int
164   "Duplicate existing file descriptor FD.
165 Return newly created file descriptor.
166 On error negative value is returned."
167   (fd int))
168
169 ;;; Memory
170 (cffi:defcfun ("memcpy" c:memcpy) pointer
171   "Elisp binding for memcpy(3)."
172   (dst pointer) (src pointer) (len unsigned-int))
173
174 (cffi:defcfun ("memset" c:memset) pointer
175   "Write LEN bytes of value C to the string B."
176   (b pointer) (c int) (len unsigned-int))
177
178 ;;; SHM
179 (defconst c:IPC-PRIVATE 0)
180 (defconst c:IPC-R #o000400)
181 (defconst c:IPC-W #o000200)
182 (defconst c:IPC-CREAT #o001000)
183 (defconst c:IPC-0777-MASK #o0777)
184
185 (cffi:defcfun ("shmget" c:shmget) int
186   "Return id of newly created or previously existing shared memory segment.
187 KEY names an IPC object.  There are three ways to specify a KEY:
188
189  o  `c:IPC-PRIVATE' may be specified, in which case a new IPC object
190     will be created.
191
192  o  An integer constant may be specified.  If no IPC object
193     corresponding to key is specified and the `c:IPC-CREAT' bit is set in
194     FLAG, a new one will be created.
195
196  o  The `c:ftok' may be used to generate a key from a pathname.
197
198 SIZE indicates the desired size of the new segment in bytes."
199   (key long) (size unsigned-int) (flag int))
200
201 (cffi:defcfun ("shmat" c:shmat) pointer
202   "Attaches the shared memory segment identified by SHMID to proccess.
203 The address where the segment is attached is determined as follows:
204
205  o  If ADDR is null-pointer, the segment is attached at an address
206     selected by the kernel.
207
208  o  If ADDR is not null-pointer and `c:SHM-RND' is not specified in
209     FLAG, the segment is attached the specified address.
210
211  o  If ADDR is specified and `c:SHM-RND' is specified, ADDR is rounded
212     down to the nearest multiple of SHMLBA."
213   (shmid int) (addr pointer) (flag int))
214
215 (cffi:defcfun ("shmdt" c:shmdt) int
216   "Detaches the shared memory segment at the ADDR from process."
217   (addr pointer))
218
219 (provide 'ffi-libc)
220
221 ;;; ffi-libc.el ends here