* strports.c (st_end_input): Inserted parenthesis to get operator
[bpt/guile.git] / libguile / filesys.c
1 /* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
41
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
44
45 \f
46 #include <stdio.h>
47 #include "_scm.h"
48 #include "genio.h"
49 #include "smob.h"
50 #include "feature.h"
51 #include "fports.h"
52 #include "iselect.h"
53
54 #include "scm_validate.h"
55 #include "filesys.h"
56
57 \f
58 #ifdef HAVE_IO_H
59 #include <io.h>
60 #endif
61
62 #ifdef TIME_WITH_SYS_TIME
63 # include <sys/time.h>
64 # include <time.h>
65 #else
66 # if HAVE_SYS_TIME_H
67 # include <sys/time.h>
68 # else
69 # include <time.h>
70 # endif
71 #endif
72
73 #ifdef HAVE_UNISTD_H
74 #include <unistd.h>
75 #endif
76
77 #ifdef LIBC_H_WITH_UNISTD_H
78 #include <libc.h>
79 #endif
80
81 #ifdef HAVE_SYS_SELECT_H
82 #include <sys/select.h>
83 #endif
84
85 #ifdef HAVE_STRING_H
86 #include <string.h>
87 #endif
88
89 #include <sys/types.h>
90 #include <sys/stat.h>
91 #include <fcntl.h>
92
93 #include <pwd.h>
94
95
96 #if HAVE_DIRENT_H
97 # include <dirent.h>
98 # define NAMLEN(dirent) strlen((dirent)->d_name)
99 #else
100 # define dirent direct
101 # define NAMLEN(dirent) (dirent)->d_namlen
102 # if HAVE_SYS_NDIR_H
103 # include <sys/ndir.h>
104 # endif
105 # if HAVE_SYS_DIR_H
106 # include <sys/dir.h>
107 # endif
108 # if HAVE_NDIR_H
109 # include <ndir.h>
110 # endif
111 #endif
112
113 /* Ultrix has S_IFSOCK, but no S_ISSOCK. Ipe! */
114 #if defined (S_IFSOCK) && ! defined (S_ISSOCK)
115 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
116 #endif
117 \f
118
119
120 \f
121
122 /* {Permissions}
123 */
124
125 SCM_DEFINE (scm_chown, "chown", 3, 0, 0,
126 (SCM object, SCM owner, SCM group),
127 "Change the ownership and group of the file referred to by @var{obj} to\n"
128 "the integer userid values @var{owner} and @var{group}. @var{obj} can be\n"
129 "a string containing a file name or a port or integer file descriptor\n"
130 "which is open on the file (in which case fchown is used as the underlying\n"
131 "system call). The return value\n"
132 "is unspecified.\n\n"
133 "If @var{obj} is a symbolic link, either the\n"
134 "ownership of the link or the ownership of the referenced file will be\n"
135 "changed depending on the operating system (lchown is\n"
136 "unsupported at present). If @var{owner} or @var{group} is specified\n"
137 "as @code{-1}, then that ID is not changed.")
138 #define FUNC_NAME s_scm_chown
139 {
140 int rv;
141 int fdes;
142
143 object = SCM_COERCE_OUTPORT (object);
144
145 SCM_VALIDATE_INUM (2,owner);
146 SCM_VALIDATE_INUM (3,group);
147 if (SCM_INUMP (object) || (SCM_OPFPORTP (object)))
148 {
149 if (SCM_INUMP (object))
150 fdes = SCM_INUM (object);
151 else
152 fdes = SCM_FPORT_FDES (object);
153 SCM_SYSCALL (rv = fchown (fdes, SCM_INUM (owner), SCM_INUM (group)));
154 }
155 else
156 {
157 SCM_VALIDATE_ROSTRING(1,object);
158 SCM_COERCE_SUBSTR (object);
159 SCM_SYSCALL (rv = chown (SCM_ROCHARS (object),
160 SCM_INUM (owner), SCM_INUM (group)));
161 }
162 if (rv == -1)
163 SCM_SYSERROR;
164 return SCM_UNSPECIFIED;
165 }
166 #undef FUNC_NAME
167
168
169 SCM_DEFINE (scm_chmod, "chmod", 2, 0, 0,
170 (SCM object, SCM mode),
171 "Changes the permissions of the file referred to by @var{obj}.\n"
172 "@var{obj} can be a string containing a file name or a port or integer file\n"
173 "descriptor which is open on a file (in which case @code{fchmod} is used\n"
174 "as the underlying system call).\n"
175 "@var{mode} specifies\n"
176 "the new permissions as a decimal number, e.g., @code{(chmod \"foo\" #o755)}.\n"
177 "The return value is unspecified.")
178 #define FUNC_NAME s_scm_chmod
179 {
180 int rv;
181 int fdes;
182
183 object = SCM_COERCE_OUTPORT (object);
184
185 SCM_VALIDATE_INUM (2,mode);
186 if (SCM_INUMP (object) || SCM_OPFPORTP (object))
187 {
188 if (SCM_INUMP (object))
189 fdes = SCM_INUM (object);
190 else
191 fdes = SCM_FPORT_FDES (object);
192 SCM_SYSCALL (rv = fchmod (fdes, SCM_INUM (mode)));
193 }
194 else
195 {
196 SCM_VALIDATE_ROSTRING (1,object);
197 SCM_COERCE_SUBSTR (object);
198 SCM_SYSCALL (rv = chmod (SCM_ROCHARS (object), SCM_INUM (mode)));
199 }
200 if (rv == -1)
201 SCM_SYSERROR;
202 return SCM_UNSPECIFIED;
203 }
204 #undef FUNC_NAME
205
206 SCM_DEFINE (scm_umask, "umask", 0, 1, 0,
207 (SCM mode),
208 "If @var{mode} is omitted, retuns a decimal number representing the current\n"
209 "file creation mask. Otherwise the file creation mask is set to\n"
210 "@var{mode} and the previous value is returned.\n\n"
211 "E.g., @code{(umask #o022)} sets the mask to octal 22, decimal 18.")
212 #define FUNC_NAME s_scm_umask
213 {
214 mode_t mask;
215 if (SCM_UNBNDP (mode))
216 {
217 mask = umask (0);
218 umask (mask);
219 }
220 else
221 {
222 SCM_VALIDATE_INUM (1,mode);
223 mask = umask (SCM_INUM (mode));
224 }
225 return SCM_MAKINUM (mask);
226 }
227 #undef FUNC_NAME
228
229 \f
230
231 SCM_DEFINE (scm_open_fdes, "open-fdes", 2, 1, 0,
232 (SCM path, SCM flags, SCM mode),
233 "Similar to @code{open} but returns a file descriptor instead of a\n"
234 "port.")
235 #define FUNC_NAME s_scm_open_fdes
236 {
237 int fd;
238 int iflags;
239 int imode;
240
241 SCM_VALIDATE_ROSTRING (1,path);
242 SCM_COERCE_SUBSTR (path);
243 iflags = SCM_NUM2LONG(2,flags);
244 imode = SCM_NUM2LONG_DEF(3,mode,0666);
245 SCM_SYSCALL (fd = open (SCM_ROCHARS (path), iflags, imode));
246 if (fd == -1)
247 SCM_SYSERROR;
248 return SCM_MAKINUM (fd);
249 }
250 #undef FUNC_NAME
251
252 SCM_DEFINE (scm_open, "open", 2, 1, 0,
253 (SCM path, SCM flags, SCM mode),
254 "Open the file named by @var{path} for reading and/or writing.\n"
255 "@var{flags} is an integer specifying how the file should be opened.\n"
256 "@var{mode} is an integer specifying the permission bits of the file, if\n"
257 "it needs to be created, before the umask is applied. The default is 666\n"
258 "(Unix itself has no default).\n\n"
259 "@var{flags} can be constructed by combining variables using @code{logior}.\n"
260 "Basic flags are:\n\n"
261 "@defvar O_RDONLY\n"
262 "Open the file read-only.\n"
263 "@end defvar\n"
264 "@defvar O_WRONLY\n"
265 "Open the file write-only. \n"
266 "@end defvar\n"
267 "@defvar O_RDWR\n"
268 "Open the file read/write.\n"
269 "@end defvar\n"
270 "@defvar O_APPEND\n"
271 "Append to the file instead of truncating.\n"
272 "@end defvar\n"
273 "@defvar O_CREAT\n"
274 "Create the file if it does not already exist.\n"
275 "@end defvar\n\n"
276 "See the Unix documentation of the @code{open} system call\n"
277 "for additional flags.")
278 #define FUNC_NAME s_scm_open
279 {
280 SCM newpt;
281 char *port_mode;
282 int fd;
283 int iflags;
284
285 fd = SCM_INUM (scm_open_fdes (path, flags, mode));
286 iflags = SCM_NUM2LONG (2,flags);
287 if (iflags & O_RDWR)
288 {
289 if (iflags & O_APPEND)
290 port_mode = "a+";
291 else if (iflags & O_CREAT)
292 port_mode = "w+";
293 else
294 port_mode = "r+";
295 }
296 else {
297 if (iflags & O_APPEND)
298 port_mode = "a";
299 else if (iflags & O_WRONLY)
300 port_mode = "w";
301 else
302 port_mode = "r";
303 }
304 newpt = scm_fdes_to_port (fd, port_mode, path);
305 return newpt;
306 }
307 #undef FUNC_NAME
308
309 SCM_DEFINE (scm_close, "close", 1, 0, 0,
310 (SCM fd_or_port),
311 "Similar to close-port (@pxref{Generic Port Operations, close-port}),\n"
312 "but also works on file descriptors. A side\n"
313 "effect of closing a file descriptor is that any ports using that file\n"
314 "descriptor are moved to a different file descriptor and have\n"
315 "their revealed counts set to zero.")
316 #define FUNC_NAME s_scm_close
317 {
318 int rv;
319 int fd;
320
321 fd_or_port = SCM_COERCE_OUTPORT (fd_or_port);
322
323 if (SCM_PORTP (fd_or_port))
324 return scm_close_port (fd_or_port);
325 SCM_VALIDATE_INUM (1,fd_or_port);
326 fd = SCM_INUM (fd_or_port);
327 scm_evict_ports (fd); /* see scsh manual. */
328 SCM_SYSCALL (rv = close (fd));
329 /* following scsh, closing an already closed file descriptor is
330 not an error. */
331 if (rv < 0 && errno != EBADF)
332 SCM_SYSERROR;
333 return SCM_NEGATE_BOOL(rv < 0);
334 }
335 #undef FUNC_NAME
336
337 \f
338 /* {Files}
339 */
340
341 SCM_SYMBOL (scm_sym_regular, "regular");
342 SCM_SYMBOL (scm_sym_directory, "directory");
343 #ifdef HAVE_S_ISLNK
344 SCM_SYMBOL (scm_sym_symlink, "symlink");
345 #endif
346 SCM_SYMBOL (scm_sym_block_special, "block-special");
347 SCM_SYMBOL (scm_sym_char_special, "char-special");
348 SCM_SYMBOL (scm_sym_fifo, "fifo");
349 SCM_SYMBOL (scm_sym_sock, "socket");
350 SCM_SYMBOL (scm_sym_unknown, "unknown");
351
352 static SCM
353 scm_stat2scm (struct stat *stat_temp)
354 {
355 SCM ans = scm_make_vector (SCM_MAKINUM (15), SCM_UNSPECIFIED);
356 SCM *ve = SCM_VELTS (ans);
357
358 ve[0] = scm_ulong2num ((unsigned long) stat_temp->st_dev);
359 ve[1] = scm_ulong2num ((unsigned long) stat_temp->st_ino);
360 ve[2] = scm_ulong2num ((unsigned long) stat_temp->st_mode);
361 ve[3] = scm_ulong2num ((unsigned long) stat_temp->st_nlink);
362 ve[4] = scm_ulong2num ((unsigned long) stat_temp->st_uid);
363 ve[5] = scm_ulong2num ((unsigned long) stat_temp->st_gid);
364 #ifdef HAVE_ST_RDEV
365 ve[6] = scm_ulong2num ((unsigned long) stat_temp->st_rdev);
366 #else
367 ve[6] = SCM_BOOL_F;
368 #endif
369 ve[7] = scm_ulong2num ((unsigned long) stat_temp->st_size);
370 ve[8] = scm_ulong2num ((unsigned long) stat_temp->st_atime);
371 ve[9] = scm_ulong2num ((unsigned long) stat_temp->st_mtime);
372 ve[10] = scm_ulong2num ((unsigned long) stat_temp->st_ctime);
373 #ifdef HAVE_ST_BLKSIZE
374 ve[11] = scm_ulong2num ((unsigned long) stat_temp->st_blksize);
375 #else
376 ve[11] = scm_ulong2num (4096L);
377 #endif
378 #ifdef HAVE_ST_BLOCKS
379 ve[12] = scm_ulong2num ((unsigned long) stat_temp->st_blocks);
380 #else
381 ve[12] = SCM_BOOL_F;
382 #endif
383 {
384 int mode = stat_temp->st_mode;
385
386 if (S_ISREG (mode))
387 ve[13] = scm_sym_regular;
388 else if (S_ISDIR (mode))
389 ve[13] = scm_sym_directory;
390 #ifdef HAVE_S_ISLNK
391 else if (S_ISLNK (mode))
392 ve[13] = scm_sym_symlink;
393 #endif
394 else if (S_ISBLK (mode))
395 ve[13] = scm_sym_block_special;
396 else if (S_ISCHR (mode))
397 ve[13] = scm_sym_char_special;
398 else if (S_ISFIFO (mode))
399 ve[13] = scm_sym_fifo;
400 else if (S_ISSOCK (mode))
401 ve[13] = scm_sym_sock;
402 else
403 ve[13] = scm_sym_unknown;
404
405 ve[14] = SCM_MAKINUM ((~S_IFMT) & mode);
406
407 /* the layout of the bits in ve[14] is intended to be portable.
408 If there are systems that don't follow the usual convention,
409 the following could be used:
410
411 tmp = 0;
412 if (S_ISUID & mode) tmp += 1;
413 tmp <<= 1;
414 if (S_IRGRP & mode) tmp += 1;
415 tmp <<= 1;
416 if (S_ISVTX & mode) tmp += 1;
417 tmp <<= 1;
418 if (S_IRUSR & mode) tmp += 1;
419 tmp <<= 1;
420 if (S_IWUSR & mode) tmp += 1;
421 tmp <<= 1;
422 if (S_IXUSR & mode) tmp += 1;
423 tmp <<= 1;
424 if (S_IWGRP & mode) tmp += 1;
425 tmp <<= 1;
426 if (S_IXGRP & mode) tmp += 1;
427 tmp <<= 1;
428 if (S_IROTH & mode) tmp += 1;
429 tmp <<= 1;
430 if (S_IWOTH & mode) tmp += 1;
431 tmp <<= 1;
432 if (S_IXOTH & mode) tmp += 1;
433
434 ve[14] = SCM_MAKINUM (tmp);
435
436 */
437 }
438
439 return ans;
440 }
441
442 SCM_DEFINE (scm_stat, "stat", 1, 0, 0,
443 (SCM object),
444 "Returns an object containing various information\n"
445 "about the file determined by @var{obj}.\n"
446 "@var{obj} can be a string containing a file name or a port or integer file\n"
447 "descriptor which is open on a file (in which case @code{fstat} is used\n"
448 "as the underlying system call).\n\n"
449 "The object returned by @code{stat} can be passed as a single parameter\n"
450 "to the following procedures, all of which return integers:\n\n"
451 "@table @code\n"
452 "@item stat:dev\n"
453 "The device containing the file.\n"
454 "@item stat:ino\n"
455 "The file serial number, which distinguishes this file from all other\n"
456 "files on the same device.\n"
457 "@item stat:mode\n"
458 "The mode of the file. This includes file type information\n"
459 "and the file permission bits. See @code{stat:type} and @code{stat:perms}\n"
460 "below.\n"
461 "@item stat:nlink\n"
462 "The number of hard links to the file.\n"
463 "@item stat:uid\n"
464 "The user ID of the file's owner.\n"
465 "@item stat:gid\n"
466 "The group ID of the file.\n"
467 "@item stat:rdev\n"
468 "Device ID; this entry is defined only for character or block\n"
469 "special files.\n"
470 "@item stat:size\n"
471 "The size of a regular file in bytes.\n"
472 "@item stat:atime\n"
473 "The last access time for the file.\n"
474 "@item stat:mtime\n"
475 "The last modification time for the file.\n"
476 "@item stat:ctime\n"
477 "The last modification time for the attributes of the file.\n"
478 "@item stat:blksize\n"
479 "The optimal block size for reading or writing the file, in bytes.\n"
480 "@item stat:blocks\n"
481 "The amount of disk space that the file occupies measured in units of\n"
482 "512 byte blocks.\n"
483 "@end table\n\n"
484 "In addition, the following procedures return the information\n"
485 "from stat:mode in a more convenient form:\n\n"
486 "@table @code\n"
487 "@item stat:type\n"
488 "A symbol representing the type of file. Possible values are\n"
489 "regular, directory, symlink, block-special, char-special,\n"
490 "fifo, socket and unknown\n"
491 "@item stat:perms\n"
492 "An integer representing the access permission bits.\n"
493 "@end table")
494 #define FUNC_NAME s_scm_stat
495 {
496 int rv;
497 int fdes;
498 struct stat stat_temp;
499
500 if (SCM_INUMP (object))
501 SCM_SYSCALL (rv = fstat (SCM_INUM (object), &stat_temp));
502 else
503 {
504 SCM_VALIDATE_NIM (1,object);
505 if (SCM_ROSTRINGP (object))
506 {
507 SCM_COERCE_SUBSTR (object);
508 SCM_SYSCALL (rv = stat (SCM_ROCHARS (object), &stat_temp));
509 }
510 else
511 {
512 object = SCM_COERCE_OUTPORT (object);
513 SCM_VALIDATE_OPFPORT(1,object);
514 fdes = SCM_FPORT_FDES (object);
515 SCM_SYSCALL (rv = fstat (fdes, &stat_temp));
516 }
517 }
518 if (rv == -1)
519 {
520 int en = errno;
521
522 SCM_SYSERROR_MSG ("~A: ~S",
523 scm_listify (scm_makfrom0str (strerror (errno)),
524 object,
525 SCM_UNDEFINED), en);
526 }
527 return scm_stat2scm (&stat_temp);
528 }
529 #undef FUNC_NAME
530
531 \f
532 /* {Modifying Directories}
533 */
534
535 SCM_DEFINE (scm_link, "link", 2, 0, 0,
536 (SCM oldpath, SCM newpath),
537 "Creates a new name @var{path-to} in the file system for the file\n"
538 "named by @var{path-from}. If @var{path-from} is a symbolic link, the\n"
539 "link may or may not be followed depending on the system.")
540 #define FUNC_NAME s_scm_link
541 {
542 int val;
543
544 SCM_VALIDATE_ROSTRING (1,oldpath);
545 if (SCM_SUBSTRP (oldpath))
546 oldpath = scm_makfromstr (SCM_ROCHARS (oldpath),
547 SCM_ROLENGTH (oldpath), 0);
548 SCM_VALIDATE_ROSTRING (2,newpath);
549 if (SCM_SUBSTRP (newpath))
550 newpath = scm_makfromstr (SCM_ROCHARS (newpath),
551 SCM_ROLENGTH (newpath), 0);
552 SCM_SYSCALL (val = link (SCM_ROCHARS (oldpath), SCM_ROCHARS (newpath)));
553 if (val != 0)
554 SCM_SYSERROR;
555 return SCM_UNSPECIFIED;
556 }
557 #undef FUNC_NAME
558
559
560
561 SCM_DEFINE (scm_rename, "rename-file", 2, 0, 0,
562 (SCM oldname, SCM newname),
563 "Renames the file specified by @var{path-from} to @var{path-to}.\n"
564 "The return value is unspecified.")
565 #define FUNC_NAME s_scm_rename
566 {
567 int rv;
568 SCM_VALIDATE_ROSTRING (1,oldname);
569 SCM_VALIDATE_ROSTRING (2,newname);
570 SCM_COERCE_SUBSTR (oldname);
571 SCM_COERCE_SUBSTR (newname);
572 #ifdef HAVE_RENAME
573 SCM_SYSCALL (rv = rename (SCM_ROCHARS (oldname), SCM_ROCHARS (newname)));
574 #else
575 SCM_SYSCALL (rv = link (SCM_ROCHARS (oldname), SCM_ROCHARS (newname)));
576 if (rv == 0)
577 {
578 SCM_SYSCALL (rv = unlink (SCM_ROCHARS (oldname)));;
579 if (rv != 0)
580 /* unlink failed. remove new name */
581 SCM_SYSCALL (unlink (SCM_ROCHARS (newname)));
582 }
583 #endif
584 if (rv != 0)
585 SCM_SYSERROR;
586 return SCM_UNSPECIFIED;
587 }
588 #undef FUNC_NAME
589
590
591 SCM_DEFINE (scm_delete_file, "delete-file", 1, 0, 0,
592 (SCM str),
593 "Deletes (or \"unlinks\") the file specified by @var{path}.")
594 #define FUNC_NAME s_scm_delete_file
595 {
596 int ans;
597 SCM_VALIDATE_ROSTRING (1,str);
598 SCM_COERCE_SUBSTR (str);
599 SCM_SYSCALL (ans = unlink (SCM_ROCHARS (str)));
600 if (ans != 0)
601 SCM_SYSERROR;
602 return SCM_UNSPECIFIED;
603 }
604 #undef FUNC_NAME
605
606 #ifdef HAVE_MKDIR
607 SCM_DEFINE (scm_mkdir, "mkdir", 1, 1, 0,
608 (SCM path, SCM mode),
609 "Create a new directory named by @var{path}. If @var{mode} is omitted\n"
610 "then the permissions of the directory file are set using the current\n"
611 "umask. Otherwise they are set to the decimal value specified with\n"
612 "@var{mode}. The return value is unspecified.")
613 #define FUNC_NAME s_scm_mkdir
614 {
615 int rv;
616 mode_t mask;
617 SCM_VALIDATE_ROSTRING (1,path);
618 SCM_COERCE_SUBSTR (path);
619 if (SCM_UNBNDP (mode))
620 {
621 mask = umask (0);
622 umask (mask);
623 SCM_SYSCALL (rv = mkdir (SCM_ROCHARS (path), 0777 ^ mask));
624 }
625 else
626 {
627 SCM_VALIDATE_INUM (2,mode);
628 SCM_SYSCALL (rv = mkdir (SCM_ROCHARS (path), SCM_INUM (mode)));
629 }
630 if (rv != 0)
631 SCM_SYSERROR;
632 return SCM_UNSPECIFIED;
633 }
634 #undef FUNC_NAME
635 #endif /* HAVE_MKDIR */
636
637 #ifdef HAVE_RMDIR
638 SCM_DEFINE (scm_rmdir, "rmdir", 1, 0, 0,
639 (SCM path),
640 "Remove the existing directory named by @var{path}. The directory must\n"
641 "be empty for this to succeed. The return value is unspecified.")
642 #define FUNC_NAME s_scm_rmdir
643 {
644 int val;
645
646 SCM_VALIDATE_ROSTRING (1,path);
647 SCM_COERCE_SUBSTR (path);
648 SCM_SYSCALL (val = rmdir (SCM_ROCHARS (path)));
649 if (val != 0)
650 SCM_SYSERROR;
651 return SCM_UNSPECIFIED;
652 }
653 #undef FUNC_NAME
654 #endif
655
656 \f
657 /* {Examining Directories}
658 */
659
660 long scm_tc16_dir;
661
662 SCM_DEFINE (scm_directory_stream_p, "directory-stream?", 1, 0, 0,
663 (SCM obj),
664 "Returns a boolean indicating whether @var{object} is a directory stream\n"
665 "as returned by @code{opendir}.")
666 #define FUNC_NAME s_scm_directory_stream_p
667 {
668 return SCM_BOOL(SCM_DIRP (obj));
669 }
670 #undef FUNC_NAME
671
672 SCM_DEFINE (scm_opendir, "opendir", 1, 0, 0,
673 (SCM dirname),
674 "Open the directory specified by @var{path} and return a directory\n"
675 "stream.")
676 #define FUNC_NAME s_scm_opendir
677 {
678 DIR *ds;
679 SCM_VALIDATE_ROSTRING (1,dirname);
680 SCM_COERCE_SUBSTR (dirname);
681 SCM_SYSCALL (ds = opendir (SCM_ROCHARS (dirname)));
682 if (ds == NULL)
683 SCM_SYSERROR;
684 SCM_RETURN_NEWSMOB (scm_tc16_dir | SCM_OPN, ds);
685 }
686 #undef FUNC_NAME
687
688
689 SCM_DEFINE (scm_readdir, "readdir", 1, 0, 0,
690 (SCM port),
691 "Return (as a string) the next directory entry from the directory stream\n"
692 "@var{stream}. If there is no remaining entry to be read then the\n"
693 "end of file object is returned.")
694 #define FUNC_NAME s_scm_readdir
695 {
696 struct dirent *rdent;
697 SCM_VALIDATE_OPDIR (1,port);
698 errno = 0;
699 SCM_SYSCALL (rdent = readdir ((DIR *) SCM_CDR (port)));
700 if (errno != 0)
701 SCM_SYSERROR;
702 return (rdent ? scm_makfromstr (rdent->d_name, NAMLEN (rdent), 0)
703 : SCM_EOF_VAL);
704 }
705 #undef FUNC_NAME
706
707
708
709 SCM_DEFINE (scm_rewinddir, "rewinddir", 1, 0, 0,
710 (SCM port),
711 "Reset the directory port @var{stream} so that the next call to\n"
712 "@code{readdir} will return the first directory entry.")
713 #define FUNC_NAME s_scm_rewinddir
714 {
715 SCM_VALIDATE_OPDIR (1,port);
716 rewinddir ((DIR *) SCM_CDR (port));
717 return SCM_UNSPECIFIED;
718 }
719 #undef FUNC_NAME
720
721
722
723 SCM_DEFINE (scm_closedir, "closedir", 1, 0, 0,
724 (SCM port),
725 "Close the directory stream @var{stream}.\n"
726 "The return value is unspecified.")
727 #define FUNC_NAME s_scm_closedir
728 {
729 int sts;
730
731 SCM_VALIDATE_DIR (1,port);
732 if (SCM_CLOSEDP (port))
733 {
734 return SCM_UNSPECIFIED;
735 }
736 SCM_SYSCALL (sts = closedir ((DIR *) SCM_CDR (port)));
737 if (sts != 0)
738 SCM_SYSERROR;
739 SCM_SETCAR (port, scm_tc16_dir);
740 return SCM_UNSPECIFIED;
741 }
742 #undef FUNC_NAME
743
744
745
746
747 static int
748 scm_dir_print (SCM exp, SCM port, scm_print_state *pstate)
749 {
750 scm_puts ("#<", port);
751 if (SCM_CLOSEDP (exp))
752 scm_puts ("closed: ", port);
753 scm_puts ("directory stream ", port);
754 scm_intprint (SCM_CDR (exp), 16, port);
755 scm_putc ('>', port);
756 return 1;
757 }
758
759
760 static scm_sizet
761 scm_dir_free (SCM p)
762 {
763 if (SCM_OPENP (p))
764 closedir ((DIR *) SCM_CDR (p));
765 return 0;
766 }
767
768 \f
769 /* {Navigating Directories}
770 */
771
772
773 SCM_DEFINE (scm_chdir, "chdir", 1, 0, 0,
774 (SCM str),
775 "Change the current working directory to @var{path}.\n"
776 "The return value is unspecified.")
777 #define FUNC_NAME s_scm_chdir
778 {
779 int ans;
780
781 SCM_VALIDATE_ROSTRING (1,str);
782 SCM_COERCE_SUBSTR (str);
783 SCM_SYSCALL (ans = chdir (SCM_ROCHARS (str)));
784 if (ans != 0)
785 SCM_SYSERROR;
786 return SCM_UNSPECIFIED;
787 }
788 #undef FUNC_NAME
789
790 #ifdef HAVE_GETCWD
791 SCM_DEFINE (scm_getcwd, "getcwd", 0, 0, 0,
792 (),
793 "Returns the name of the current working directory.")
794 #define FUNC_NAME s_scm_getcwd
795 {
796 char *rv;
797
798 scm_sizet size = 100;
799 char *wd;
800 SCM result;
801
802 wd = scm_must_malloc (size, FUNC_NAME);
803 while ((rv = getcwd (wd, size)) == 0 && errno == ERANGE)
804 {
805 scm_must_free (wd);
806 size *= 2;
807 wd = scm_must_malloc (size, FUNC_NAME);
808 }
809 if (rv == 0)
810 SCM_SYSERROR;
811 result = scm_makfromstr (wd, strlen (wd), 0);
812 scm_must_free (wd);
813 return result;
814 }
815 #undef FUNC_NAME
816 #endif /* HAVE_GETCWD */
817
818 \f
819
820 static int
821 set_element (SELECT_TYPE *set, SCM element, int arg)
822 {
823 int fd;
824 element = SCM_COERCE_OUTPORT (element);
825 if (SCM_OPFPORTP (element))
826 fd = SCM_FPORT_FDES (element);
827 else {
828 SCM_ASSERT (SCM_INUMP (element), element, arg, "select");
829 fd = SCM_INUM (element);
830 }
831 FD_SET (fd, set);
832 return fd;
833 }
834
835 static int
836 fill_select_type (SELECT_TYPE *set, SCM list, int arg)
837 {
838 int max_fd = 0, fd;
839 if (SCM_VECTORP (list))
840 {
841 int len = SCM_LENGTH (list);
842 SCM *ve = SCM_VELTS (list);
843
844 while (len > 0)
845 {
846 fd = set_element (set, ve[len - 1], arg);
847 if (fd > max_fd)
848 max_fd = fd;
849 len--;
850 }
851 }
852 else
853 {
854 while (list != SCM_EOL)
855 {
856 fd = set_element (set, SCM_CAR (list), arg);
857 if (fd > max_fd)
858 max_fd = fd;
859 list = SCM_CDR (list);
860 }
861 }
862
863 return max_fd;
864 }
865
866 static SCM
867 get_element (SELECT_TYPE *set, SCM element, SCM list)
868 {
869 element = SCM_COERCE_OUTPORT (element);
870 if (SCM_OPFPORTP (element))
871 {
872 if (FD_ISSET (SCM_FPORT_FDES (element), set))
873 list = scm_cons (element, list);
874 }
875 else if (SCM_INUMP (element))
876 {
877 if (FD_ISSET (SCM_INUM (element), set))
878 list = scm_cons (element, list);
879 }
880 return list;
881 }
882
883 static SCM
884 retrieve_select_type (SELECT_TYPE *set, SCM list)
885 {
886 SCM answer_list = SCM_EOL;
887
888 if (SCM_VECTORP (list))
889 {
890 int len = SCM_LENGTH (list);
891 SCM *ve = SCM_VELTS (list);
892
893 while (len > 0)
894 {
895 answer_list = get_element (set, ve[len - 1], answer_list);
896 len--;
897 }
898 return scm_vector (answer_list);
899 }
900 else
901 {
902 /* list is a list. */
903 while (list != SCM_EOL)
904 {
905 answer_list = get_element (set, SCM_CAR (list), answer_list);
906 list = SCM_CDR (list);
907 }
908 return answer_list;
909 }
910 }
911
912 #ifdef HAVE_SELECT
913 /* Static helper functions above refer to s_scm_select directly as s_select */
914 SCM_DEFINE (scm_select, "select", 3, 2, 0,
915 (SCM reads, SCM writes, SCM excepts, SCM secs, SCM usecs),
916 "@var{reads}, @var{writes} and @var{excepts} can be lists or vectors: it\n"
917 "doesn't matter which, but the corresponding object returned will be\n"
918 "of the same type.\n"
919 "Each element is a port or file descriptor on which to wait for\n"
920 "readability, writeability\n"
921 "or exceptional conditions respectively. @var{secs} and @var{usecs}\n"
922 "optionally specify a timeout: @var{secs} can be specified alone, as\n"
923 "either an integer or a real number, or both @var{secs} and @var{usecs}\n"
924 "can be specified as integers, in which case @var{usecs} is an additional\n"
925 "timeout expressed in microseconds.\n\n"
926 "Buffered input or output data is (currently, but this may change)\n"
927 "ignored: select uses the underlying file descriptor of a port\n"
928 "(@code{char-ready?} will check input buffers, output buffers are\n"
929 "problematic).\n\n"
930 "The return value is a list of subsets of the input lists or vectors for\n"
931 "which the requested condition has been met.\n\n"
932 "It is not quite compatible with scsh's select: scsh checks port buffers,\n"
933 "doesn't accept input lists or a microsecond timeout, returns multiple\n"
934 "values instead of a list and has an additional select! interface.\n"
935 "")
936 #define FUNC_NAME s_scm_select
937 {
938 struct timeval timeout;
939 struct timeval * time_p;
940 SELECT_TYPE read_set;
941 SELECT_TYPE write_set;
942 SELECT_TYPE except_set;
943 int max_fd, fd;
944 int sreturn;
945
946 #define assert_set(x, arg) \
947 SCM_ASSERT (scm_ilength (x) >= 0 || (SCM_VECTORP (x)), \
948 x, arg, FUNC_NAME)
949 assert_set (reads, SCM_ARG1);
950 assert_set (writes, SCM_ARG2);
951 assert_set (excepts, SCM_ARG3);
952 #undef assert_set
953
954 FD_ZERO (&read_set);
955 FD_ZERO (&write_set);
956 FD_ZERO (&except_set);
957
958 max_fd = fill_select_type (&read_set, reads, SCM_ARG1);
959 fd = fill_select_type (&write_set, writes, SCM_ARG2);
960 if (fd > max_fd)
961 max_fd = fd;
962 fd = fill_select_type (&except_set, excepts, SCM_ARG3);
963 if (fd > max_fd)
964 max_fd = fd;
965
966 if (SCM_UNBNDP (secs) || SCM_FALSEP (secs))
967 time_p = 0;
968 else
969 {
970 if (SCM_INUMP (secs))
971 {
972 timeout.tv_sec = SCM_INUM (secs);
973 if (SCM_UNBNDP (usecs))
974 timeout.tv_usec = 0;
975 else
976 {
977 SCM_VALIDATE_INUM (5,usecs);
978 timeout.tv_usec = SCM_INUM (usecs);
979 }
980 }
981 else
982 {
983 double fl = scm_num2dbl (secs, FUNC_NAME);
984
985 if (!SCM_UNBNDP (usecs))
986 SCM_WRONG_TYPE_ARG (4, secs);
987 if (fl > LONG_MAX)
988 SCM_OUT_OF_RANGE (4, secs);
989 timeout.tv_sec = (long) fl;
990 timeout.tv_usec = (long) ((fl - timeout.tv_sec) * 1000000);
991 }
992 time_p = &timeout;
993 }
994
995 #ifdef GUILE_ISELECT
996 sreturn = scm_internal_select (max_fd + 1,
997 &read_set, &write_set, &except_set, time_p);
998 #else
999 sreturn = select (max_fd + 1,
1000 &read_set, &write_set, &except_set, time_p);
1001 #endif
1002 if (sreturn < 0)
1003 SCM_SYSERROR;
1004 return scm_listify (retrieve_select_type (&read_set, reads),
1005 retrieve_select_type (&write_set, writes),
1006 retrieve_select_type (&except_set, excepts),
1007 SCM_UNDEFINED);
1008 }
1009 #undef FUNC_NAME
1010 #endif /* HAVE_SELECT */
1011
1012 \f
1013
1014 SCM_DEFINE (scm_fcntl, "fcntl", 2, 0, 1,
1015 (SCM object, SCM cmd, SCM value),
1016 "Apply @var{command} to the specified file descriptor or the underlying\n"
1017 "file descriptor of the specified port. @var{value} is an optional\n"
1018 "integer argument.\n\n"
1019 "Values for @var{command} are:\n\n"
1020 "@table @code\n"
1021 "@item F_DUPFD\n"
1022 "Duplicate a file descriptor\n"
1023 "@item F_GETFD\n"
1024 "Get flags associated with the file descriptor.\n"
1025 "@item F_SETFD\n"
1026 "Set flags associated with the file descriptor to @var{value}.\n"
1027 "@item F_GETFL\n"
1028 "Get flags associated with the open file.\n"
1029 "@item F_SETFL\n"
1030 "Set flags associated with the open file to @var{value}\n"
1031 "@item F_GETOWN\n"
1032 "Get the process ID of a socket's owner, for @code{SIGIO} signals.\n"
1033 "@item F_SETOWN\n"
1034 "Set the process that owns a socket to @var{value}, for @code{SIGIO} signals.\n"
1035 "@item FD_CLOEXEC\n"
1036 "The value used to indicate the \"close on exec\" flag with @code{F_GETFL} or"
1037 "@code{F_SETFL}."
1038 "@end table")
1039 #define FUNC_NAME s_scm_fcntl
1040 {
1041 int rv;
1042 int fdes;
1043 int ivalue;
1044
1045 object = SCM_COERCE_OUTPORT (object);
1046
1047 SCM_VALIDATE_INUM (2,cmd);
1048 if (SCM_OPFPORTP (object))
1049 fdes = SCM_FPORT_FDES (object);
1050 else
1051 {
1052 SCM_VALIDATE_INUM (1,object);
1053 fdes = SCM_INUM (object);
1054 }
1055 if (SCM_NULLP (value))
1056 ivalue = 0;
1057 else
1058 {
1059 SCM_ASSERT (SCM_INUMP (SCM_CAR (value)), value, SCM_ARG3, FUNC_NAME);
1060 ivalue = SCM_INUM (SCM_CAR (value));
1061 }
1062 SCM_SYSCALL (rv = fcntl (fdes, SCM_INUM (cmd), ivalue));
1063 if (rv == -1)
1064 SCM_SYSERROR;
1065 return SCM_MAKINUM (rv);
1066 }
1067 #undef FUNC_NAME
1068
1069 SCM_DEFINE (scm_fsync, "fsync", 1, 0, 0,
1070 (SCM object),
1071 "Copies any unwritten data for the specified output file descriptor to disk.\n"
1072 "If @var{port/fd} is a port, its buffer is flushed before the underlying\n"
1073 "file descriptor is fsync'd.\n"
1074 "The return value is unspecified.")
1075 #define FUNC_NAME s_scm_fsync
1076 {
1077 int fdes;
1078
1079 object = SCM_COERCE_OUTPORT (object);
1080
1081 if (SCM_OPFPORTP (object))
1082 {
1083 scm_flush (object);
1084 fdes = SCM_FPORT_FDES (object);
1085 }
1086 else
1087 {
1088 SCM_VALIDATE_INUM (1,object);
1089 fdes = SCM_INUM (object);
1090 }
1091 if (fsync (fdes) == -1)
1092 SCM_SYSERROR;
1093 return SCM_UNSPECIFIED;
1094 }
1095 #undef FUNC_NAME
1096
1097 #ifdef HAVE_SYMLINK
1098 SCM_DEFINE (scm_symlink, "symlink", 2, 0, 0,
1099 (SCM oldpath, SCM newpath),
1100 "Create a symbolic link named @var{path-to} with the value (i.e., pointing to)\n"
1101 "@var{path-from}. The return value is unspecified.")
1102 #define FUNC_NAME s_scm_symlink
1103 {
1104 int val;
1105
1106 SCM_VALIDATE_ROSTRING (1,oldpath);
1107 SCM_VALIDATE_ROSTRING (2,newpath);
1108 SCM_COERCE_SUBSTR (oldpath);
1109 SCM_COERCE_SUBSTR (newpath);
1110 SCM_SYSCALL (val = symlink(SCM_ROCHARS(oldpath), SCM_ROCHARS(newpath)));
1111 if (val != 0)
1112 SCM_SYSERROR;
1113 return SCM_UNSPECIFIED;
1114 }
1115 #undef FUNC_NAME
1116 #endif /* HAVE_SYMLINK */
1117
1118 #ifdef HAVE_READLINK
1119 SCM_DEFINE (scm_readlink, "readlink", 1, 0, 0,
1120 (SCM path),
1121 "Returns the value of the symbolic link named by\n"
1122 "@var{path} (a string), i.e., the\n"
1123 "file that the link points to.")
1124 #define FUNC_NAME s_scm_readlink
1125 {
1126 int rv;
1127 int size = 100;
1128 char *buf;
1129 SCM result;
1130 SCM_VALIDATE_ROSTRING (1,path);
1131 SCM_COERCE_SUBSTR (path);
1132 buf = scm_must_malloc (size, FUNC_NAME);
1133 while ((rv = readlink (SCM_ROCHARS (path), buf, size)) == size)
1134 {
1135 scm_must_free (buf);
1136 size *= 2;
1137 buf = scm_must_malloc (size, FUNC_NAME);
1138 }
1139 if (rv == -1)
1140 SCM_SYSERROR;
1141 result = scm_makfromstr (buf, rv, 0);
1142 scm_must_free (buf);
1143 return result;
1144 }
1145 #undef FUNC_NAME
1146 #endif /* HAVE_READLINK */
1147
1148 #ifdef HAVE_LSTAT
1149 SCM_DEFINE (scm_lstat, "lstat", 1, 0, 0,
1150 (SCM str),
1151 "Similar to @code{stat}, but does not follow symbolic links, i.e.,\n"
1152 "it will return information about a symbolic link itself, not the \n"
1153 "file it points to. @var{path} must be a string.")
1154 #define FUNC_NAME s_scm_lstat
1155 {
1156 int rv;
1157 struct stat stat_temp;
1158
1159 SCM_VALIDATE_ROSTRING (1,str);
1160 SCM_COERCE_SUBSTR (str);
1161 SCM_SYSCALL(rv = lstat(SCM_ROCHARS(str), &stat_temp));
1162 if (rv != 0)
1163 {
1164 int en = errno;
1165
1166 SCM_SYSERROR_MSG ("~A: ~S",
1167 scm_listify (scm_makfrom0str (strerror (errno)),
1168 str,
1169 SCM_UNDEFINED), en);
1170 }
1171 return scm_stat2scm(&stat_temp);
1172 }
1173 #undef FUNC_NAME
1174 #endif /* HAVE_LSTAT */
1175
1176 SCM_DEFINE (scm_copy_file, "copy-file", 2, 0, 0,
1177 (SCM oldfile, SCM newfile),
1178 "Copy the file specified by @var{path-from} to @var{path-to}.\n"
1179 "The return value is unspecified.")
1180 #define FUNC_NAME s_scm_copy_file
1181 {
1182 int oldfd, newfd;
1183 int n;
1184 char buf[BUFSIZ];
1185 struct stat oldstat;
1186
1187 SCM_VALIDATE_ROSTRING (1,oldfile);
1188 if (SCM_SUBSTRP (oldfile))
1189 oldfile = scm_makfromstr (SCM_ROCHARS (oldfile), SCM_ROLENGTH (oldfile), 0);
1190 SCM_VALIDATE_ROSTRING (2,newfile);
1191 if (SCM_SUBSTRP (newfile))
1192 newfile = scm_makfromstr (SCM_ROCHARS (newfile), SCM_ROLENGTH (newfile), 0);
1193 if (stat (SCM_ROCHARS (oldfile), &oldstat) == -1)
1194 SCM_SYSERROR;
1195 oldfd = open (SCM_ROCHARS (oldfile), O_RDONLY);
1196 if (oldfd == -1)
1197 SCM_SYSERROR;
1198
1199 /* use POSIX flags instead of 07777?. */
1200 newfd = open (SCM_ROCHARS (newfile), O_WRONLY | O_CREAT | O_TRUNC,
1201 oldstat.st_mode & 07777);
1202 if (newfd == -1)
1203 SCM_SYSERROR;
1204
1205 while ((n = read (oldfd, buf, sizeof buf)) > 0)
1206 if (write (newfd, buf, n) != n)
1207 {
1208 close (oldfd);
1209 close (newfd);
1210 SCM_SYSERROR;
1211 }
1212 close (oldfd);
1213 if (close (newfd) == -1)
1214 SCM_SYSERROR;
1215 return SCM_UNSPECIFIED;
1216 }
1217 #undef FUNC_NAME
1218
1219 \f
1220 /* Filename manipulation */
1221
1222 SCM scm_dot_string;
1223
1224 SCM_DEFINE (scm_dirname, "dirname", 1, 0, 0,
1225 (SCM filename),
1226 "")
1227 #define FUNC_NAME s_scm_dirname
1228 {
1229 char *s;
1230 int i, len;
1231 SCM_VALIDATE_ROSTRING (1,filename);
1232 s = SCM_ROCHARS (filename);
1233 len = SCM_LENGTH (filename);
1234 i = len - 1;
1235 while (i >= 0 && s[i] == '/') --i;
1236 while (i >= 0 && s[i] != '/') --i;
1237 while (i >= 0 && s[i] == '/') --i;
1238 if (i < 0)
1239 {
1240 if (len > 0 && s[0] == '/')
1241 return scm_make_shared_substring (filename, SCM_INUM0, SCM_MAKINUM (1));
1242 else
1243 return scm_dot_string;
1244 }
1245 else
1246 return scm_make_shared_substring (filename, SCM_INUM0, SCM_MAKINUM (i + 1));
1247 }
1248 #undef FUNC_NAME
1249
1250 SCM_DEFINE (scm_basename, "basename", 1, 1, 0,
1251 (SCM filename, SCM suffix),
1252 "")
1253 #define FUNC_NAME s_scm_basename
1254 {
1255 char *f, *s = 0;
1256 int i, j, len, end;
1257 SCM_VALIDATE_ROSTRING (1,filename);
1258 SCM_ASSERT (SCM_UNBNDP (suffix)
1259 || (SCM_ROSTRINGP (suffix)),
1260 suffix,
1261 SCM_ARG2,
1262 FUNC_NAME);
1263 f = SCM_ROCHARS (filename);
1264 if (SCM_UNBNDP (suffix))
1265 j = -1;
1266 else
1267 {
1268 s = SCM_ROCHARS (suffix);
1269 j = SCM_LENGTH (suffix) - 1;
1270 }
1271 len = SCM_LENGTH (filename);
1272 i = len - 1;
1273 while (i >= 0 && f[i] == '/') --i;
1274 end = i;
1275 while (i >= 0 && j >= 0 && f[i] == s[j]) --i, --j;
1276 if (j == -1)
1277 end = i;
1278 while (i >= 0 && f[i] != '/') --i;
1279 if (i == end)
1280 {
1281 if (len > 0 && f[0] == '/')
1282 return scm_make_shared_substring (filename, SCM_INUM0, SCM_MAKINUM (1));
1283 else
1284 return scm_dot_string;
1285 }
1286 else
1287 return scm_make_shared_substring (filename,
1288 SCM_MAKINUM (i + 1),
1289 SCM_MAKINUM (end + 1));
1290 }
1291 #undef FUNC_NAME
1292
1293
1294
1295 \f
1296
1297 void
1298 scm_init_filesys ()
1299 {
1300 scm_tc16_dir = scm_make_smob_type_mfpe ("directory", 0,
1301 NULL, scm_dir_free,scm_dir_print, NULL);
1302
1303 scm_dot_string = scm_permanent_object (scm_makfrom0str ("."));
1304
1305 #ifdef O_RDONLY
1306 scm_sysintern ("O_RDONLY", scm_long2num (O_RDONLY));
1307 #endif
1308 #ifdef O_WRONLY
1309 scm_sysintern ("O_WRONLY", scm_long2num (O_WRONLY));
1310 #endif
1311 #ifdef O_RDWR
1312 scm_sysintern ("O_RDWR", scm_long2num (O_RDWR));
1313 #endif
1314 #ifdef O_CREAT
1315 scm_sysintern ("O_CREAT", scm_long2num (O_CREAT));
1316 #endif
1317 #ifdef O_EXCL
1318 scm_sysintern ("O_EXCL", scm_long2num (O_EXCL));
1319 #endif
1320 #ifdef O_NOCTTY
1321 scm_sysintern ("O_NOCTTY", scm_long2num (O_NOCTTY));
1322 #endif
1323 #ifdef O_TRUNC
1324 scm_sysintern ("O_TRUNC", scm_long2num (O_TRUNC));
1325 #endif
1326 #ifdef O_APPEND
1327 scm_sysintern ("O_APPEND", scm_long2num (O_APPEND));
1328 #endif
1329 #ifdef O_NONBLOCK
1330 scm_sysintern ("O_NONBLOCK", scm_long2num (O_NONBLOCK));
1331 #endif
1332 #ifdef O_NDELAY
1333 scm_sysintern ("O_NDELAY", scm_long2num (O_NDELAY));
1334 #endif
1335 #ifdef O_SYNC
1336 scm_sysintern ("O_SYNC", scm_long2num (O_SYNC));
1337 #endif
1338
1339 #ifdef F_DUPFD
1340 scm_sysintern ("F_DUPFD", scm_long2num (F_DUPFD));
1341 #endif
1342 #ifdef F_GETFD
1343 scm_sysintern ("F_GETFD", scm_long2num (F_GETFD));
1344 #endif
1345 #ifdef F_SETFD
1346 scm_sysintern ("F_SETFD", scm_long2num (F_SETFD));
1347 #endif
1348 #ifdef F_GETFL
1349 scm_sysintern ("F_GETFL", scm_long2num (F_GETFL));
1350 #endif
1351 #ifdef F_SETFL
1352 scm_sysintern ("F_SETFL", scm_long2num (F_SETFL));
1353 #endif
1354 #ifdef F_GETOWN
1355 scm_sysintern ("F_GETOWN", scm_long2num (F_GETOWN));
1356 #endif
1357 #ifdef F_SETOWN
1358 scm_sysintern ("F_SETOWN", scm_long2num (F_SETOWN));
1359 #endif
1360 #ifdef FD_CLOEXEC
1361 scm_sysintern ("FD_CLOEXEC", scm_long2num (FD_CLOEXEC));
1362 #endif
1363
1364 #include "filesys.x"
1365 }