summaryrefslogtreecommitdiff
path: root/sysdeps/mach
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mach')
-rw-r--r--sysdeps/mach/hurd/faccessat.c70
-rw-r--r--sysdeps/mach/hurd/fchmodat.c44
-rw-r--r--sysdeps/mach/hurd/fchownat.c46
-rw-r--r--sysdeps/mach/hurd/fxstatat.c33
-rw-r--r--sysdeps/mach/hurd/fxstatat64.c46
-rw-r--r--sysdeps/mach/hurd/linkat.c66
-rw-r--r--sysdeps/mach/hurd/mkdirat.c42
-rw-r--r--sysdeps/mach/hurd/open.c8
-rw-r--r--sysdeps/mach/hurd/open64.c1
-rw-r--r--sysdeps/mach/hurd/openat.c62
-rw-r--r--sysdeps/mach/hurd/openat64.c1
-rw-r--r--sysdeps/mach/hurd/symlinkat.c74
-rw-r--r--sysdeps/mach/hurd/unlinkat.c55
-rw-r--r--sysdeps/mach/hurd/xmknod.c90
-rw-r--r--sysdeps/mach/hurd/xmknodat.c118
15 files changed, 669 insertions, 87 deletions
diff --git a/sysdeps/mach/hurd/faccessat.c b/sysdeps/mach/hurd/faccessat.c
new file mode 100644
index 0000000000..bb3c9fe19f
--- /dev/null
+++ b/sysdeps/mach/hurd/faccessat.c
@@ -0,0 +1,70 @@
+/* Test for access to file, relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+int
+faccessat (fd, file, type, flag)
+ int fd;
+ const char *file;
+ int type;
+ int flag;
+{
+ error_t err;
+ file_t port;
+ int allowed, flags;
+
+ if ((flag & AT_EACCESS) == 0)
+ {
+ if (fd == AT_FDCWD || file[0] == '/')
+ return __access (file, type);
+ __set_errno (ENOTSUP); /* XXX later */
+ return -1;
+ }
+
+ port = __file_name_lookup_at (fd, flag &~ AT_EACCESS, file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ /* Find out what types of access we are allowed to this file. */
+ err = __file_check_access (port, &allowed);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+
+ flags = 0;
+ if (type & R_OK)
+ flags |= O_READ;
+ if (type & W_OK)
+ flags |= O_WRITE;
+ if (type & X_OK)
+ flags |= O_EXEC;
+
+ if (flags & ~allowed)
+ /* We are not allowed all the requested types of access. */
+ return __hurd_fail (EACCES);
+
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/fchmodat.c b/sysdeps/mach/hurd/fchmodat.c
new file mode 100644
index 0000000000..d27e845274
--- /dev/null
+++ b/sysdeps/mach/hurd/fchmodat.c
@@ -0,0 +1,44 @@
+/* Change the protections of file relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+int
+fchmodat (fd, file, mode, flag)
+ int fd;
+ const char *file;
+ mode_t mode;
+ int flag;
+{
+ error_t err;
+ file_t port = __file_name_lookup_at (fd, flag, file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_chmod (port, mode);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/fchownat.c b/sysdeps/mach/hurd/fchownat.c
new file mode 100644
index 0000000000..1b99b29272
--- /dev/null
+++ b/sysdeps/mach/hurd/fchownat.c
@@ -0,0 +1,46 @@
+/* Change owner and group of a file relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the owner and group of FILE. */
+int
+fchownat (fd, file, owner, group, flag)
+ int fd;
+ const char *file;
+ uid_t owner;
+ gid_t group;
+ int flag;
+{
+ error_t err;
+ file_t port = __file_name_lookup_at (fd, flag, file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_chown (port, owner, group);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/fxstatat.c b/sysdeps/mach/hurd/fxstatat.c
new file mode 100644
index 0000000000..dd9d2796eb
--- /dev/null
+++ b/sysdeps/mach/hurd/fxstatat.c
@@ -0,0 +1,33 @@
+/* Get information about file named relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include "xstatconv.c"
+
+int
+__fxstatat (int vers, int fd, const char *filename, struct stat *buf, int flag)
+{
+ struct stat64 buf64;
+ return (__fxstatat64 (vers, fd, filename, &buf64, flag)
+ ?: xstat64_conv (buf, &buf64));
+}
+libc_hidden_def (__fxstatat)
diff --git a/sysdeps/mach/hurd/fxstatat64.c b/sysdeps/mach/hurd/fxstatat64.c
new file mode 100644
index 0000000000..6862e80d52
--- /dev/null
+++ b/sysdeps/mach/hurd/fxstatat64.c
@@ -0,0 +1,46 @@
+/* Get information about file named relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__fxstatat64 (int vers, int fd, const char *filename, struct stat64 *buf,
+ int flag)
+{
+ error_t err;
+ io_t port;
+
+ if (vers != _STAT_VER)
+ return __hurd_fail (EINVAL);
+
+ port = __file_name_lookup_at (fd, flag, filename, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ err = __io_stat (port, buf);
+ __mach_port_deallocate (__mach_task_self (), port);
+
+ return __hurd_fail (err);
+}
diff --git a/sysdeps/mach/hurd/linkat.c b/sysdeps/mach/hurd/linkat.c
new file mode 100644
index 0000000000..1942144e0f
--- /dev/null
+++ b/sysdeps/mach/hurd/linkat.c
@@ -0,0 +1,66 @@
+/* Make a link between file names relative to open directories. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+
+/* Make a link to FROM relative to FROMFD called TO relative to TOFD. */
+int
+linkat (fromfd, from, tofd, to, flags)
+ int fromfd;
+ const char *from;
+ int tofd;
+ const char *to;
+ int flags;
+{
+ error_t err;
+ file_t oldfile, linknode, todir;
+ char *toname;
+
+ oldfile = __file_name_lookup_at (fromfd, flags, from, 0, 0);
+ if (oldfile == MACH_PORT_NULL)
+ return -1;
+
+ /* The file_getlinknode RPC returns the port that should be passed to
+ the receiving filesystem (the one containing TODIR) in dir_link. */
+
+ err = __file_getlinknode (oldfile, &linknode);
+ __mach_port_deallocate (__mach_task_self (), oldfile);
+ if (err)
+ return __hurd_fail (err);
+
+ todir = __file_name_split_at (tofd, to, &toname);
+ if (todir != MACH_PORT_NULL)
+ {
+ err = __dir_link (todir, linknode, toname, 1);
+ __mach_port_deallocate (__mach_task_self (), todir);
+ }
+ __mach_port_deallocate (__mach_task_self (), linknode);
+ if (todir == MACH_PORT_NULL)
+ return -1;
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/mkdirat.c b/sysdeps/mach/hurd/mkdirat.c
new file mode 100644
index 0000000000..321d59f2fd
--- /dev/null
+++ b/sysdeps/mach/hurd/mkdirat.c
@@ -0,0 +1,42 @@
+/* Create a directory named relative to another open directory. Hurd version.
+ Copyright (C) 1991,1993,1994,1995,1996,1997,2002,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+int
+mkdirat (fd, path, mode)
+ int fd;
+ const char *path;
+ mode_t mode;
+{
+ error_t err;
+ const char *name;
+ file_t parent = __directory_name_split (path, (char **) &name);
+ if (parent == MACH_PORT_NULL)
+ return -1;
+ err = __dir_mkdir (parent, name, mode & ~_hurd_umask);
+ __mach_port_deallocate (__mach_task_self (), parent);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/open.c b/sysdeps/mach/hurd/open.c
index dd575a47b1..bdfed5e311 100644
--- a/sysdeps/mach/hurd/open.c
+++ b/sysdeps/mach/hurd/open.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,93,94,95,97,2000,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1992,93,94,95,97,2000,2002,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -51,3 +51,9 @@ libc_hidden_def (__libc_open)
weak_alias (__libc_open, __open)
libc_hidden_weak (__open)
weak_alias (__libc_open, open)
+
+/* open64 is just the same as open for us. */
+weak_alias (__libc_open, __libc_open64)
+weak_alias (__libc_open, __open64)
+libc_hidden_weak (_open64)
+weak_alias (__libc_open, open64)
diff --git a/sysdeps/mach/hurd/open64.c b/sysdeps/mach/hurd/open64.c
new file mode 100644
index 0000000000..018ac94f28
--- /dev/null
+++ b/sysdeps/mach/hurd/open64.c
@@ -0,0 +1 @@
+/* open64 is defined in open.c as an alias. */
diff --git a/sysdeps/mach/hurd/openat.c b/sysdeps/mach/hurd/openat.c
new file mode 100644
index 0000000000..1faf857e16
--- /dev/null
+++ b/sysdeps/mach/hurd/openat.c
@@ -0,0 +1,62 @@
+/* openat -- Open a file named relative to an open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Open FILE with access OFLAG. Interpret relative paths relative to
+ the directory associated with FD. If OFLAG includes O_CREAT, a
+ third argument is the file protection. */
+int
+__openat (fd, file, oflag)
+ int fd;
+ const char *file;
+ int oflag;
+{
+ int mode;
+ io_t port;
+
+ if (oflag & O_CREAT)
+ {
+ va_list arg;
+ va_start (arg, oflag);
+ mode = va_arg (arg, int);
+ va_end (arg);
+ }
+ else
+ mode = 0;
+
+ port = __file_name_lookup_at (fd, 0, file, oflag, mode);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ return _hurd_intern_fd (port, oflag, 1);
+}
+libc_hidden_def (__openat)
+weak_alias (__openat, openat)
+
+/* openat64 is just the same as openat for us. */
+weak_alias (__openat, __openat64)
+libc_hidden_weak (__openat64)
+weak_alias (__openat, openat64)
diff --git a/sysdeps/mach/hurd/openat64.c b/sysdeps/mach/hurd/openat64.c
new file mode 100644
index 0000000000..15d9d6a183
--- /dev/null
+++ b/sysdeps/mach/hurd/openat64.c
@@ -0,0 +1 @@
+/* openat64 is defined in openat.c as an alias. */
diff --git a/sysdeps/mach/hurd/symlinkat.c b/sysdeps/mach/hurd/symlinkat.c
new file mode 100644
index 0000000000..9a51c66d8d
--- /dev/null
+++ b/sysdeps/mach/hurd/symlinkat.c
@@ -0,0 +1,74 @@
+/* Create a symbolic link named relative to an open directory. Hurd version.
+ Copyright (C) 1991,1992,1993,1994,1995,1996,1997,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <hurd/fd.h>
+#include <string.h>
+
+
+/* Make a link to FROM called TO relative to FD. */
+int
+symlinkat (from, fd, to)
+ const char *from;
+ int fd;
+ const char *to;
+{
+ error_t err;
+ file_t dir, node;
+ char *name;
+ const size_t len = strlen (from) + 1;
+ char buf[sizeof (_HURD_SYMLINK) + len];
+
+ /* A symlink is a file whose translator is "/hurd/symlink\0target\0". */
+
+ memcpy (buf, _HURD_SYMLINK, sizeof (_HURD_SYMLINK));
+ memcpy (&buf[sizeof (_HURD_SYMLINK)], from, len);
+
+ dir = __file_name_split_at (fd, to, &name);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ /* Create a new, unlinked node in the target directory. */
+ err = __dir_mkfile (dir, O_WRITE, 0777 & ~_hurd_umask, &node);
+
+ if (! err)
+ /* Set the node's translator to make it a symlink. */
+ err = __file_set_translator (node,
+ FS_TRANS_EXCL|FS_TRANS_SET,
+ FS_TRANS_EXCL|FS_TRANS_SET, 0,
+ buf, sizeof (_HURD_SYMLINK) + len,
+ MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
+
+ if (! err)
+ /* Link the node, now a valid symlink, into the target directory. */
+ err = __dir_link (dir, node, name, 1);
+
+ __mach_port_deallocate (__mach_task_self (), dir);
+ __mach_port_deallocate (__mach_task_self (), node);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/unlinkat.c b/sysdeps/mach/hurd/unlinkat.c
new file mode 100644
index 0000000000..7740c5a297
--- /dev/null
+++ b/sysdeps/mach/hurd/unlinkat.c
@@ -0,0 +1,55 @@
+/* unlinkat -- Remove a name relative to an open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+
+/* Remove the link named NAME. */
+int
+unlinkat (fd, name, flag)
+ int fd;
+ const char *name;
+ int flag;
+{
+ error_t err;
+ file_t dir;
+ const char *file;
+
+ if ((flag &~ AT_REMOVEDIR) != 0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ dir = __directory_name_split_at (fd, name, (char **) &file);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ err = ((flag & AT_REMOVEDIR) ? __dir_rmdir : __dir_unlink) (dir, file);
+ __mach_port_deallocate (__mach_task_self (), dir);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/sysdeps/mach/hurd/xmknod.c b/sysdeps/mach/hurd/xmknod.c
index aaa6771cd8..5f40188fb6 100644
--- a/sysdeps/mach/hurd/xmknod.c
+++ b/sysdeps/mach/hurd/xmknod.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1992,1993,1994,1995,1996,1999,2002,2005
+/* Copyright (C) 1991,1992,1993,1994,1995,1996,1999,2002,2005,2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -18,13 +18,10 @@
02111-1307 USA. */
#include <errno.h>
-#include <sys/stat.h>
-#include <hurd.h>
-#include <hurd/paths.h>
#include <fcntl.h>
-#include "stdio-common/_itoa.h"
-#include <string.h>
+#include <stddef.h>
#include <sys/types.h>
+#include <sys/stat.h>
/* Create a device file named FILE_NAME, with permission and special bits MODE
@@ -33,85 +30,6 @@
int
__xmknod (int vers, const char *file_name, mode_t mode, dev_t *dev)
{
- error_t err;
- file_t dir, node;
- char *name;
- char buf[100], *bp;
- const char *translator;
- size_t len;
-
- if (vers != _MKNOD_VER)
- return __hurd_fail (EINVAL);
-
- if (S_ISCHR (mode))
- {
- translator = _HURD_CHRDEV;
- len = sizeof (_HURD_CHRDEV);
- }
- else if (S_ISBLK (mode))
- {
- translator = _HURD_BLKDEV;
- len = sizeof (_HURD_BLKDEV);
- }
- else if (S_ISFIFO (mode))
- {
- translator = _HURD_FIFO;
- len = sizeof (_HURD_FIFO);
- }
- else if (S_ISREG (mode))
- {
- translator = NULL;
- len = 0;
- }
- else
- {
- errno = EINVAL;
- return -1;
- }
-
- if (translator != NULL && ! S_ISFIFO (mode))
- {
- /* We set the translator to "ifmt\0major\0minor\0", where IFMT
- depends on the S_IFMT bits of our MODE argument, and MAJOR and
- MINOR are ASCII decimal (octal or hex would do as well)
- representations of our arguments. Thus the convention is that
- CHRDEV and BLKDEV translators are invoked with two non-switch
- arguments, giving the major and minor device numbers in %i format. */
-
- bp = buf + sizeof (buf);
- *--bp = '\0';
- bp = _itoa (minor (*dev), bp, 10, 0);
- *--bp = '\0';
- bp = _itoa (major (*dev), bp, 10, 0);
- memcpy (bp - len, translator, len);
- translator = bp - len;
- len = buf + sizeof (buf) - translator;
- }
-
- dir = __file_name_split (file_name, &name);
- if (dir == MACH_PORT_NULL)
- return -1;
-
- /* Create a new, unlinked node in the target directory. */
- err = __dir_mkfile (dir, O_WRITE, (mode & ~S_IFMT) & ~_hurd_umask, &node);
-
- if (! err && translator != NULL)
- /* Set the node's translator to make it a device. */
- err = __file_set_translator (node,
- FS_TRANS_EXCL | FS_TRANS_SET,
- FS_TRANS_EXCL | FS_TRANS_SET, 0,
- translator, len,
- MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
-
- if (! err)
- /* Link the node, now a valid device, into the target directory. */
- err = __dir_link (dir, node, name, 1);
-
- __mach_port_deallocate (__mach_task_self (), dir);
- __mach_port_deallocate (__mach_task_self (), node);
-
- if (err)
- return __hurd_fail (err);
- return 0;
+ return __xmknodat (vers, AT_FDCWD, file_name, mode, dev);
}
libc_hidden_def (__xmknod)
diff --git a/sysdeps/mach/hurd/xmknodat.c b/sysdeps/mach/hurd/xmknodat.c
new file mode 100644
index 0000000000..b2227593c9
--- /dev/null
+++ b/sysdeps/mach/hurd/xmknodat.c
@@ -0,0 +1,118 @@
+/* Create a device file relative to an open directory. Hurd version.
+ Copyright (C) 1991,1992,1993,1994,1995,1996,1999,2002,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+#include "stdio-common/_itoa.h"
+#include <string.h>
+#include <sys/types.h>
+
+/* Create a device file named PATH relative to FD, with permission and
+ special bits MODE and device number DEV (which can be constructed
+ from major and minor device numbers with the `makedev' macro
+ above). */
+int
+__xmknodat (int vers, int fd, const char *path, mode_t mode, dev_t *dev)
+{
+ error_t err;
+ file_t dir, node;
+ char *name;
+ char buf[100], *bp;
+ const char *translator;
+ size_t len;
+
+ if (vers != _MKNOD_VER)
+ return __hurd_fail (EINVAL);
+
+ if (S_ISCHR (mode))
+ {
+ translator = _HURD_CHRDEV;
+ len = sizeof (_HURD_CHRDEV);
+ }
+ else if (S_ISBLK (mode))
+ {
+ translator = _HURD_BLKDEV;
+ len = sizeof (_HURD_BLKDEV);
+ }
+ else if (S_ISFIFO (mode))
+ {
+ translator = _HURD_FIFO;
+ len = sizeof (_HURD_FIFO);
+ }
+ else if (S_ISREG (mode))
+ {
+ translator = NULL;
+ len = 0;
+ }
+ else
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (translator != NULL && ! S_ISFIFO (mode))
+ {
+ /* We set the translator to "ifmt\0major\0minor\0", where IFMT
+ depends on the S_IFMT bits of our MODE argument, and MAJOR and
+ MINOR are ASCII decimal (octal or hex would do as well)
+ representations of our arguments. Thus the convention is that
+ CHRDEV and BLKDEV translators are invoked with two non-switch
+ arguments, giving the major and minor device numbers in %i format. */
+
+ bp = buf + sizeof (buf);
+ *--bp = '\0';
+ bp = _itoa (minor (*dev), bp, 10, 0);
+ *--bp = '\0';
+ bp = _itoa (major (*dev), bp, 10, 0);
+ memcpy (bp - len, translator, len);
+ translator = bp - len;
+ len = buf + sizeof (buf) - translator;
+ }
+
+ dir = __file_name_split_at (fd, path, &name);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ /* Create a new, unlinked node in the target directory. */
+ err = __dir_mkfile (dir, O_WRITE, (mode & ~S_IFMT) & ~_hurd_umask, &node);
+
+ if (! err && translator != NULL)
+ /* Set the node's translator to make it a device. */
+ err = __file_set_translator (node,
+ FS_TRANS_EXCL | FS_TRANS_SET,
+ FS_TRANS_EXCL | FS_TRANS_SET, 0,
+ translator, len,
+ MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
+
+ if (! err)
+ /* Link the node, now a valid device, into the target directory. */
+ err = __dir_link (dir, node, name, 1);
+
+ __mach_port_deallocate (__mach_task_self (), dir);
+ __mach_port_deallocate (__mach_task_self (), node);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}