diff options
author | Kaz Kyheku <kaz@kylheku.com> | 2020-01-15 20:07:06 -0800 |
---|---|---|
committer | Kaz Kyheku <kaz@kylheku.com> | 2020-01-15 20:07:06 -0800 |
commit | 267802c97c4a19354647eb96893429d5c67214df (patch) | |
tree | d326a40f3c5133de1c46e7e3489b65b80189a83a /sysif.c | |
parent | f76995965d0d8c5cff6885ff305c4f8b0cec524e (diff) | |
download | txr-267802c97c4a19354647eb96893429d5c67214df.tar.gz txr-267802c97c4a19354647eb96893429d5c67214df.tar.bz2 txr-267802c97c4a19354647eb96893429d5c67214df.zip |
chmod: work on streams and descriptors using fchmod.
* configure: extend chmod detection to cover fchmod.
* sysif.c (get_fd): New static functions.
(chmod_wrap): Include fchmod wrapping for integer
or stream argument.
(sysif_init): Register fchmod intrinsic.
Diffstat (limited to 'sysif.c')
-rw-r--r-- | sysif.c | 37 |
1 files changed, 31 insertions, 6 deletions
@@ -451,17 +451,42 @@ static val mknod_wrap(val path, val mode, val dev) #if HAVE_CHMOD -static val chmod_wrap(val path, val mode) +static int get_fd(val stream, val self) { + val fd_in = if3(integerp(stream), stream, stream_get_prop(stream, fd_k)); + + if (stream && !fd_in) + uw_throwf(file_error_s, + lit("~a: stream ~s has no :fd property"), + self, stream, nao); + + if (!stream) + uw_throwf(file_error_s, + lit("~a: ~s isn't a stream object"), + self, stream, nao); + + return c_int(fd_in, self); +} + +static val chmod_wrap(val target, val mode) +{ + val self = lit("chmod"); cnum cmode = c_num(mode); - char *u8path = utf8_dup_to(c_str(path)); - int err = chmod(u8path, cmode); - free(u8path); + int err; + + if (stringp(target)) { + char *u8path = utf8_dup_to(c_str(target)); + err = chmod(u8path, cmode); + free(u8path); + } else { + int fd = get_fd(target, self); + err = fchmod(fd, cmode); + } if (err < 0) { int eno = errno; - uw_throwf(errno_to_file_error(eno), lit("chmod ~a #o~o: ~d/~s"), - path, mode, num(eno), string_utf8(strerror(eno)), nao); + uw_throwf(errno_to_file_error(eno), lit("~a ~a #o~o: ~d/~s"), + self, target, mode, num(eno), string_utf8(strerror(eno)), nao); } return t; |