1 /* Copyright (C) 1996 Free Software Foundation, Inc.
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)
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.
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, 675 Mass Ave, Cambridge, MA 02139, USA.
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
39 * If you do not wish that, delete this exception notice.
45 #ifdef TIME_WITH_SYS_TIME
46 # include <sys/time.h>
50 # include <sys/time.h>
60 #ifdef HAVE_SYS_SELECT_H
61 #include <sys/select.h>
72 #define SELECT_TYPE fd_set
73 #define SELECT_SET_SIZE FD_SETSIZE
77 /* Define the macros to access a single-int bitmap of descriptors. */
78 #define SELECT_SET_SIZE 32
79 #define SELECT_TYPE int
80 #define FD_SET(n, p) (*(p) |= (1 << (n)))
81 #define FD_CLR(n, p) (*(p) &= ~(1 << (n)))
82 #define FD_ISSET(n, p) (*(p) & (1 << (n)))
83 #define FD_ZERO(p) (*(p) = 0)
85 #endif /* no FD_SET */
89 # define NAMLEN(dirent) strlen((dirent)->d_name)
91 # define dirent direct
92 # define NAMLEN(dirent) (dirent)->d_namlen
94 # include <sys/ndir.h>
107 SCM_CONST_LONG (scm_O_CREAT
, "O_CREAT", O_CREAT
);
111 SCM_CONST_LONG (scm_O_EXCL
, "O_EXCL", O_EXCL
);
115 SCM_CONST_LONG (scm_O_NOCTTY
, "O_NOCTTY", O_NOCTTY
);
119 SCM_CONST_LONG (scm_O_TRUNC
, "O_TRUNC", O_TRUNC
);
123 SCM_CONST_LONG (scm_O_APPEND
, "O_APPEND", O_APPEND
);
127 SCM_CONST_LONG (scm_O_NONBLOCK
, "O_NONBLOCK", O_NONBLOCK
);
131 SCM_CONST_LONG (scm_O_NDELAY
, "O_NDELAY", O_NDELAY
);
135 SCM_CONST_LONG (scm_O_SYNC
, "O_SYNC", O_SYNC
);
145 SCM_PROC (s_sys_chown
, "%chown", 3, 0, 0, scm_sys_chown
);
148 scm_sys_chown (SCM path
, SCM owner
, SCM group
)
151 scm_sys_chown (path
, owner
, group
)
158 SCM_ASSERT (SCM_NIMP (path
) && SCM_ROSTRINGP (path
), path
, SCM_ARG1
, s_sys_chown
);
159 if (SCM_SUBSTRP (path
))
160 path
= scm_makfromstr (SCM_ROCHARS (path
), SCM_ROLENGTH (path
), 0);
161 SCM_ASSERT (SCM_INUMP (owner
), owner
, SCM_ARG2
, s_sys_chown
);
162 SCM_ASSERT (SCM_INUMP (group
), group
, SCM_ARG3
, s_sys_chown
);
163 SCM_SYSCALL (val
= chown (SCM_ROCHARS (path
), SCM_INUM (owner
), SCM_INUM (group
)));
164 return val
? SCM_MAKINUM (errno
) : SCM_BOOL_T
;
168 SCM_PROC (s_sys_chmod
, "%chmod", 2, 0, 0, scm_sys_chmod
);
171 scm_sys_chmod (SCM port_or_path
, SCM mode
)
174 scm_sys_chmod (port_or_path
, mode
)
180 SCM_ASSERT (SCM_INUMP (mode
), mode
, SCM_ARG2
, s_sys_chmod
);
181 SCM_ASSERT (SCM_NIMP (port_or_path
), port_or_path
, SCM_ARG1
, s_sys_chmod
);
182 if (SCM_STRINGP (port_or_path
))
183 SCM_SYSCALL (rv
= chmod (SCM_CHARS (port_or_path
), SCM_INUM (mode
)));
186 SCM_ASSERT (SCM_OPFPORTP (port_or_path
), port_or_path
, SCM_ARG1
, s_sys_chmod
);
187 rv
= fileno ((FILE *)SCM_STREAM (port_or_path
));
189 SCM_SYSCALL (rv
= fchmod (rv
, SCM_INUM (mode
)));
191 return rv
? SCM_MAKINUM (errno
) : SCM_BOOL_T
;
194 SCM_PROC (s_umask
, "umask", 0, 1, 0, scm_umask
);
205 if (SCM_UNBNDP (mode
))
212 SCM_ASSERT (SCM_INUMP (mode
), mode
, SCM_ARG1
, s_umask
);
213 mask
= umask (SCM_INUM (mode
));
215 return SCM_MAKINUM (mask
);
219 /* {File Descriptors}
225 scm_fd_print (SCM sexp
, SCM port
, int writing
)
228 scm_fd_print (sexp
, port
, writing
)
234 scm_gen_puts (scm_regular_string
, "#<fd ", port
);
235 scm_intprint (SCM_CDR (sexp
), 10, port
);
236 scm_gen_puts (scm_regular_string
, ">", port
);
251 flags
= SCM_FD_FLAGS (p
);
252 if ((scm_close_fd_on_gc
& flags
) && (scm_fd_is_open
& flags
))
254 SCM_SYSCALL( close (SCM_FD (p
)) );
259 static scm_smobfuns fd_smob
= {scm_mark0
, scm_fd_free
, scm_fd_print
, 0};
263 scm_intern_fd (int fd
, int flags
)
266 scm_intern_fd (fd
, flags
)
274 SCM_SETCAR (it
, (scm_tc16_fd
| (flags
<< 16)));
275 SCM_SETCDR (it
, (SCM
)fd
);
282 SCM_PROC (s_sys_open
, "%open", 3, 0, 0, scm_sys_open
);
285 scm_sys_open (SCM path
, SCM flags
, SCM mode
)
288 scm_sys_open (path
, flags
, mode
)
297 SCM_ASSERT (SCM_NIMP (path
) && SCM_ROSTRINGP (path
), path
, SCM_ARG1
, s_sys_open
);
298 SCM_ASSERT (SCM_INUMP (flags
), flags
, SCM_ARG2
, s_sys_open
);
299 SCM_ASSERT (SCM_INUMP (mode
), mode
, SCM_ARG3
, s_sys_open
);
301 if (SCM_SUBSTRP (path
))
302 path
= scm_makfromstr (SCM_ROCHARS (path
), SCM_ROLENGTH (path
), 0);
305 SCM_SYSCALL ( fd
= open (SCM_ROCHARS (path
), SCM_INUM (flags
), SCM_INUM (mode
)) );
307 sfd
= SCM_MAKINUM (errno
);
309 sfd
= scm_intern_fd (fd
, scm_fd_is_open
| scm_close_fd_on_gc
);
312 return scm_return_first (sfd
, path
);
316 SCM_PROC (s_sys_create
, "%create", 2, 0, 0, scm_sys_create
);
319 scm_sys_create (SCM path
, SCM mode
)
322 scm_sys_create (path
, mode
)
330 SCM_ASSERT (SCM_NIMP (path
) && SCM_ROSTRINGP (path
), path
, SCM_ARG1
, s_sys_create
);
331 SCM_ASSERT (SCM_INUMP (mode
), mode
, SCM_ARG2
, s_sys_create
);
333 if (SCM_SUBSTRP (path
))
334 path
= scm_makfromstr (SCM_ROCHARS (path
), SCM_ROLENGTH (path
), 0);
337 SCM_SYSCALL ( fd
= creat (SCM_ROCHARS (path
), SCM_INUM (mode
)) );
339 sfd
= SCM_MAKINUM (errno
);
341 sfd
= scm_intern_fd (fd
, scm_fd_is_open
| scm_close_fd_on_gc
);
344 return scm_return_first (sfd
, path
);
348 SCM_PROC (s_sys_close
, "%close", 1, 0, 0, scm_sys_close
);
351 scm_sys_close (SCM sfd
)
360 SCM_ASSERT (SCM_NIMP (sfd
) && SCM_FD_P (sfd
), sfd
, SCM_ARG1
, s_sys_close
);
365 SCM_SETCAR (sfd
, scm_tc16_fd
);
367 return (got
== -1 ? SCM_MAKINUM (errno
) : SCM_BOOL_T
);
371 SCM_PROC (s_sys_write_fd
, "%write-fd", 2, 0, 0, scm_sys_write_fd
);
374 scm_sys_write_fd (SCM sfd
, SCM buf
)
377 scm_sys_write_fd (sfd
, buf
)
385 SCM_ASSERT (SCM_NIMP (sfd
) && SCM_FD_P (sfd
), sfd
, SCM_ARG1
, s_sys_write_fd
);
386 SCM_ASSERT (SCM_NIMP (buf
) && SCM_ROSTRINGP (buf
), buf
, SCM_ARG2
, s_sys_write_fd
);
389 written
= write (fd
, SCM_ROCHARS (buf
), SCM_ROLENGTH (buf
));
391 answer
= scm_cons (SCM_MAKINUM (errno
), SCM_EOL
);
393 answer
= scm_long2num (written
);
395 return scm_return_first (answer
, buf
);
399 SCM_PROC (s_sys_read_fd
, "%read-fd", 2, 2, 0, scm_sys_read_fd
);
402 scm_sys_read_fd (SCM sfd
, SCM buf
, SCM offset
, SCM length
)
405 scm_sys_read_fd (sfd
, buf
, offset
, length
)
419 SCM_ASSERT (SCM_NIMP (sfd
) && SCM_FD_P (sfd
), sfd
, SCM_ARG1
, s_sys_read_fd
);
422 SCM_ASSERT (SCM_NIMP (buf
) && SCM_STRINGP (buf
), buf
, SCM_ARG2
, s_sys_read_fd
);
423 bytes
= SCM_CHARS (buf
);
425 if (SCM_UNBNDP (offset
))
429 SCM_ASSERT (SCM_INUMP (offset
), offset
, SCM_ARG3
, s_sys_read_fd
);
430 off
= SCM_INUM (offset
);
433 if (SCM_UNBNDP (length
))
434 len
= SCM_LENGTH (buf
);
437 SCM_ASSERT (SCM_INUMP (length
), length
, SCM_ARG3
, s_sys_read_fd
);
438 len
= SCM_INUM (length
);
442 got
= read (fd
, bytes
+ off
, len
);
444 answer
= scm_cons (SCM_MAKINUM (errno
), SCM_EOL
);
446 answer
= scm_long2num (got
);
448 return scm_return_first (answer
, buf
);
451 SCM_PROC (s_sys_lseek
, "%lseek", 2, 1, 0, scm_sys_lseek
);
454 scm_sys_lseek (SCM sfd
, SCM offset
, SCM whence
)
457 scm_sys_lseek (sfd
, offset
, whence
)
469 SCM_ASSERT (SCM_NIMP (sfd
) && SCM_FD_P (sfd
), sfd
, SCM_ARG1
, s_sys_lseek
);
472 off
= scm_num2long (offset
, (char *)SCM_ARG2
, s_sys_lseek
);
473 if (SCM_UNBNDP (whence
))
477 SCM_ASSERT (SCM_INUMP (whence
), whence
, SCM_ARG3
, s_sys_lseek
);
478 wh
= SCM_INUM (whence
);
482 SCM_SYSCALL (got
= lseek (fd
, off
, wh
));
484 answer
= SCM_MAKINUM (errno
);
486 answer
= scm_long2num (got
);
492 SCM_PROC (s_sys_dup
, "%dup", 1, 1, 0, scm_sys_dup
);
495 scm_sys_dup (SCM oldfd
, SCM newfd
)
498 scm_sys_dup (oldfd
, newfd
)
508 SCM_ASSERT (SCM_NIMP (oldfd
) && SCM_FD_P (oldfd
), oldfd
, SCM_ARG1
, s_sys_dup
);
509 SCM_ASSERT (SCM_UNBNDP (newfd
) || SCM_INUMP (newfd
), newfd
, SCM_ARG2
, s_sys_dup
);
511 nfd
= (SCM_INUMP (newfd
) ? SCM_INUM (newfd
) : -1);
514 fn
= ((nfd
== -1) ? (int (*)())dup
: (int (*)())dup2
);
517 ? scm_cons (SCM_MAKINUM (errno
), SCM_EOL
)
518 : SCM_MAKINUM (nfd
));
529 scm_stat2scm (struct stat
*stat_temp
)
532 scm_stat2scm (stat_temp
)
533 struct stat
*stat_temp
;
536 SCM ans
= scm_make_vector (SCM_MAKINUM (13), SCM_UNSPECIFIED
, SCM_BOOL_F
);
537 SCM
*ve
= SCM_VELTS (ans
);
538 ve
[0] = scm_ulong2num ((unsigned long) stat_temp
->st_dev
);
539 ve
[1] = scm_ulong2num ((unsigned long) stat_temp
->st_ino
);
540 ve
[2] = scm_ulong2num ((unsigned long) stat_temp
->st_mode
);
541 ve
[3] = scm_ulong2num ((unsigned long) stat_temp
->st_nlink
);
542 ve
[4] = scm_ulong2num ((unsigned long) stat_temp
->st_uid
);
543 ve
[5] = scm_ulong2num ((unsigned long) stat_temp
->st_gid
);
545 ve
[6] = scm_ulong2num ((unsigned long) stat_temp
->st_rdev
);
549 ve
[7] = scm_ulong2num ((unsigned long) stat_temp
->st_size
);
550 ve
[8] = scm_ulong2num ((unsigned long) stat_temp
->st_atime
);
551 ve
[9] = scm_ulong2num ((unsigned long) stat_temp
->st_mtime
);
552 ve
[10] = scm_ulong2num ((unsigned long) stat_temp
->st_ctime
);
553 #ifdef HAVE_ST_BLKSIZE
554 ve
[11] = scm_ulong2num ((unsigned long) stat_temp
->st_blksize
);
556 ve
[11] = scm_ulong2num (4096L);
558 #ifdef HAVE_ST_BLOCKS
559 ve
[12] = scm_ulong2num ((unsigned long) stat_temp
->st_blocks
);
567 SCM_PROC (s_sys_stat
, "%stat", 1, 0, 0, scm_sys_stat
);
570 scm_sys_stat (SCM fd_or_path
)
573 scm_sys_stat (fd_or_path
)
578 struct stat stat_temp
;
580 if (SCM_INUMP (fd_or_path
))
582 SCM_ASSERT (SCM_OPFPORTP (fd_or_path
), fd_or_path
, SCM_ARG1
, s_sys_stat
);
583 rv
= SCM_INUM (fd_or_path
);
584 SCM_SYSCALL (rv
= fstat (rv
, &stat_temp
));
586 else if (SCM_NIMP (fd_or_path
) && SCM_FD_P (fd_or_path
))
588 rv
= SCM_FD (fd_or_path
);
589 SCM_SYSCALL (rv
= fstat (rv
, &stat_temp
));
593 SCM_ASSERT (SCM_NIMP (fd_or_path
), fd_or_path
, SCM_ARG1
, s_sys_stat
);
594 SCM_ASSERT (SCM_ROSTRINGP (fd_or_path
), fd_or_path
, SCM_ARG1
, s_sys_stat
);
595 if (SCM_ROSTRINGP (fd_or_path
))
597 if (SCM_SUBSTRP (fd_or_path
))
598 fd_or_path
= scm_makfromstr (SCM_ROCHARS (fd_or_path
), SCM_ROLENGTH (fd_or_path
), 0);
599 SCM_SYSCALL (rv
= stat (SCM_CHARS (fd_or_path
), &stat_temp
));
603 return rv
? SCM_MAKINUM (errno
) : scm_stat2scm (&stat_temp
);
608 /* {Modifying Directories}
611 SCM_PROC (s_sys_link
, "%link", 2, 0, 0, scm_sys_link
);
614 scm_sys_link (SCM oldpath
, SCM newpath
)
617 scm_sys_link (oldpath
, newpath
)
623 SCM_ASSERT (SCM_NIMP (oldpath
) && SCM_ROSTRINGP (oldpath
), oldpath
, SCM_ARG1
, s_sys_link
);
624 if (SCM_SUBSTRP (oldpath
))
625 oldpath
= scm_makfromstr (SCM_ROCHARS (oldpath
), SCM_ROLENGTH (oldpath
), 0);
626 SCM_ASSERT (SCM_NIMP (newpath
) && SCM_ROSTRINGP (newpath
), newpath
, SCM_ARG2
, s_sys_link
);
627 if (SCM_SUBSTRP (newpath
))
628 newpath
= scm_makfromstr (SCM_ROCHARS (newpath
), SCM_ROLENGTH (newpath
), 0);
629 SCM_SYSCALL (val
= link (SCM_ROCHARS (oldpath
), SCM_ROCHARS (newpath
)));
630 return val
? SCM_MAKINUM (errno
) : SCM_BOOL_T
;
635 SCM_PROC (s_sys_rename
, "%rename-file", 2, 0, 0, scm_sys_rename
);
638 scm_sys_rename (SCM oldname
, SCM newname
)
641 scm_sys_rename (oldname
, newname
)
647 SCM_ASSERT (SCM_NIMP (oldname
) && SCM_STRINGP (oldname
), oldname
, SCM_ARG1
, s_sys_rename
);
648 SCM_ASSERT (SCM_NIMP (newname
) && SCM_STRINGP (newname
), newname
, SCM_ARG2
, s_sys_rename
);
650 SCM_SYSCALL (rv
= rename (SCM_CHARS (oldname
), SCM_CHARS (newname
)));
651 return rv
? SCM_MAKINUM (errno
) : SCM_BOOL_T
;
654 SCM_SYSCALL (rv
= link (SCM_CHARS (oldname
), SCM_CHARS (newname
)));
657 SCM_SYSCALL (rv
= unlink (SCM_CHARS (oldname
)));;
659 /* unlink failed. remove new name */
660 SCM_SYSCALL (unlink (SCM_CHARS (newname
)));
663 return rv
? SCM_MAKINUM (errno
) : SCM_BOOL_T
;
669 SCM_PROC (s_sys_mkdir
, "%mkdir", 1, 1, 0, scm_sys_mkdir
);
672 scm_sys_mkdir (SCM path
, SCM mode
)
675 scm_sys_mkdir (path
, mode
)
683 SCM_ASSERT (SCM_NIMP (path
) && SCM_STRINGP (path
), path
, SCM_ARG1
, s_sys_mkdir
);
684 if (SCM_UNBNDP (mode
))
688 SCM_SYSCALL (rv
= mkdir (SCM_CHARS (path
), 0777 ^ mask
));
692 SCM_ASSERT (SCM_INUMP (mode
), mode
, SCM_ARG2
, s_sys_mkdir
);
693 SCM_SYSCALL (rv
= mkdir (SCM_CHARS (path
), SCM_INUM (mode
)));
695 return rv
? SCM_MAKINUM (errno
) : SCM_BOOL_T
;
697 return SCM_MAKINUM (ENOSYS
);
702 SCM_PROC (s_sys_rmdir
, "%rmdir", 1, 0, 0, scm_sys_rmdir
);
705 scm_sys_rmdir (SCM path
)
714 SCM_ASSERT (SCM_NIMP (path
) && SCM_STRINGP (path
), path
, SCM_ARG1
, s_sys_rmdir
);
715 SCM_SYSCALL (val
= rmdir (SCM_CHARS (path
)));
716 return val
? SCM_MAKINUM (errno
) : SCM_BOOL_T
;
718 return SCM_MAKINUM (ENOSYS
);
723 /* {Examining Directories}
728 SCM_PROC (s_sys_opendir
, "%opendir", 1, 0, 0, scm_sys_opendir
);
731 scm_sys_opendir (SCM dirname
)
734 scm_sys_opendir (dirname
)
740 SCM_ASSERT (SCM_NIMP (dirname
) && SCM_STRINGP (dirname
), dirname
, SCM_ARG1
, s_sys_opendir
);
743 SCM_SYSCALL (ds
= opendir (SCM_CHARS (dirname
)));
747 return SCM_MAKINUM (errno
);
749 SCM_CAR (dir
) = scm_tc16_dir
| SCM_OPN
;
750 SCM_SETCDR (dir
, ds
);
756 SCM_PROC (s_sys_readdir
, "%readdir", 1, 0, 0, scm_sys_readdir
);
759 scm_sys_readdir (SCM port
)
762 scm_sys_readdir (port
)
766 struct dirent
*rdent
;
768 SCM_ASSERT (SCM_NIMP (port
) && SCM_OPDIRP (port
), port
, SCM_ARG1
, s_sys_readdir
);
770 SCM_SYSCALL (rdent
= readdir ((DIR *) SCM_CDR (port
)));
773 ? scm_makfromstr (rdent
->d_name
, NAMLEN (rdent
), 0)
774 : (errno
? SCM_MAKINUM (errno
) : SCM_EOF_VAL
));
779 SCM_PROC (s_rewinddir
, "rewinddir", 1, 0, 0, scm_rewinddir
);
782 scm_rewinddir (SCM port
)
789 SCM_ASSERT (SCM_NIMP (port
) && SCM_OPDIRP (port
), port
, SCM_ARG1
, s_rewinddir
);
790 rewinddir ((DIR *) SCM_CDR (port
));
791 return SCM_UNSPECIFIED
;
796 SCM_PROC (s_sys_closedir
, "%closedir", 1, 0, 0, scm_sys_closedir
);
799 scm_sys_closedir (SCM port
)
802 scm_sys_closedir (port
)
807 SCM_ASSERT (SCM_NIMP (port
) && SCM_DIRP (port
), port
, SCM_ARG1
, s_sys_closedir
);
809 if (SCM_CLOSEDP (port
))
812 return SCM_MAKINUM (errno
);
814 SCM_SYSCALL (sts
= closedir ((DIR *) SCM_CDR (port
)));
818 return SCM_MAKINUM (errno
);
820 SCM_CAR (port
) = scm_tc16_dir
;
829 scm_dir_print (SCM sexp
, SCM port
, int writing
)
832 scm_dir_print (sexp
, port
, writing
)
838 scm_prinport (sexp
, port
, "directory");
852 closedir ((DIR *) SCM_CDR (p
));
856 static scm_smobfuns dir_smob
= {scm_mark0
, scm_dir_free
, scm_dir_print
, 0};
859 /* {Navigating Directories}
863 SCM_PROC (s_sys_chdir
, "%chdir", 1, 0, 0, scm_sys_chdir
);
866 scm_sys_chdir (SCM str
)
874 SCM_ASSERT (SCM_NIMP (str
) && SCM_STRINGP (str
), str
, SCM_ARG1
, s_sys_chdir
);
875 SCM_SYSCALL (ans
= chdir (SCM_CHARS (str
)));
876 return ans
? SCM_MAKINUM (errno
) : SCM_BOOL_T
;
881 SCM_PROC (s_sys_getcwd
, "%getcwd", 0, 0, 0, scm_sys_getcwd
);
884 scm_sys_getcwd (void)
893 scm_sizet size
= 100;
898 wd
= scm_must_malloc (size
, s_sys_getcwd
);
899 while ((rv
= getcwd (wd
, size
)) == 0 && errno
== ERANGE
)
903 wd
= scm_must_malloc (size
, s_sys_getcwd
);
906 result
= scm_makfromstr (wd
, strlen (wd
), 0);
908 result
= SCM_MAKINUM (errno
);
913 return SCM_MAKINUM (ENOSYS
);
921 fill_select_type (SELECT_TYPE
* set
, SCM list
)
924 fill_select_type (set
, list
)
929 while (list
!= SCM_EOL
)
931 if ( SCM_NIMP (SCM_CAR (list
))
932 && (scm_tc16_fport
== SCM_TYP16 (SCM_CAR (list
)))
933 && SCM_OPPORTP (SCM_CAR (list
)))
934 FD_SET (fileno ((FILE *)SCM_STREAM (SCM_CAR (list
))), set
);
935 else if (SCM_INUMP (SCM_CAR (list
)))
936 FD_SET (SCM_INUM (SCM_CAR (list
)), set
);
937 else if (SCM_NIMP (SCM_CAR (list
)) && SCM_FD_P (SCM_CAR (list
)))
938 FD_SET (SCM_FD (SCM_CAR (list
)), set
);
939 list
= SCM_CDR (list
);
945 retrieve_select_type (SELECT_TYPE
* set
, SCM list
)
948 retrieve_select_type (set
, list
)
955 while (list
!= SCM_EOL
)
957 if ( SCM_NIMP (SCM_CAR (list
))
958 && (scm_tc16_fport
== SCM_TYP16 (SCM_CAR (list
)))
959 && SCM_OPPORTP (SCM_CAR (list
)))
961 if (FD_ISSET (fileno ((FILE *)SCM_STREAM (SCM_CAR (list
))), set
))
962 answer
= scm_cons (SCM_CAR (list
), answer
);
964 else if (SCM_INUMP (SCM_CAR (list
)))
966 if (FD_ISSET (SCM_INUM (SCM_CAR (list
)), set
))
967 answer
= scm_cons (SCM_CAR (list
), answer
);
969 else if (SCM_NIMP (SCM_CAR (list
)) && SCM_FD_P (SCM_CAR (list
)))
971 if (FD_ISSET (SCM_FD (SCM_CAR (list
)), set
))
972 answer
= scm_cons (SCM_CAR (list
), answer
);
974 list
= SCM_CDR (list
);
980 SCM_PROC (s_sys_select
, "%select", 3, 2, 0, scm_sys_select
);
983 scm_sys_select (SCM reads
, SCM writes
, SCM excepts
, SCM secs
, SCM msecs
)
986 scm_sys_select (reads
, writes
, excepts
, secs
, msecs
)
995 struct timeval timeout
;
996 struct timeval
* time_p
;
997 SELECT_TYPE read_set
;
998 SELECT_TYPE write_set
;
999 SELECT_TYPE except_set
;
1002 SCM_ASSERT (-1 < scm_ilength (reads
), reads
, SCM_ARG1
, s_sys_select
);
1003 SCM_ASSERT (-1 < scm_ilength (writes
), reads
, SCM_ARG1
, s_sys_select
);
1004 SCM_ASSERT (-1 < scm_ilength (excepts
), reads
, SCM_ARG1
, s_sys_select
);
1006 FD_ZERO (&read_set
);
1007 FD_ZERO (&write_set
);
1008 FD_ZERO (&except_set
);
1010 fill_select_type (&read_set
, reads
);
1011 fill_select_type (&write_set
, writes
);
1012 fill_select_type (&except_set
, excepts
);
1014 if (SCM_UNBNDP (secs
))
1018 SCM_ASSERT (SCM_INUMP (secs
), secs
, SCM_ARG4
, s_sys_select
);
1019 if (SCM_UNBNDP (msecs
))
1022 SCM_ASSERT (SCM_INUMP (msecs
), msecs
, SCM_ARG5
, s_sys_select
);
1024 timeout
.tv_sec
= SCM_INUM (secs
);
1025 timeout
.tv_usec
= 1000 * SCM_INUM (msecs
);
1030 sreturn
= select (SELECT_SET_SIZE
,
1031 &read_set
, &write_set
, &except_set
, time_p
);
1034 return SCM_MAKINUM (errno
);
1036 return scm_listify (retrieve_select_type (&read_set
, reads
),
1037 retrieve_select_type (&write_set
, writes
),
1038 retrieve_select_type (&except_set
, excepts
),
1041 return SCM_MAKINUM (ENOSYS
);
1049 SCM_PROC (s_sys_symlink
, "%symlink", 2, 0, 0, scm_sys_symlink
);
1052 scm_sys_symlink(SCM oldpath
, SCM newpath
)
1055 scm_sys_symlink(oldpath
, newpath
)
1062 SCM_ASSERT(SCM_NIMP(oldpath
) && SCM_STRINGP(oldpath
), oldpath
, SCM_ARG1
, s_sys_symlink
);
1063 SCM_ASSERT(SCM_NIMP(newpath
) && SCM_STRINGP(newpath
), newpath
, SCM_ARG2
, s_sys_symlink
);
1064 SCM_SYSCALL(val
= symlink(SCM_CHARS(oldpath
), SCM_CHARS(newpath
)));
1065 return val
? SCM_MAKINUM (errno
) : SCM_BOOL_T
;
1067 return SCM_MAKINUM (ENOSYS
);
1072 SCM_PROC (s_sys_readlink
, "%readlink", 1, 0, 0, scm_sys_readlink
);
1075 scm_sys_readlink(SCM path
)
1078 scm_sys_readlink(path
)
1082 #ifdef HAVE_READLINK
1084 scm_sizet size
= 100;
1087 SCM_ASSERT (SCM_NIMP (path
) && SCM_STRINGP (path
), path
, (char *) SCM_ARG1
, s_sys_readlink
);
1089 buf
= scm_must_malloc (size
, s_sys_readlink
);
1090 while ((rv
= readlink (SCM_CHARS (path
), buf
, (scm_sizet
) size
)) == size
)
1092 scm_must_free (buf
);
1094 buf
= scm_must_malloc (size
, s_sys_readlink
);
1097 result
= scm_makfromstr (buf
, rv
, 0);
1099 result
= SCM_MAKINUM (errno
);
1100 scm_must_free (buf
);
1104 return SCM_MAKINUM (ENOSYS
);
1109 SCM_PROC (s_sys_lstat
, "%lstat", 1, 0, 0, scm_sys_lstat
);
1112 scm_sys_lstat(SCM str
)
1121 struct stat stat_temp
;
1122 SCM_ASSERT(SCM_NIMP(str
) && SCM_STRINGP(str
), str
, (char *)SCM_ARG1
, s_sys_lstat
);
1123 SCM_SYSCALL(i
= lstat(SCM_CHARS(str
), &stat_temp
));
1124 return i
? SCM_MAKINUM (errno
) : scm_stat2scm(&stat_temp
);
1126 return SCM_MAKINUM (ENOSYS
);
1131 SCM_PROC (s_sys_copy_file
, "%copy-file", 2, 0, 0, scm_sys_copy_file
);
1134 scm_sys_copy_file (SCM oldfile
, SCM newfile
)
1137 scm_sys_copy_file (oldfile
, newfile
)
1144 char buf
[BUFSIZ
]; /* this space could be shared. */
1145 struct stat oldstat
;
1147 SCM_ASSERT (SCM_NIMP (oldfile
) && SCM_ROSTRINGP (oldfile
), oldfile
, SCM_ARG1
, s_sys_copy_file
);
1148 if (SCM_SUBSTRP (oldfile
))
1149 oldfile
= scm_makfromstr (SCM_ROCHARS (oldfile
), SCM_ROLENGTH (oldfile
), 0);
1150 SCM_ASSERT (SCM_NIMP (newfile
) && SCM_ROSTRINGP (newfile
), newfile
, SCM_ARG2
, s_sys_copy_file
);
1151 if (SCM_SUBSTRP (newfile
))
1152 newfile
= scm_makfromstr (SCM_ROCHARS (newfile
), SCM_ROLENGTH (newfile
), 0);
1153 if (stat (SCM_ROCHARS (oldfile
), &oldstat
) == -1)
1156 oldfd
= open (SCM_ROCHARS (oldfile
), O_RDONLY
);
1162 /* should probably use the POSIX flags instead of 07777. */
1163 newfd
= open (SCM_ROCHARS (newfile
), O_WRONLY
| O_CREAT
| O_TRUNC
,
1164 oldstat
.st_mode
& 07777);
1171 while ((n
= read (oldfd
, buf
, sizeof buf
)) > 0)
1172 if (write (newfd
, buf
, n
) != n
)
1180 if (close (newfd
) == -1)
1192 scm_init_filesys (void)
1198 /* File type/permission bits. */
1200 scm_sysintern ("S_IRUSR", SCM_MAKINUM (S_IRUSR
));
1203 scm_sysintern ("S_IWUSR", SCM_MAKINUM (S_IWUSR
));
1206 scm_sysintern ("S_IXUSR", SCM_MAKINUM (S_IXUSR
));
1209 scm_sysintern ("S_IRWXU", SCM_MAKINUM (S_IRWXU
));
1213 scm_sysintern ("S_IRGRP", SCM_MAKINUM (S_IRGRP
));
1216 scm_sysintern ("S_IWGRP", SCM_MAKINUM (S_IWGRP
));
1219 scm_sysintern ("S_IXGRP", SCM_MAKINUM (S_IXGRP
));
1222 scm_sysintern ("S_IRWXG", SCM_MAKINUM (S_IRWXG
));
1226 scm_sysintern ("S_IROTH", SCM_MAKINUM (S_IROTH
));
1229 scm_sysintern ("S_IWOTH", SCM_MAKINUM (S_IWOTH
));
1232 scm_sysintern ("S_IXOTH", SCM_MAKINUM (S_IXOTH
));
1235 scm_sysintern ("S_IRWXO", SCM_MAKINUM (S_IRWXO
));
1239 scm_sysintern ("S_ISUID", SCM_MAKINUM (S_ISUID
));
1242 scm_sysintern ("S_ISGID", SCM_MAKINUM (S_ISGID
));
1245 scm_sysintern ("S_ISVTX", SCM_MAKINUM (S_ISVTX
));
1249 scm_sysintern ("S_IFMT", SCM_MAKINUM (S_IFMT
));
1252 scm_sysintern ("S_IFDIR", SCM_MAKINUM (S_IFDIR
));
1255 scm_sysintern ("S_IFCHR", SCM_MAKINUM (S_IFCHR
));
1258 scm_sysintern ("S_IFBLK", SCM_MAKINUM (S_IFBLK
));
1261 scm_sysintern ("S_IFREG", SCM_MAKINUM (S_IFREG
));
1264 scm_sysintern ("S_IFLNK", SCM_MAKINUM (S_IFLNK
));
1267 scm_sysintern ("S_IFSOCK", SCM_MAKINUM (S_IFSOCK
));
1270 scm_sysintern ("S_IFIFO", SCM_MAKINUM (S_IFIFO
));
1274 scm_tc16_fd
= scm_newsmob (&fd_smob
);
1275 scm_tc16_dir
= scm_newsmob (&dir_smob
);
1277 #include "filesys.x"