Scheme 48 Manual | Contents | In Chapter: Access to POSIX
Previous: Files and directories | Next: Files and directories

## Files and directories

These procedures are in structures `posix-files` and `posix`.

### Directory streams

Directory streams are like input ports, with each read operation returning the next name in the directory.

- `(open-directory-stream name) -> directory`
- `(directory-stream? x) -> boolean`
- `(read-directory-stream directory) -> name or `#f``
- `(close-directory-stream directory)`

`Open-directory-stream` opens a new directory stream. `Directory-stream?` is a predicate that recognizes directory streams. `Read-directory-stream` returns the next name in the directory or `#f` if all names have been read. `Close-directory-stream` closes a directory stream.

- `(list-directory name) -> list of strings`

This is the obvious utility; it returns a list of the names in directory `name`.

### Working directory

- `(working-directory) -> string`
- `(set-working-directory! string)`

These return and set the working directory.

### File creation and removal

- `(open-file path file-options) -> port`
- `(open-file path file-options file-mode) -> port`

`Open-file` opens a port to the file named by string `path`. The `file-options` argument determines various aspects of the returned port. The optional `file-mode` argument is used only if the file to be opened does not already exist. The returned port is an input port if `file-options` includes `read-only`; otherwise it returns an output port. `Dup-switching-mode` can be used to open an input port for output ports opened with the `read/write` option.

- `(file-options `file-option-name` ...) -> file-options` | syntax

- `(file-options-on? file-options file-options) -> boolean`

The syntax `file-options` returns a file-option with the indicated options set. `File-options-on?` returns true if its first argument includes all of the options listed in the second argument. The following file options may be used with `open-file`.

> | `create` | create file if it does not already exist; a file-mode argument is required with this option
> | `exclusive` | an error will be raised if this option and `create` are both set and the file already exists
> | `no-controlling-tty` | if `path` is a terminal device this option causes the terminal to not become the controlling terminal of the process
> | `truncate` | file is truncated
> | `append` | writes are appended to existing contents
> | `nonblocking` | read and write operations do not block
> | `read-only` | port may not be written
> | `read-write` | file descriptor may be read or written
> | `write-only` | port may not be read

Only one of the last three options may be used.

For example

>     (open-file "some-file.txt"
>                (file-options create write-only)
>                (file-mode read owner-write))

returns an output port that writes to a newly-created file that can be read by anyone and written only by the owner. Once the file exists,

>     (open-file "some-file.txt"
>                (file-options append write-only))

will open an output port that appends to the file.

The `append` and `nonblocking` options and the read/write nature of the port can be read using `i/o-flags`. The `append` and `nonblocking` options can be set using `set-i/o-flags!`.

To keep port operations from blocking the Scheme 48 process, output ports are set to be nonblocking at the time of creation (input ports are managed using `select()`). You can use `set-i/o-flags!` to make an output port blocking, for example just before a fork, but care should be exercised. The Scheme 48 runtime code may get confused if an I/O operation blocks.

- `(set-file-creation-mask! file-mode)`

Sets the file creation mask to be `file-mode`. Bits set in `file-mode` are cleared in the modes of any files or directories created by the current process.

- `(link existing new)`

`Link` makes path `new` be a new link to the file pointed to by path `existing`. The two paths must be in the same file system.

- `(make-directory name file-mode)`
- `(make-fifo file-mode)`

These two procedures make new directories and fifo files.

- `(unlink path)`
- `(remove-directory path)`
- `(rename old-path new-path)`

`Unlink` removes the link indicated by `path`. `Remove-directory` removes the indicated (empty) directory. `Rename` moves the file pointed to by `old-path` to the location pointed to by `new-path` (the two paths must be in the same file system). Any other links to the file remain unchanged.

- `(accessible? path access-mode . more-modes) -> boolean`

- `(access-mode `mode-name`) -> access-mode` | syntax

`Accessible?` returns true if `path` is a file that can be accessed in the listed mode. If more than one mode is specified `accessible?` returns true if all of the specified modes are permitted. The `mode-name`s are: `read`, `write`, `execute`, `exists`.

### File information

- `(get-file-info name) -> file-info`
- `(get-file/link-info name) -> file-info`
- `(get-port-info fd-port) -> file-info`

`Get-file-info` and `get-file/link-info` both return a file info record for the named file. `Get-file-info` follows symbolic links while `get-file/link-info` does not. `Get-port-info` returns a file info record for the file which `port` reads from or writes to. An error is raised if `fd-port` does not read from or write to a file descriptor.

- `(file-info? x) -> boolean`
- `(file-info-name file-info) -> string`

`File-info?` is a predicate for file-info records. `File-info-name` is the name which was used to get `file-info`, either as passed to `get-file-info` or `get-file/link-info`, or used to open the port passed to `get-port-info`.

- `(file-info-type file-info) -> file-type`
- `(file-type? x) -> boolean`
- `(file-type-name file-type) -> symbol`

- `(file-type `type`) -> file-type` | syntax

`File-info-type` returns the type of the file, as a file-type object File types may be compared using `eq?`. The valid file types are:

> `regular`
> `directory`
> `character-device`
> `block-device`
> `fifo`
> `symbolic-link`
> `socket`
> `other`

`Symbolic-link` and `socket` are not required by POSIX.

- `(file-info-device file-info) -> integer`
- `(file-info-inode file-info) -> integer`

The device and inode numbers uniquely determine a file.

- `(file-info-link-count file-info) -> integer`
- `(file-info-size file-info) -> integer`

These return the number of links to a file and the file size in bytes. The size is only meaningful for regular files.

- `(file-info-owner file-info) -> user-id`
- `(file-info-group file-info) -> group-id`
- `(file-info-mode file-info) -> file-mode`

These return the owner, group, and access mode of a file.

- `(file-info-last-access file-info) -> time`
- `(file-info-last-modification file-info) -> time`
- `(file-info-last-info-change file-info) -> time`

These return the time the file was last read, modified, or had its status modified

### File modes

A file mode is a boxed integer representing a file protection mask.

- `(file-mode permission-name ...) -> file-mode` | syntax

- `(file-mode? x) -> boolean`
- `(file-mode+ file-mode ...) -> file-mode`
- `(file-mode- file-mode0 file-mode1) -> file-mode`

`File-mode` is syntax for creating file modes. The mode-names are listed below. `File-mode?` is a predicate for file modes. `File-mode+` returns a mode that contains all of permissions of its arguments. `File-mode-` returns a mode that has all of the permissions of `file-mode0` that are not in `file-mode1`.

- `(file-mode=? file-mode0 file-mode1) -> boolean`
- `(file-mode<=? file-mode0 file-mode1) -> boolean`
- `(file-mode>=? file-mode0 file-mode1) -> boolean`

`File-mode=?` returns true if the two modes are exactly the same. `File-mode<=?` returns true if `file-mode0` has a subset of the permissions of `file-mode1`. `File-mode>=?` is `file-mode<=?` with the arguments reversed.

- `(file-mode->integer file-mode) -> integer`
- `(integer->file-mode integer) -> file-mode`

`Integer->file-mode` and `file-mode->integer` translate file modes to and from the classic Unix file mode masks. These may not be the masks used by the underlying OS.

> Permission name | Bit mask
> `set-uid` | `#o4000` | set user id when executing
> `set-gid` | `#o2000` | set group id when executing
> `owner-read` | `#o0400` | read by owner
> `owner-write` | `#o0200` | write by owner
> `owner-exec` | `#o0100` | execute (or search) by owner
> `group-read` | `#o0040` | read by group
> `group-write` | `#o0020` | write by group
> `group-exec` | `#o0010` | execute (or search) by group
> `other-read` | `#o0004` | read by others
> `other-write` | `#o0002` | write by others
> `other-exec` | `#o0001` | execute (or search) by others

> Names for sets of permissions
> `owner` | `#o0700` | read, write, and execute by owner
> `group` | `#o0070` | read, write, and execute by group
> `other` | `#o0007` | read, write, and execute by others
> `read` | `#o0444` | read by anyone
> `write` | `#o0222` | write by anyone
> `exec` | `#o0111` | execute by anyone
> `all` | `#o0777` | anything by anyone

Previous: Files and directories | Next: Files and directories