int fchownat(int, const char *, uid_t, gid_t, int);
#if 0
int fexecve(int, char *const [], char *const []);
-int linkat(int, const char *, int, const char *, int);
#endif
+int linkat(int, const char *, int, const char *, int);
ssize_t readlinkat(int, const char * __restrict, char * __restrict, size_t);
int symlinkat(const char *, int, const char *);
int unlinkat(int, const char *, int);
{ AS(symlinkat_args), (sy_call_t *)sys_symlinkat }, /* 528 = symlinkat */
{ AS(swapoff_args), (sy_call_t *)sys_swapoff }, /* 529 = swapoff */
{ AS(vquotactl_args), (sy_call_t *)sys_vquotactl }, /* 530 = vquotactl */
+ { AS(linkat_args), (sy_call_t *)sys_linkat }, /* 531 = linkat */
};
"symlinkat", /* 528 = symlinkat */
"swapoff", /* 529 = swapoff */
"vquotactl", /* 530 = vquotactl */
+ "linkat", /* 531 = linkat */
};
529 STD BSD { int swapoff(char *name); }
530 STD BSD { int vquotactl(const char *path, \
struct plistref *pref); }
+531 STD POSIX { int linkat(int fd1, char *path1, int fd2, \
+ char *path2, int flags); }
return (error);
}
+/*
+ * linkat_args(int fd1, char *path1, int fd2, char *path2, int flags)
+ *
+ * Make a hard file link. The path1 argument is relative to the directory
+ * associated with fd1, and similarly the path2 argument is relative to
+ * the directory associated with fd2.
+ */
+int
+sys_linkat(struct linkat_args *uap)
+{
+ struct nlookupdata nd, linknd;
+ struct file *fp1, *fp2;
+ int error;
+
+ error = nlookup_init_at(&nd, &fp1, uap->fd1, uap->path1, UIO_USERSPACE,
+ (uap->flags & AT_SYMLINK_FOLLOW) ? NLC_FOLLOW : 0);
+ if (error == 0) {
+ error = nlookup_init_at(&linknd, &fp2, uap->fd2,
+ uap->path2, UIO_USERSPACE, 0);
+ if (error == 0)
+ error = kern_link(&nd, &linknd);
+ nlookup_done_at(&linknd, fp2);
+ }
+ nlookup_done_at(&nd, fp1);
+ return (error);
+}
+
int
kern_symlink(struct nlookupdata *nd, char *path, int mode)
{
#define AT_SYMLINK_NOFOLLOW 1
#define AT_REMOVEDIR 2
#define AT_EACCESS 4
+#define AT_SYMLINK_FOLLOW 8
/*
* Constants used for fcntl(2)
HIDE_POSIX(symlinkat)
HIDE_BSD(swapoff)
HIDE_BSD(vquotactl)
+HIDE_POSIX(linkat)
#define SYS_symlinkat 528
#define SYS_swapoff 529
#define SYS_vquotactl 530
-#define SYS_MAXSYSCALL 531
+#define SYS_linkat 531
+#define SYS_MAXSYSCALL 532
readlinkat.o \
symlinkat.o \
swapoff.o \
- vquotactl.o
+ vquotactl.o \
+ linkat.o
const char * path; char path_[PAD_(const char *)];
struct plistref * pref; char pref_[PAD_(struct plistref *)];
};
+struct linkat_args {
+#ifdef _KERNEL
+ struct sysmsg sysmsg;
+#endif
+ int fd1; char fd1_[PAD_(int)];
+ char * path1; char path1_[PAD_(char *)];
+ int fd2; char fd2_[PAD_(int)];
+ char * path2; char path2_[PAD_(char *)];
+ int flags; char flags_[PAD_(int)];
+};
#ifdef COMPAT_43
int sys_symlinkat (struct symlinkat_args *);
int sys_swapoff (struct swapoff_args *);
int sys_vquotactl (struct vquotactl_args *);
+int sys_linkat (struct linkat_args *);
#endif /* !_SYS_SYSPROTO_H_ */
#undef PAD_
struct symlinkat_args symlinkat;
struct swapoff_args swapoff;
struct vquotactl_args vquotactl;
+ struct linkat_args linkat;
};