From 43590a698cd27d6360caeed761dbad695b00f2c7 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 12 Sep 2023 23:53:38 -0700 Subject: chdir: support stream and fd argument via fchdir. * configure: new test for fchdir resulting in HAVE_FCHDIR. * sysif.c (get_fd): Define for HAVE_FCHDIR also. (chdir_wrap): If HAVE_FCHDIR, handle non-string arguments via fchdir, with help of get_fd. * txr.1: Documented. --- configure | 16 ++++++++++++++++ sysif.c | 18 ++++++++++++++---- txr.1 | 21 +++++++++++++++++---- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 720bcd77..51f7723c 100755 --- a/configure +++ b/configure @@ -2860,6 +2860,22 @@ else printf "no\n" fi +printf "Checking for fchdir ... " +cat > conftest.c < + +int main(void) +{ + int e = fchdir(1); + return 0; +} +! +if conftest ; then + printf "yes\n" + printf "#define HAVE_FCHDIR 1\n" >> config.h +else + printf "no\n" +fi printf "Checking for log2 ... " diff --git a/sysif.c b/sysif.c index 3b48af0b..e8fa1dac 100644 --- a/sysif.c +++ b/sysif.c @@ -452,7 +452,7 @@ static val mkdir_wrap(val path, val mode) } #endif -#if HAVE_CHMOD || HAVE_CHOWN || HAVE_SYS_STAT || HAVE_FILE_STAMP_CHANGE +#if HAVE_CHMOD || HAVE_CHOWN || HAVE_FCHDIR || HAVE_SYS_STAT || HAVE_FILE_STAMP_CHANGE static int get_fd(val stream, val self) { val fd_in = if3(integerp(stream), stream, stream_fd(stream)); @@ -576,9 +576,19 @@ static val ensure_dir(val path, val mode) static val chdir_wrap(val path) { val self = lit("chdir"); - char *u8path = utf8_dup_to(c_str(path, self)); - int err = chdir(u8path); - free(u8path); + int err; + +#if HAVE_FCHDIR + if (!stringp(path)) { + int fd = get_fd(path, self); + err = fchdir(fd); + } else +#endif + { + char *u8path = utf8_dup_to(c_str(path, self)); + err = chdir(u8path); + free(u8path); + } if (err < 0) { int eno = errno; diff --git a/txr.1 b/txr.1 index 83b82a28..dde521b6 100644 --- a/txr.1 +++ b/txr.1 @@ -72513,17 +72513,30 @@ instead of .coNP Function @ chdir .synb -.mets (chdir << path ) +.mets (chdir >> { path | < stream | << fd }) .syne .desc .code chdir -changes the current working directory to -.metn path , -and returns +changes the current working directory to the object specified +by the argument, and returns .metn t , or else throws an exception of type .codn file-error . +If the argument is a string, it is interpreted as a +.metn path , +in which case the POSIX +.code chdir +function is used. If the argument is a +.meta stream +then an integer file descriptor is retrieved from that stream using the +.code fileno +function. That descriptor can be specified directly as a +.meta fd +argument. In the case of these these two argument types, the +.code fchdir +function is used. + .coNP Function @ pwd .synb .mets (pwd) -- cgit v1.2.3