1 /* Copyright (C) 1996, 1997 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, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
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.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
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.
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. */
51 #ifdef TIME_WITH_SYS_TIME
52 # include <sys/time.h>
56 # include <sys/time.h>
66 #ifdef LIBC_H_WITH_UNISTD_H
70 #ifdef HAVE_SYS_SELECT_H
71 #include <sys/select.h>
78 #include <sys/types.h>
87 #define SELECT_TYPE fd_set
88 #define SELECT_SET_SIZE FD_SETSIZE
92 /* Define the macros to access a single-int bitmap of descriptors. */
93 #define SELECT_SET_SIZE 32
94 #define SELECT_TYPE int
95 #define FD_SET(n, p) (*(p) |= (1 << (n)))
96 #define FD_CLR(n, p) (*(p) &= ~(1 << (n)))
97 #define FD_ISSET(n, p) (*(p) & (1 << (n)))
98 #define FD_ZERO(p) (*(p) = 0)
100 #endif /* no FD_SET */
104 # define NAMLEN(dirent) strlen((dirent)->d_name)
106 # define dirent direct
107 # define NAMLEN(dirent) (dirent)->d_namlen
109 # include <sys/ndir.h>
112 # include <sys/dir.h>
119 /* Ultrix has S_IFSOCK, but no S_ISSOCK. Ipe! */
120 #if defined (S_IFSOCK) && ! defined (S_ISSOCK)
121 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
131 SCM_PROC (s_chown
, "chown", 3, 0, 0, scm_chown
);
134 scm_chown (object
, owner
, group
)
142 object
= SCM_COERCE_OUTPORT (object
);
144 SCM_ASSERT (SCM_INUMP (owner
), owner
, SCM_ARG2
, s_chown
);
145 SCM_ASSERT (SCM_INUMP (group
), group
, SCM_ARG3
, s_chown
);
147 if (SCM_INUMP (object
) || (SCM_NIMP (object
) && SCM_OPFPORTP (object
)))
149 if (SCM_INUMP (object
))
150 fdes
= SCM_INUM (object
);
153 fdes
= fileno ((FILE *) SCM_STREAM (object
));
155 scm_syserror (s_chown
);
157 SCM_SYSCALL (rv
= fchown (fdes
, SCM_INUM (owner
), SCM_INUM (group
)));
161 SCM_ASSERT (SCM_NIMP (object
) && SCM_ROSTRINGP (object
),
162 object
, SCM_ARG1
, s_chown
);
163 SCM_COERCE_SUBSTR (object
);
164 SCM_SYSCALL (rv
= chown (SCM_ROCHARS (object
),
165 SCM_INUM (owner
), SCM_INUM (group
)));
168 scm_syserror (s_chown
);
170 return SCM_UNSPECIFIED
;
174 SCM_PROC (s_chmod
, "chmod", 2, 0, 0, scm_chmod
);
177 scm_chmod (object
, mode
)
184 object
= SCM_COERCE_OUTPORT (object
);
186 SCM_ASSERT (SCM_INUMP (mode
), mode
, SCM_ARG2
, s_chmod
);
188 if (SCM_INUMP (object
) || (SCM_NIMP (object
) && SCM_OPFPORTP (object
)))
190 if (SCM_INUMP (object
))
191 fdes
= SCM_INUM (object
);
194 fdes
= fileno ((FILE *) SCM_STREAM (object
));
196 scm_syserror (s_chmod
);
198 SCM_SYSCALL (rv
= fchmod (fdes
, SCM_INUM (mode
)));
202 SCM_ASSERT (SCM_NIMP (object
) && SCM_ROSTRINGP (object
),
203 object
, SCM_ARG1
, s_chmod
);
204 SCM_COERCE_SUBSTR (object
);
205 SCM_SYSCALL (rv
= chmod (SCM_ROCHARS (object
), SCM_INUM (mode
)));
208 scm_syserror (s_chmod
);
210 return SCM_UNSPECIFIED
;
213 SCM_PROC (s_umask
, "umask", 0, 1, 0, scm_umask
);
220 if (SCM_UNBNDP (mode
))
227 SCM_ASSERT (SCM_INUMP (mode
), mode
, SCM_ARG1
, s_umask
);
228 mask
= umask (SCM_INUM (mode
));
230 return SCM_MAKINUM (mask
);
235 SCM_PROC (s_open_fdes
, "open-fdes", 2, 1, 0, scm_open_fdes
);
237 scm_open_fdes (SCM path
, SCM flags
, SCM mode
)
243 SCM_ASSERT (SCM_NIMP (path
) && SCM_ROSTRINGP (path
), path
, SCM_ARG1
,
245 SCM_COERCE_SUBSTR (path
);
246 iflags
= scm_num2long (flags
, (char *) SCM_ARG2
, s_open_fdes
);
249 if (SCM_UNBNDP (mode
))
253 SCM_ASSERT (SCM_INUMP (mode
), mode
, SCM_ARG3
, s_open_fdes
);
254 imode
= SCM_INUM (mode
);
256 SCM_SYSCALL (fd
= open (SCM_ROCHARS (path
), iflags
, imode
));
258 scm_syserror (s_open_fdes
);
260 return SCM_MAKINUM (fd
);
263 SCM_PROC (s_open
, "open", 2, 1, 0, scm_open
);
265 scm_open (SCM path
, SCM flags
, SCM mode
)
273 fd
= SCM_INUM (scm_open_fdes (path
, flags
, mode
));
274 iflags
= scm_num2long (flags
, (char *) SCM_ARG2
, s_open_fdes
);
279 if (iflags
& O_WRONLY
)
285 f
= fdopen (fd
, port_mode
);
288 SCM_SYSCALL (close (fd
));
289 scm_syserror (s_open
);
292 struct scm_port_table
* pt
;
294 pt
= scm_add_to_port_table (newpt
);
295 SCM_SETPTAB_ENTRY (newpt
, pt
);
296 SCM_SETCAR (newpt
, scm_tc16_fport
| scm_mode_bits (port_mode
));
297 /* if (SCM_BUF0 & SCM_CAR (newpt))
298 scm_setbuf0 (newpt); */
299 SCM_SETSTREAM (newpt
, (SCM
)f
);
300 SCM_PTAB_ENTRY (newpt
)->file_name
= path
;
307 SCM_PROC (s_close
, "close", 1, 0, 0, scm_close
);
309 scm_close (SCM fd_or_port
)
314 fd_or_port
= SCM_COERCE_OUTPORT (fd_or_port
);
316 if (SCM_NIMP (fd_or_port
) && SCM_PORTP (fd_or_port
))
317 return scm_close_port (fd_or_port
);
318 SCM_ASSERT (SCM_INUMP (fd_or_port
), fd_or_port
, SCM_ARG1
, s_close
);
319 fd
= SCM_INUM (fd_or_port
);
321 scm_evict_ports (fd
); /* see scsh manual. */
322 SCM_SYSCALL (rv
= close (fd
));
323 /* following scsh, closing an already closed file descriptor is
325 if (rv
< 0 && errno
!= EBADF
)
326 scm_syserror (s_close
);
328 return (rv
< 0) ? SCM_BOOL_F
: SCM_BOOL_T
;
335 SCM_SYMBOL (scm_sym_regular
, "regular");
336 SCM_SYMBOL (scm_sym_directory
, "directory");
337 SCM_SYMBOL (scm_sym_symlink
, "symlink");
338 SCM_SYMBOL (scm_sym_block_special
, "block-special");
339 SCM_SYMBOL (scm_sym_char_special
, "char-special");
340 SCM_SYMBOL (scm_sym_fifo
, "fifo");
341 SCM_SYMBOL (scm_sym_sock
, "socket");
342 SCM_SYMBOL (scm_sym_unknown
, "unknown");
344 static SCM scm_stat2scm
SCM_P ((struct stat
*stat_temp
));
347 scm_stat2scm (stat_temp
)
348 struct stat
*stat_temp
;
350 SCM ans
= scm_make_vector (SCM_MAKINUM (15), SCM_UNSPECIFIED
, SCM_BOOL_F
);
351 SCM
*ve
= SCM_VELTS (ans
);
353 ve
[0] = scm_ulong2num ((unsigned long) stat_temp
->st_dev
);
354 ve
[1] = scm_ulong2num ((unsigned long) stat_temp
->st_ino
);
355 ve
[2] = scm_ulong2num ((unsigned long) stat_temp
->st_mode
);
356 ve
[3] = scm_ulong2num ((unsigned long) stat_temp
->st_nlink
);
357 ve
[4] = scm_ulong2num ((unsigned long) stat_temp
->st_uid
);
358 ve
[5] = scm_ulong2num ((unsigned long) stat_temp
->st_gid
);
360 ve
[6] = scm_ulong2num ((unsigned long) stat_temp
->st_rdev
);
364 ve
[7] = scm_ulong2num ((unsigned long) stat_temp
->st_size
);
365 ve
[8] = scm_ulong2num ((unsigned long) stat_temp
->st_atime
);
366 ve
[9] = scm_ulong2num ((unsigned long) stat_temp
->st_mtime
);
367 ve
[10] = scm_ulong2num ((unsigned long) stat_temp
->st_ctime
);
368 #ifdef HAVE_ST_BLKSIZE
369 ve
[11] = scm_ulong2num ((unsigned long) stat_temp
->st_blksize
);
371 ve
[11] = scm_ulong2num (4096L);
373 #ifdef HAVE_ST_BLOCKS
374 ve
[12] = scm_ulong2num ((unsigned long) stat_temp
->st_blocks
);
379 int mode
= stat_temp
->st_mode
;
382 ve
[13] = scm_sym_regular
;
383 else if (S_ISDIR (mode
))
384 ve
[13] = scm_sym_directory
;
385 else if (S_ISLNK (mode
))
386 ve
[13] = scm_sym_symlink
;
387 else if (S_ISBLK (mode
))
388 ve
[13] = scm_sym_block_special
;
389 else if (S_ISCHR (mode
))
390 ve
[13] = scm_sym_char_special
;
391 else if (S_ISFIFO (mode
))
392 ve
[13] = scm_sym_fifo
;
393 else if (S_ISSOCK (mode
))
394 ve
[13] = scm_sym_sock
;
396 ve
[13] = scm_sym_unknown
;
398 ve
[14] = SCM_MAKINUM ((~S_IFMT
) & mode
);
400 /* the layout of the bits in ve[14] is intended to be portable.
401 If there are systems that don't follow the usual convention,
402 the following could be used:
405 if (S_ISUID & mode) tmp += 1;
407 if (S_IRGRP & mode) tmp += 1;
409 if (S_ISVTX & mode) tmp += 1;
411 if (S_IRUSR & mode) tmp += 1;
413 if (S_IWUSR & mode) tmp += 1;
415 if (S_IXUSR & mode) tmp += 1;
417 if (S_IWGRP & mode) tmp += 1;
419 if (S_IXGRP & mode) tmp += 1;
421 if (S_IROTH & mode) tmp += 1;
423 if (S_IWOTH & mode) tmp += 1;
425 if (S_IXOTH & mode) tmp += 1;
427 ve[14] = SCM_MAKINUM (tmp);
435 SCM_PROC (s_stat
, "stat", 1, 0, 0, scm_stat
);
443 struct stat stat_temp
;
445 object
= SCM_COERCE_OUTPORT (object
);
448 if (SCM_INUMP (object
) || (SCM_NIMP (object
) && SCM_OPFPORTP (object
)))
450 if (SCM_INUMP (object
))
451 fdes
= SCM_INUM (object
);
454 fdes
= fileno ((FILE *) SCM_STREAM (object
));
456 scm_syserror (s_stat
);
458 SCM_SYSCALL (rv
= fstat (fdes
, &stat_temp
));
462 SCM_ASSERT (SCM_NIMP (object
) && SCM_ROSTRINGP (object
),
463 object
, SCM_ARG1
, s_stat
);
464 SCM_COERCE_SUBSTR (object
);
465 SCM_SYSCALL (rv
= stat (SCM_ROCHARS (object
), &stat_temp
));
471 scm_syserror_msg (s_stat
, "%s: %S",
472 scm_listify (scm_makfrom0str (strerror (errno
)),
478 return scm_stat2scm (&stat_temp
);
483 /* {Modifying Directories}
486 SCM_PROC (s_link
, "link", 2, 0, 0, scm_link
);
489 scm_link (oldpath
, newpath
)
495 SCM_ASSERT (SCM_NIMP (oldpath
) && SCM_ROSTRINGP (oldpath
), oldpath
,
497 if (SCM_SUBSTRP (oldpath
))
498 oldpath
= scm_makfromstr (SCM_ROCHARS (oldpath
),
499 SCM_ROLENGTH (oldpath
), 0);
500 SCM_ASSERT (SCM_NIMP (newpath
) && SCM_ROSTRINGP (newpath
), newpath
,
502 if (SCM_SUBSTRP (newpath
))
503 newpath
= scm_makfromstr (SCM_ROCHARS (newpath
),
504 SCM_ROLENGTH (newpath
), 0);
506 SCM_SYSCALL (val
= link (SCM_ROCHARS (oldpath
), SCM_ROCHARS (newpath
)));
508 scm_syserror (s_link
);
510 return SCM_UNSPECIFIED
;
515 SCM_PROC (s_rename
, "rename-file", 2, 0, 0, scm_rename
);
518 scm_rename (oldname
, newname
)
523 SCM_ASSERT (SCM_NIMP (oldname
) && SCM_ROSTRINGP (oldname
), oldname
, SCM_ARG1
,
525 SCM_ASSERT (SCM_NIMP (newname
) && SCM_ROSTRINGP (newname
), newname
, SCM_ARG2
,
527 SCM_COERCE_SUBSTR (oldname
);
528 SCM_COERCE_SUBSTR (newname
);
531 SCM_SYSCALL (rv
= rename (SCM_ROCHARS (oldname
), SCM_ROCHARS (newname
)));
533 SCM_SYSCALL (rv
= link (SCM_ROCHARS (oldname
), SCM_ROCHARS (newname
)));
536 SCM_SYSCALL (rv
= unlink (SCM_ROCHARS (oldname
)));;
538 /* unlink failed. remove new name */
539 SCM_SYSCALL (unlink (SCM_ROCHARS (newname
)));
543 scm_syserror (s_rename
);
545 return SCM_UNSPECIFIED
;
549 SCM_PROC(s_delete_file
, "delete-file", 1, 0, 0, scm_delete_file
);
552 scm_delete_file (str
)
556 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
), str
, SCM_ARG1
,
558 SCM_COERCE_SUBSTR (str
);
560 SCM_SYSCALL (ans
= unlink (SCM_ROCHARS (str
)));
562 scm_syserror (s_delete_file
);
564 return SCM_UNSPECIFIED
;
567 SCM_PROC (s_truncate_file
, "truncate-file", 2, 0, 0, scm_truncate_file
);
569 scm_truncate_file (SCM object
, SCM size
)
575 object
= SCM_COERCE_OUTPORT (object
);
577 csize
= (scm_sizet
) scm_num2long (size
, (char *) SCM_ARG2
, s_truncate_file
);
579 if (SCM_INUMP (object
) || (SCM_NIMP (object
) && SCM_OPFPORTP (object
)))
581 if (SCM_INUMP (object
))
582 fdes
= SCM_INUM (object
);
585 fdes
= fileno ((FILE *) SCM_STREAM (object
));
587 scm_syserror (s_truncate_file
);
589 SCM_SYSCALL (rv
= ftruncate (fdes
, csize
));
593 SCM_ASSERT (SCM_NIMP (object
) && SCM_ROSTRINGP (object
),
594 object
, SCM_ARG1
, s_chown
);
595 SCM_COERCE_SUBSTR (object
);
596 SCM_SYSCALL (rv
= truncate (SCM_ROCHARS (object
), csize
));
599 scm_syserror (s_truncate_file
);
601 return SCM_UNSPECIFIED
;
604 SCM_PROC (s_mkdir
, "mkdir", 1, 1, 0, scm_mkdir
);
607 scm_mkdir (path
, mode
)
614 SCM_ASSERT (SCM_NIMP (path
) && SCM_ROSTRINGP (path
), path
, SCM_ARG1
,
616 SCM_COERCE_SUBSTR (path
);
618 if (SCM_UNBNDP (mode
))
622 SCM_SYSCALL (rv
= mkdir (SCM_ROCHARS (path
), 0777 ^ mask
));
626 SCM_ASSERT (SCM_INUMP (mode
), mode
, SCM_ARG2
, s_mkdir
);
627 SCM_SYSCALL (rv
= mkdir (SCM_ROCHARS (path
), SCM_INUM (mode
)));
630 scm_syserror (s_mkdir
);
632 return SCM_UNSPECIFIED
;
634 scm_sysmissing (s_mkdir
);
641 SCM_PROC (s_rmdir
, "rmdir", 1, 0, 0, scm_rmdir
);
650 SCM_ASSERT (SCM_NIMP (path
) && SCM_ROSTRINGP (path
), path
, SCM_ARG1
,
652 SCM_COERCE_SUBSTR (path
);
654 SCM_SYSCALL (val
= rmdir (SCM_ROCHARS (path
)));
656 scm_syserror (s_rmdir
);
658 return SCM_UNSPECIFIED
;
660 scm_sysmissing (s_rmdir
);
667 /* {Examining Directories}
672 SCM_PROC (s_opendir
, "opendir", 1, 0, 0, scm_opendir
);
675 scm_opendir (dirname
)
680 SCM_ASSERT (SCM_NIMP (dirname
) && SCM_ROSTRINGP (dirname
), dirname
, SCM_ARG1
,
682 SCM_COERCE_SUBSTR (dirname
);
685 SCM_SYSCALL (ds
= opendir (SCM_ROCHARS (dirname
)));
687 scm_syserror (s_opendir
);
688 SCM_SETCAR (dir
, scm_tc16_dir
| SCM_OPN
);
689 SCM_SETCDR (dir
, ds
);
695 SCM_PROC (s_readdir
, "readdir", 1, 0, 0, scm_readdir
);
701 struct dirent
*rdent
;
703 SCM_ASSERT (SCM_NIMP (port
) && SCM_OPDIRP (port
), port
, SCM_ARG1
, s_readdir
);
705 SCM_SYSCALL (rdent
= readdir ((DIR *) SCM_CDR (port
)));
708 scm_syserror (s_readdir
);
709 return (rdent
? scm_makfromstr (rdent
->d_name
, NAMLEN (rdent
), 0)
715 SCM_PROC (s_rewinddir
, "rewinddir", 1, 0, 0, scm_rewinddir
);
721 SCM_ASSERT (SCM_NIMP (port
) && SCM_OPDIRP (port
), port
, SCM_ARG1
, s_rewinddir
);
722 rewinddir ((DIR *) SCM_CDR (port
));
723 return SCM_UNSPECIFIED
;
728 SCM_PROC (s_closedir
, "closedir", 1, 0, 0, scm_closedir
);
736 SCM_ASSERT (SCM_NIMP (port
) && SCM_DIRP (port
), port
, SCM_ARG1
, s_closedir
);
738 if (SCM_CLOSEDP (port
))
741 return SCM_UNSPECIFIED
;
743 SCM_SYSCALL (sts
= closedir ((DIR *) SCM_CDR (port
)));
745 scm_syserror (s_closedir
);
746 SCM_SETCAR (port
, scm_tc16_dir
);
748 return SCM_UNSPECIFIED
;
754 static int scm_dir_print
SCM_P ((SCM sexp
, SCM port
, scm_print_state
*pstate
));
757 scm_dir_print (sexp
, port
, pstate
)
760 scm_print_state
*pstate
;
762 scm_prinport (sexp
, port
, "directory");
767 static scm_sizet scm_dir_free
SCM_P ((SCM p
));
774 closedir ((DIR *) SCM_CDR (p
));
778 static scm_smobfuns dir_smob
= {scm_mark0
, scm_dir_free
, scm_dir_print
, 0};
781 /* {Navigating Directories}
785 SCM_PROC (s_chdir
, "chdir", 1, 0, 0, scm_chdir
);
793 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
), str
, SCM_ARG1
, s_chdir
);
794 SCM_COERCE_SUBSTR (str
);
796 SCM_SYSCALL (ans
= chdir (SCM_ROCHARS (str
)));
798 scm_syserror (s_chdir
);
800 return SCM_UNSPECIFIED
;
805 SCM_PROC (s_getcwd
, "getcwd", 0, 0, 0, scm_getcwd
);
813 scm_sizet size
= 100;
818 wd
= scm_must_malloc (size
, s_getcwd
);
819 while ((rv
= getcwd (wd
, size
)) == 0 && errno
== ERANGE
)
823 wd
= scm_must_malloc (size
, s_getcwd
);
826 scm_syserror (s_getcwd
);
827 result
= scm_makfromstr (wd
, strlen (wd
), 0);
832 scm_sysmissing (s_getcwd
);
842 set_element (SELECT_TYPE
*set
, SCM element
)
844 element
= SCM_COERCE_OUTPORT (element
);
845 if (SCM_NIMP (element
) && SCM_TYP16 (element
) == scm_tc16_fport
846 && SCM_OPPORTP (element
))
847 FD_SET (fileno ((FILE *) SCM_STREAM (element
)), set
);
848 else if (SCM_INUMP (element
))
849 FD_SET (SCM_INUM (element
), set
);
853 fill_select_type (SELECT_TYPE
*set
, SCM list
)
855 if (SCM_NIMP (list
) && SCM_VECTORP (list
))
857 int len
= SCM_LENGTH (list
);
858 SCM
*ve
= SCM_VELTS (list
);
862 set_element (set
, ve
[len
- 1]);
868 while (list
!= SCM_EOL
)
870 set_element (set
, SCM_CAR (list
));
871 list
= SCM_CDR (list
);
877 get_element (SELECT_TYPE
*set
, SCM element
, SCM list
)
879 element
= SCM_COERCE_OUTPORT (element
);
880 if (SCM_NIMP (element
)
881 && (scm_tc16_fport
== SCM_TYP16 (element
))
882 && SCM_OPPORTP (element
))
884 if (FD_ISSET (fileno ((FILE *)SCM_STREAM (element
)), set
))
885 list
= scm_cons (element
, list
);
887 else if (SCM_INUMP (element
))
889 if (FD_ISSET (SCM_INUM (element
), set
))
890 list
= scm_cons (element
, list
);
896 retrieve_select_type (SELECT_TYPE
*set
, SCM list
)
898 SCM answer_list
= SCM_EOL
;
900 if (SCM_NIMP (list
) && SCM_VECTORP (list
))
902 int len
= SCM_LENGTH (list
);
903 SCM
*ve
= SCM_VELTS (list
);
907 answer_list
= get_element (set
, ve
[len
- 1], answer_list
);
910 return scm_vector (answer_list
);
914 /* list is a list. */
915 while (list
!= SCM_EOL
)
917 answer_list
= get_element (set
, SCM_CAR (list
), answer_list
);
918 list
= SCM_CDR (list
);
925 SCM_PROC (s_select
, "select", 3, 2, 0, scm_select
);
928 scm_select (reads
, writes
, excepts
, secs
, usecs
)
936 struct timeval timeout
;
937 struct timeval
* time_p
;
938 SELECT_TYPE read_set
;
939 SELECT_TYPE write_set
;
940 SELECT_TYPE except_set
;
943 #define assert_set(x, arg) \
944 SCM_ASSERT (scm_ilength (x) > -1 || (SCM_NIMP (x) && SCM_VECTORP (x)), \
946 assert_set (reads
, SCM_ARG1
);
947 assert_set (writes
, SCM_ARG2
);
948 assert_set (excepts
, SCM_ARG3
);
952 FD_ZERO (&write_set
);
953 FD_ZERO (&except_set
);
955 fill_select_type (&read_set
, reads
);
956 fill_select_type (&write_set
, writes
);
957 fill_select_type (&except_set
, excepts
);
959 if (SCM_UNBNDP (secs
) || SCM_FALSEP (secs
))
963 if (SCM_INUMP (secs
))
965 timeout
.tv_sec
= SCM_INUM (secs
);
966 if (SCM_UNBNDP (usecs
))
970 SCM_ASSERT (SCM_INUMP (usecs
), usecs
, SCM_ARG5
, s_select
);
972 timeout
.tv_usec
= SCM_INUM (usecs
);
977 double fl
= scm_num2dbl (secs
, s_select
);
979 if (!SCM_UNBNDP (usecs
))
980 scm_wrong_type_arg (s_select
, 4, secs
);
982 scm_out_of_range (s_select
, secs
);
983 timeout
.tv_sec
= (long) fl
;
984 timeout
.tv_usec
= (long) ((fl
- timeout
.tv_sec
) * 1000000);
990 sreturn
= select (SELECT_SET_SIZE
,
991 &read_set
, &write_set
, &except_set
, time_p
);
993 scm_syserror (s_select
);
995 return scm_listify (retrieve_select_type (&read_set
, reads
),
996 retrieve_select_type (&write_set
, writes
),
997 retrieve_select_type (&except_set
, excepts
),
1000 scm_sysmissing (s_select
);
1006 /* Check if FILE has characters waiting to be read. */
1017 scm_input_waiting_p (f
, caller
)
1023 if (fileno (f
) == fileno (stdin
) && (isatty (fileno (stdin
))))
1036 # include <sys/io.h>
1040 # include <sys/ioctl.h>
1049 scm_input_waiting_p (f
, caller
)
1053 /* Can we return an end-of-file character? */
1057 /* Do we have characters in the stdio buffer? */
1058 # ifdef FILE_CNT_FIELD
1059 if (f
->FILE_CNT_FIELD
> 0)
1062 # ifdef FILE_CNT_GPTR
1063 if (f
->_gptr
!= f
->_egptr
)
1066 # ifdef FILE_CNT_READPTR
1067 if (f
->_IO_read_end
!= f
->_IO_read_ptr
)
1070 Configure
.in could
not guess the name of the correct field in a
FILE *.
1071 This function needs to be ported to your system
.
1072 It should
return zero iff no characters are waiting to be read
.;
1077 /* Is the file prepared to deliver input? */
1080 struct timeval timeout
;
1081 SELECT_TYPE read_set
;
1082 SELECT_TYPE write_set
;
1083 SELECT_TYPE except_set
;
1084 int fno
= fileno ((FILE *)f
);
1086 FD_ZERO (&read_set
);
1087 FD_ZERO (&write_set
);
1088 FD_ZERO (&except_set
);
1090 FD_SET (fno
, &read_set
);
1093 timeout
.tv_usec
= 0;
1096 if (select (SELECT_SET_SIZE
,
1097 &read_set
, &write_set
, &except_set
, &timeout
)
1099 scm_syserror (caller
);
1101 return FD_ISSET (fno
, &read_set
);
1107 ioctl(fileno(f
), FIONREAD
, &remir
);
1111 scm_misc_error ("char-ready?", "Not fully implemented on this platform",
1120 SCM_PROC (s_fcntl
, "fcntl", 2, 0, 1, scm_fcntl
);
1122 scm_fcntl (SCM object
, SCM cmd
, SCM value
)
1128 object
= SCM_COERCE_OUTPORT (object
);
1130 SCM_ASSERT (SCM_INUMP (cmd
), cmd
, SCM_ARG2
, s_fcntl
);
1131 if (SCM_NIMP (object
) && SCM_OPFPORTP (object
))
1132 fdes
= fileno ((FILE *) SCM_STREAM (object
));
1135 SCM_ASSERT (SCM_INUMP (object
), object
, SCM_ARG1
, s_fcntl
);
1136 fdes
= SCM_INUM (object
);
1138 if (SCM_NULLP (value
))
1142 SCM_ASSERT (SCM_INUMP (SCM_CAR (value
)), value
, SCM_ARG3
, s_fcntl
);
1143 ivalue
= SCM_INUM (SCM_CAR (value
));
1147 SCM_SYSCALL (rv
= fcntl (fdes
, SCM_INUM (cmd
), ivalue
));
1149 rv
= 0; /* avoid compiler warning. */
1150 if (rv
== -1 || fdes
== -1)
1151 scm_syserror (s_fcntl
);
1153 return SCM_MAKINUM (rv
);
1156 SCM_PROC (s_fsync
, "fsync", 1, 0, 0, scm_fsync
);
1158 scm_fsync (SCM object
)
1162 object
= SCM_COERCE_OUTPORT (object
);
1165 if (SCM_NIMP (object
) && SCM_OPFPORTP (object
))
1167 scm_force_output (object
);
1168 fdes
= fileno ((FILE *) SCM_STREAM (object
));
1170 scm_syserror (s_fsync
);
1174 SCM_ASSERT (SCM_INUMP (object
), object
, SCM_ARG1
, s_fsync
);
1175 fdes
= SCM_INUM (object
);
1177 if (fsync (fdes
) == -1)
1178 scm_syserror (s_fsync
);
1180 return SCM_UNSPECIFIED
;
1183 SCM_PROC (s_symlink
, "symlink", 2, 0, 0, scm_symlink
);
1186 scm_symlink(oldpath
, newpath
)
1193 SCM_ASSERT (SCM_NIMP (oldpath
) && SCM_ROSTRINGP (oldpath
), oldpath
, SCM_ARG1
,
1195 SCM_ASSERT (SCM_NIMP (newpath
) && SCM_ROSTRINGP (newpath
), newpath
, SCM_ARG2
,
1197 SCM_COERCE_SUBSTR (oldpath
);
1198 SCM_COERCE_SUBSTR (newpath
);
1200 SCM_SYSCALL (val
= symlink(SCM_ROCHARS(oldpath
), SCM_ROCHARS(newpath
)));
1202 scm_syserror (s_symlink
);
1204 return SCM_UNSPECIFIED
;
1206 scm_sysmissing (s_symlink
);
1213 SCM_PROC (s_readlink
, "readlink", 1, 0, 0, scm_readlink
);
1219 #ifdef HAVE_READLINK
1221 scm_sizet size
= 100;
1224 SCM_ASSERT (SCM_NIMP (path
) && SCM_ROSTRINGP (path
), path
, (char *) SCM_ARG1
,
1226 SCM_COERCE_SUBSTR (path
);
1228 buf
= scm_must_malloc (size
, s_readlink
);
1229 while ((rv
= readlink (SCM_ROCHARS (path
), buf
, (scm_sizet
) size
)) == size
)
1231 scm_must_free (buf
);
1233 buf
= scm_must_malloc (size
, s_readlink
);
1236 scm_syserror (s_readlink
);
1237 result
= scm_makfromstr (buf
, rv
, 0);
1238 scm_must_free (buf
);
1242 scm_sysmissing (s_readlink
);
1249 SCM_PROC (s_lstat
, "lstat", 1, 0, 0, scm_lstat
);
1257 struct stat stat_temp
;
1259 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
), str
, (char *) SCM_ARG1
,
1261 SCM_COERCE_SUBSTR (str
);
1263 SCM_SYSCALL(rv
= lstat(SCM_ROCHARS(str
), &stat_temp
));
1268 scm_syserror_msg (s_lstat
, "%s: %S",
1269 scm_listify (scm_makfrom0str (strerror (errno
)),
1275 return scm_stat2scm(&stat_temp
);
1277 scm_sysmissing (s_lstat
);
1284 SCM_PROC (s_copy_file
, "copy-file", 2, 0, 0, scm_copy_file
);
1287 scm_copy_file (oldfile
, newfile
)
1293 char buf
[BUFSIZ
]; /* this space could be shared. */
1294 struct stat oldstat
;
1296 SCM_ASSERT (SCM_NIMP (oldfile
) && SCM_ROSTRINGP (oldfile
), oldfile
, SCM_ARG1
, s_copy_file
);
1297 if (SCM_SUBSTRP (oldfile
))
1298 oldfile
= scm_makfromstr (SCM_ROCHARS (oldfile
), SCM_ROLENGTH (oldfile
), 0);
1299 SCM_ASSERT (SCM_NIMP (newfile
) && SCM_ROSTRINGP (newfile
), newfile
, SCM_ARG2
, s_copy_file
);
1300 if (SCM_SUBSTRP (newfile
))
1301 newfile
= scm_makfromstr (SCM_ROCHARS (newfile
), SCM_ROLENGTH (newfile
), 0);
1302 if (stat (SCM_ROCHARS (oldfile
), &oldstat
) == -1)
1303 scm_syserror (s_copy_file
);
1305 oldfd
= open (SCM_ROCHARS (oldfile
), O_RDONLY
);
1307 scm_syserror (s_copy_file
);
1309 /* use POSIX flags instead of 07777?. */
1310 newfd
= open (SCM_ROCHARS (newfile
), O_WRONLY
| O_CREAT
| O_TRUNC
,
1311 oldstat
.st_mode
& 07777);
1313 scm_syserror (s_copy_file
);
1315 while ((n
= read (oldfd
, buf
, sizeof buf
)) > 0)
1316 if (write (newfd
, buf
, n
) != n
)
1320 scm_syserror (s_copy_file
);
1323 if (close (newfd
) == -1)
1324 scm_syserror (s_copy_file
);
1326 return SCM_UNSPECIFIED
;
1334 scm_add_feature ("i/o-extensions");
1336 scm_tc16_dir
= scm_newsmob (&dir_smob
);
1339 scm_sysintern ("O_RDONLY", scm_long2num (O_RDONLY
));
1342 scm_sysintern ("O_WRONLY", scm_long2num (O_WRONLY
));
1345 scm_sysintern ("O_RDWR", scm_long2num (O_RDWR
));
1348 scm_sysintern ("O_CREAT", scm_long2num (O_CREAT
));
1351 scm_sysintern ("O_EXCL", scm_long2num (O_EXCL
));
1354 scm_sysintern ("O_NOCTTY", scm_long2num (O_NOCTTY
));
1357 scm_sysintern ("O_TRUNC", scm_long2num (O_TRUNC
));
1360 scm_sysintern ("O_APPEND", scm_long2num (O_APPEND
));
1363 scm_sysintern ("O_NONBLOCK", scm_long2num (O_NONBLOCK
));
1366 scm_sysintern ("O_NDELAY", scm_long2num (O_NDELAY
));
1369 scm_sysintern ("O_SYNC", scm_long2num (O_SYNC
));
1373 scm_sysintern ("F_DUPFD", scm_long2num (F_DUPFD
));
1376 scm_sysintern ("F_GETFD", scm_long2num (F_GETFD
));
1379 scm_sysintern ("F_SETFD", scm_long2num (F_SETFD
));
1382 scm_sysintern ("F_GETFL", scm_long2num (F_GETFL
));
1385 scm_sysintern ("F_SETFL", scm_long2num (F_SETFL
));
1388 scm_sysintern ("F_GETOWN", scm_long2num (F_GETOWN
));
1391 scm_sysintern ("F_SETOWN", scm_long2num (F_SETOWN
));
1394 scm_sysintern ("FD_CLOEXEC", scm_long2num (FD_CLOEXEC
));
1397 #include "filesys.x"