From 239396557cd0f428ef803bb034ed1ec4db0cf887 Mon Sep 17 00:00:00 2001 From: Maxime Devos Date: Fri, 12 Mar 2021 22:36:22 +0100 Subject: [PATCH 16/17] =?UTF-8?q?Define=20a=20Scheme=20binding=20to=20?= =?UTF-8?q?=E2=80=98mknodat=E2=80=99=20when=20supported.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * configure.ac: Detect if ‘mknodat’ exists. * libguile/posix.texi (mknod, symbol_to_numeric_type): Split off common code with ‘mknodat’. (mknodat): Define the new Scheme binding. * libguile/posix.h (scm_mknodat): Make it part of the C API. * doc/ref/posix.texi (File System): Document it. --- configure.ac | 2 +- doc/ref/posix.texi | 6 ++++ libguile/posix.c | 88 +++++++++++++++++++++++++++++++++------------- libguile/posix.h | 1 + 4 files changed, 72 insertions(+), 25 deletions(-) diff --git a/configure.ac b/configure.ac index 10320ce98..d5a8208f8 100644 --- a/configure.ac +++ b/configure.ac @@ -483,7 +483,7 @@ AC_CHECK_HEADERS([assert.h crt_externs.h]) AC_CHECK_FUNCS([DINFINITY DQNAN cexp chsize clog clog10 ctermid \ fesetround ftime ftruncate fchown fchmod fchdir readlinkat linkat \ symlinkat mkdirat renameat fchmodat unlinkat fchownat fstatat openat \ - getcwd geteuid getsid \ + mknodat getcwd geteuid getsid \ gettimeofday getuid getgid gmtime_r ioctl lstat mkdir mkdtemp mknod \ nice readlink rename rmdir setegid seteuid \ setlocale setuid setgid setpgid setsid sigaction siginterrupt stat64 \ diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi index dbbf8cc7a..5844e271c 100644 --- a/doc/ref/posix.texi +++ b/doc/ref/posix.texi @@ -1110,6 +1110,12 @@ E.g., The return value is unspecified. @end deffn +@deffn {Scheme Procedure} mknodat dir path type perms dev +@deffnx {C Fuction} scm_mknodat (dir, path, type, perms, dev) +Similar to @code{mknod}, but resolve @var{path} relative to +@var{dir} instead. +@end deffn + @deffn {Scheme Procedure} tmpnam @deffnx {C Function} scm_tmpnam () @cindex temporary file diff --git a/libguile/posix.c b/libguile/posix.c index 2ee459d2d..a74f87215 100644 --- a/libguile/posix.c +++ b/libguile/posix.c @@ -1854,6 +1854,38 @@ SCM_DEFINE (scm_setlocale, "setlocale", 1, 1, 0, #undef FUNC_NAME #endif /* HAVE_SETLOCALE */ +#if defined(HAVE_MKNOD) || defined(HAVE_MKNODAT) +/* Static helper function for converting symbols to their + corresponding S_* constants */ +static int +symbol_to_numeric_type (const char *FUNC_NAME, int position, SCM type) +{ + const char *p; + p = scm_i_symbol_chars (type); + if (strcmp (p, "regular") == 0) + return S_IFREG; + else if (strcmp (p, "directory") == 0) + return S_IFDIR; +#ifdef S_IFLNK + /* systems without symlinks probably don't have S_IFLNK defined */ + else if (strcmp (p, "symlink") == 0) + return S_IFLNK; +#endif + else if (strcmp (p, "block-special") == 0) + return S_IFBLK; + else if (strcmp (p, "char-special") == 0) + return S_IFCHR; + else if (strcmp (p, "fifo") == 0) + return S_IFIFO; +#ifdef S_IFSOCK + else if (strcmp (p, "socket") == 0) + return S_IFSOCK; +#endif + else + SCM_OUT_OF_RANGE (position, type); +} +#endif + #ifdef HAVE_MKNOD SCM_DEFINE (scm_mknod, "mknod", 4, 0, 0, (SCM path, SCM type, SCM perms, SCM dev), @@ -1873,34 +1905,12 @@ SCM_DEFINE (scm_mknod, "mknod", 4, 0, 0, #define FUNC_NAME s_scm_mknod { int val; - const char *p; - int ctype = 0; + int ctype; SCM_VALIDATE_STRING (1, path); SCM_VALIDATE_SYMBOL (2, type); - p = scm_i_symbol_chars (type); - if (strcmp (p, "regular") == 0) - ctype = S_IFREG; - else if (strcmp (p, "directory") == 0) - ctype = S_IFDIR; -#ifdef S_IFLNK - /* systems without symlinks probably don't have S_IFLNK defined */ - else if (strcmp (p, "symlink") == 0) - ctype = S_IFLNK; -#endif - else if (strcmp (p, "block-special") == 0) - ctype = S_IFBLK; - else if (strcmp (p, "char-special") == 0) - ctype = S_IFCHR; - else if (strcmp (p, "fifo") == 0) - ctype = S_IFIFO; -#ifdef S_IFSOCK - else if (strcmp (p, "socket") == 0) - ctype = S_IFSOCK; -#endif - else - SCM_OUT_OF_RANGE (2, type); + ctype = symbol_to_numeric_type (FUNC_NAME, SCM_ARG2, type); STRING_SYSCALL (path, c_path, val = mknod (c_path, @@ -1913,6 +1923,36 @@ SCM_DEFINE (scm_mknod, "mknod", 4, 0, 0, #undef FUNC_NAME #endif /* HAVE_MKNOD */ +#ifdef HAVE_MKNODAT +SCM_DEFINE (scm_mknodat, "mknodat", 5, 0, 0, + (SCM dir, SCM path, SCM type, SCM perms, SCM dev), + "Similar to @code{mknod}, but resolve @var{path} relative to\n" + "@var{dir} instead.") +#define FUNC_NAME s_scm_mknodat +{ + int val; + int ctype; + int dir_fdes; + + SCM_VALIDATE_STRING (2, path); + SCM_VALIDATE_SYMBOL (3, type); + SCM_VALIDATE_OPFPORT (1, dir); + + dir_fdes = SCM_FPORT_FDES (dir); + ctype = symbol_to_numeric_type (FUNC_NAME, SCM_ARG3, type); + + STRING_SYSCALL (path, c_path, + val = mknodat (dir_fdes, c_path, + ctype | scm_to_int (perms), + scm_to_int (dev))); + scm_remember_upto_here_1 (dir); + if (val != 0) + SCM_SYSERROR; + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME +#endif /* HAVE_MKNODAT */ + #ifdef HAVE_NICE SCM_DEFINE (scm_nice, "nice", 1, 0, 0, (SCM incr), diff --git a/libguile/posix.h b/libguile/posix.h index ff3bec9ea..da82ae8eb 100644 --- a/libguile/posix.h +++ b/libguile/posix.h @@ -76,6 +76,7 @@ SCM_API SCM scm_getpid (void); SCM_API SCM scm_putenv (SCM str); SCM_API SCM scm_setlocale (SCM category, SCM locale); SCM_API SCM scm_mknod (SCM path, SCM type, SCM perms, SCM dev); +SCM_API SCM scm_mknodat (SCM dir, SCM path, SCM type, SCM perms, SCM dev); SCM_API SCM scm_nice (SCM incr); SCM_API SCM scm_sync (void); SCM_API SCM scm_crypt (SCM key, SCM salt); -- 2.30.2