Page MenuHomeFreeBSD

D21423.id61414.diff
No OneTemporary

D21423.id61414.diff

Index: lib/libc/sys/Makefile.inc
===================================================================
--- lib/libc/sys/Makefile.inc
+++ lib/libc/sys/Makefile.inc
@@ -475,7 +475,8 @@
setuid.2 seteuid.2 \
setuid.2 setgid.2
MLINKS+=shmat.2 shmdt.2
-MLINKS+=shm_open.2 shm_unlink.2
+MLINKS+=shm_open.2 shm_unlink.2 \
+ shm_open.2 shm_rename.2
MLINKS+=sigwaitinfo.2 sigtimedwait.2
MLINKS+=stat.2 fstat.2 \
stat.2 fstatat.2 \
Index: lib/libc/sys/Symbol.map
===================================================================
--- lib/libc/sys/Symbol.map
+++ lib/libc/sys/Symbol.map
@@ -408,6 +408,7 @@
fhreadlink;
getfhat;
funlinkat;
+ shm_rename;
};
FBSDprivate_1.0 {
Index: lib/libc/sys/shm_open.2
===================================================================
--- lib/libc/sys/shm_open.2
+++ lib/libc/sys/shm_open.2
@@ -32,7 +32,7 @@
.Dt SHM_OPEN 2
.Os
.Sh NAME
-.Nm shm_open , shm_unlink
+.Nm shm_open , shm_rename , shm_unlink
.Nd "shared memory object operations"
.Sh LIBRARY
.Lb libc
@@ -43,6 +43,8 @@
.Ft int
.Fn shm_open "const char *path" "int flags" "mode_t mode"
.Ft int
+.Fn shm_rename "const char *path_from" "const char *path_to"
+.Ft int
.Fn shm_unlink "const char *path"
.Sh DESCRIPTION
The
@@ -121,6 +123,8 @@
Since the object has no name,
it cannot be removed via a subsequent call to
.Fn shm_unlink .
+or moved with a call to
+.Fn shm_rename .
Instead,
the shared memory object will be garbage collected when the last reference to
the shared memory object is removed.
@@ -136,6 +140,17 @@
All other flags are ignored.
.Pp
The
+.Fn shm_rename
+system call atomically removes a shared memory object named
+.Fa path_from
+and relinks it at
+.Fa path_to .
+If another object is already linked at
+.Fa path_to ,
+that object will be unlinked first.
+This is also a FreeBSD extension.
+.Pp
+The
.Fn shm_unlink
system call removes a shared memory object named
.Fa path .
@@ -144,15 +159,20 @@
.Fn shm_open
returns a non-negative integer,
and
+.Fn shm_rename
+and
.Fn shm_unlink
-returns zero.
-Both functions return -1 on failure, and set
+return zero.
+All functions return -1 on failure, and set
.Va errno
to indicate the error.
.Sh COMPATIBILITY
The
-.Fa path
-argument does not necessarily represent a pathname (although it does in
+.Fa path ,
+.Fa path_from ,
+and
+.Fa path_to
+arguments do not necessarily represent a pathname (although they do in
most other implementations).
Two processes opening the same
.Fa path
@@ -265,6 +285,25 @@
The required permissions (for reading or reading and writing) are denied.
.El
.Pp
+The following errors are defined for
+.Fn shm_rename :
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The
+.Fa path_from
+or
+.Fa path_to
+argument points outside the process' allocated address space.
+.It Bq Er ENAMETOOLONG
+The entire pathname exceeded 1023 characters.
+.It Bq Er ENOENT
+The shared memory object at
+.Fa path_from
+does not exist.
+.It Bq Er EACCES
+The required permissions are denied.
+.El
+.Pp
.Fn shm_unlink
fails with these error codes for these conditions:
.Bl -tag -width Er
@@ -305,6 +344,9 @@
The functions were reimplemented as system calls using shared memory objects
directly rather than files in
.Fx 8.0 .
+.Pp
+.Fn shm_rename
+first appeared in FreeBSD 13.0 as a FreeBSD-specific extension.
.Sh AUTHORS
.An Garrett A. Wollman Aq Mt wollman@FreeBSD.org
(C library support and this manual page)
@@ -311,3 +353,6 @@
.Pp
.An Matthew Dillon Aq Mt dillon@FreeBSD.org
.Pq Dv MAP_NOSYNC
+.Pp
+.An Matthew Bryan Aq Mt matthew.bryan@isilon.com
+.Pq Dv shm_rename implementation
Index: sys/compat/freebsd32/freebsd32_syscall.h
===================================================================
--- sys/compat/freebsd32/freebsd32_syscall.h
+++ sys/compat/freebsd32/freebsd32_syscall.h
@@ -496,4 +496,5 @@
#define FREEBSD32_SYS_fhreadlink 567
#define FREEBSD32_SYS_funlinkat 568
#define FREEBSD32_SYS_copy_file_range 569
-#define FREEBSD32_SYS_MAXSYSCALL 570
+#define FREEBSD32_SYS_shm_rename 570
+#define FREEBSD32_SYS_MAXSYSCALL 571
Index: sys/compat/freebsd32/freebsd32_syscalls.c
===================================================================
--- sys/compat/freebsd32/freebsd32_syscalls.c
+++ sys/compat/freebsd32/freebsd32_syscalls.c
@@ -606,4 +606,5 @@
"fhreadlink", /* 567 = fhreadlink */
"funlinkat", /* 568 = funlinkat */
"copy_file_range", /* 569 = copy_file_range */
+ "shm_rename", /* 570 = shm_rename */
};
Index: sys/compat/freebsd32/freebsd32_sysent.c
===================================================================
--- sys/compat/freebsd32/freebsd32_sysent.c
+++ sys/compat/freebsd32/freebsd32_sysent.c
@@ -653,4 +653,5 @@
{ AS(fhreadlink_args), (sy_call_t *)sys_fhreadlink, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 567 = fhreadlink */
{ AS(funlinkat_args), (sy_call_t *)sys_funlinkat, AUE_UNLINKAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 568 = funlinkat */
{ AS(copy_file_range_args), (sy_call_t *)sys_copy_file_range, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 569 = copy_file_range */
+ { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 570 = shm_rename */
};
Index: sys/compat/freebsd32/freebsd32_systrace_args.c
===================================================================
--- sys/compat/freebsd32/freebsd32_systrace_args.c
+++ sys/compat/freebsd32/freebsd32_systrace_args.c
@@ -3332,6 +3332,14 @@
*n_args = 6;
break;
}
+ /* shm_rename */
+ case 570: {
+ struct shm_rename_args *p = params;
+ uarg[0] = (intptr_t) p->path_from; /* const char * */
+ uarg[1] = (intptr_t) p->path_to; /* const char * */
+ *n_args = 2;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -8971,6 +8979,19 @@
break;
};
break;
+ /* shm_rename */
+ case 570:
+ switch(ndx) {
+ case 0:
+ p = "userland const char *";
+ break;
+ case 1:
+ p = "userland const char *";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -10850,6 +10871,11 @@
if (ndx == 0 || ndx == 1)
p = "ssize_t";
break;
+ /* shm_rename */
+ case 570:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
Index: sys/compat/freebsd32/syscalls.master
===================================================================
--- sys/compat/freebsd32/syscalls.master
+++ sys/compat/freebsd32/syscalls.master
@@ -1150,5 +1150,6 @@
569 AUE_NULL NOPROTO { ssize_t copy_file_range(int infd, \
off_t *inoffp, int outfd, off_t *outoffp, \
size_t len, unsigned int flags); }
+570 AUE_NULL NOPROTO { int shm_rename(const char *path_from, const char *path_to); }
; vim: syntax=off
Index: sys/kern/init_sysent.c
===================================================================
--- sys/kern/init_sysent.c
+++ sys/kern/init_sysent.c
@@ -619,4 +619,5 @@
{ AS(fhreadlink_args), (sy_call_t *)sys_fhreadlink, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 567 = fhreadlink */
{ AS(funlinkat_args), (sy_call_t *)sys_funlinkat, AUE_UNLINKAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 568 = funlinkat */
{ AS(copy_file_range_args), (sy_call_t *)sys_copy_file_range, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 569 = copy_file_range */
+ { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 570 = shm_rename */
};
Index: sys/kern/syscalls.c
===================================================================
--- sys/kern/syscalls.c
+++ sys/kern/syscalls.c
@@ -576,4 +576,5 @@
"fhreadlink", /* 567 = fhreadlink */
"funlinkat", /* 568 = funlinkat */
"copy_file_range", /* 569 = copy_file_range */
+ "shm_rename", /* 570 = shm_rename */
};
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -3185,6 +3185,11 @@
unsigned int flags
);
}
+570 AUE_NULL STD {
+ int shm_rename(
+ _In_z_ const char *path_from,
+ _In_z_ const char *path_to);
+ }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Index: sys/kern/systrace_args.c
===================================================================
--- sys/kern/systrace_args.c
+++ sys/kern/systrace_args.c
@@ -3324,6 +3324,14 @@
*n_args = 6;
break;
}
+ /* shm_rename */
+ case 570: {
+ struct shm_rename_args *p = params;
+ uarg[0] = (intptr_t) p->path_from; /* const char * */
+ uarg[1] = (intptr_t) p->path_to; /* const char * */
+ *n_args = 2;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -8876,6 +8884,19 @@
break;
};
break;
+ /* shm_rename */
+ case 570:
+ switch(ndx) {
+ case 0:
+ p = "userland const char *";
+ break;
+ case 1:
+ p = "userland const char *";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -10782,6 +10803,11 @@
if (ndx == 0 || ndx == 1)
p = "ssize_t";
break;
+ /* shm_rename */
+ case 570:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
Index: sys/kern/uipc_shm.c
===================================================================
--- sys/kern/uipc_shm.c
+++ sys/kern/uipc_shm.c
@@ -33,8 +33,9 @@
/*
* Support for shared swap-backed anonymous memory objects via
- * shm_open(2) and shm_unlink(2). While most of the implementation is
- * here, vm_mmap.c contains mapping logic changes.
+ * shm_open(2), shm_rename(2), and shm_unlink(2).
+ * While most of the implementation is here, vm_mmap.c contains
+ * mapping logic changes.
*
* posixshmcontrol(1) allows users to inspect the state of the memory
* objects. Per-uid swap resource limit controls total amount of
@@ -118,7 +119,8 @@
static void shm_init(void *arg);
static void shm_insert(char *path, Fnv32_t fnv, struct shmfd *shmfd);
static struct shmfd *shm_lookup(char *path, Fnv32_t fnv);
-static int shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred);
+static int shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred,
+ bool preserve);
static fo_rdwr_t shm_read;
static fo_rdwr_t shm_write;
@@ -665,7 +667,7 @@
}
static int
-shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred)
+shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred, bool preserve)
{
struct shm_mapping *map;
int error;
@@ -685,7 +687,8 @@
return (error);
map->sm_shmfd->shm_path = NULL;
LIST_REMOVE(map, sm_link);
- shm_drop(map->sm_shmfd);
+ if (!preserve)
+ shm_drop(map->sm_shmfd);
free(map->sm_path, M_SHMFD);
free(map, M_SHMFD);
return (0);
@@ -881,7 +884,7 @@
AUDIT_ARG_UPATH1_CANON(path);
fnv = fnv_32_str(path, FNV1_32_INIT);
sx_xlock(&shm_dict_lock);
- error = shm_remove(path, fnv, td->td_ucred);
+ error = shm_remove(path, fnv, td->td_ucred, false);
sx_xunlock(&shm_dict_lock);
free(path, M_TEMP);
@@ -888,7 +891,108 @@
return (error);
}
+/*
+ * TODO: add a 'flags' argument, similar to the Linux renameat2.
+ * The flag states what should happen if there is an shm already at path_to.
+ * That way we have the option to e.g. return EEXIST instead of unlinking
+ * the shm at path_to. We could also have an option to swap the two shms.
+ */
int
+sys_shm_rename(struct thread *td, struct shm_rename_args *uap)
+{
+ char *path_from = NULL, *path_to = NULL;
+ Fnv32_t fnv_from, fnv_to;
+ struct shmfd *fd_from;
+ int error;
+
+ path_from = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+ error = copyinstr(uap->path_from, path_from, MAXPATHLEN, NULL);
+ if (error)
+ goto out;
+
+ /*
+ * Malloc zone M_SHMFD, since this path may end up freed later from
+ * M_SHMFD.
+ */
+ path_to = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK);
+ error = copyinstr(uap->path_to, path_to, MAXPATHLEN, NULL);
+ if (error)
+ goto out;
+
+ /* Rename with from/to equal is a no-op */
+ if (strncmp(path_from, path_to, MAXPATHLEN) == 0)
+ goto out;
+
+ fnv_from = fnv_32_str(path_from, FNV1_32_INIT);
+ fnv_to = fnv_32_str(path_to, FNV1_32_INIT);
+
+ sx_xlock(&shm_dict_lock);
+
+ fd_from = shm_lookup(path_from, fnv_from);
+ if (fd_from == NULL) {
+ sx_xunlock(&shm_dict_lock);
+ error = ENOENT;
+ goto out;
+ }
+
+ error = shm_remove(path_from, fnv_from, td->td_ucred, true);
+
+ /*
+ * One of my assumptions failed if ENOENT (e.g. locking didn't
+ * protect us)
+ */
+ KASSERT(error != ENOENT, ("Our shm disappeared during shm_rename: %s",
+ path_from));
+ if (error) {
+ sx_xunlock(&shm_dict_lock);
+ goto out;
+ }
+
+ /*
+ * NOTE: if path_to is not already in the hash, c'est la vie;
+ * it simply means we have nothing already at path_to to unlink.
+ * That is the ENOENT case.
+ *
+ * If we somehow don't have access to unlink this guy, but
+ * did for the shm at path_from, then relink the shm to path_from
+ * and abort with EACCES.
+ */
+ error = shm_remove(path_to, fnv_to, td->td_ucred, false);
+ if (error == EACCES) {
+ shm_insert(path_from, fnv_from, fd_from);
+ /* Don't free path_from now, since the hash references it */
+ path_from = NULL;
+ sx_xunlock(&shm_dict_lock);
+ goto out;
+ }
+ else if (error && error != ENOENT) {
+ sx_xunlock(&shm_dict_lock);
+ goto out;
+ }
+
+ shm_insert(path_to, fnv_to, fd_from);
+
+ /* Don't free path_to now, since the hash references it */
+ path_to = NULL;
+
+ /* We kept a ref when we removed, and incremented again in insert */
+ shm_drop(fd_from);
+#ifdef DEBUG
+ KASSERT(fd_from->shm_refs > 0, ("Expected >0 refs; got: %d\n",
+ fd_from->shm_refs));
+#endif
+
+ sx_xunlock(&shm_dict_lock);
+
+out:
+ if (path_from != NULL)
+ free(path_from, M_TEMP);
+ if (path_to != NULL)
+ free(path_to, M_SHMFD);
+ return(error);
+}
+
+int
shm_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t objsize,
vm_prot_t prot, vm_prot_t cap_maxprot, int flags,
vm_ooffset_t foff, struct thread *td)
Index: sys/sys/mman.h
===================================================================
--- sys/sys/mman.h
+++ sys/sys/mman.h
@@ -281,6 +281,7 @@
int mlockall(int);
int munlockall(void);
int shm_open(const char *, int, mode_t);
+int shm_rename(const char *, const char *);
int shm_unlink(const char *);
#endif
__END_DECLS
Index: sys/sys/syscall.h
===================================================================
--- sys/sys/syscall.h
+++ sys/sys/syscall.h
@@ -505,4 +505,5 @@
#define SYS_fhreadlink 567
#define SYS_funlinkat 568
#define SYS_copy_file_range 569
-#define SYS_MAXSYSCALL 570
+#define SYS_shm_rename 570
+#define SYS_MAXSYSCALL 571
Index: sys/sys/syscall.mk
===================================================================
--- sys/sys/syscall.mk
+++ sys/sys/syscall.mk
@@ -410,4 +410,5 @@
fhlinkat.o \
fhreadlink.o \
funlinkat.o \
- copy_file_range.o
+ copy_file_range.o \
+ shm_rename.o
Index: sys/sys/sysproto.h
===================================================================
--- sys/sys/sysproto.h
+++ sys/sys/sysproto.h
@@ -1804,6 +1804,10 @@
char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)];
char flags_l_[PADL_(unsigned int)]; unsigned int flags; char flags_r_[PADR_(unsigned int)];
};
+struct shm_rename_args {
+ char path_from_l_[PADL_(const char *)]; const char * path_from; char path_from_r_[PADR_(const char *)];
+ char path_to_l_[PADL_(const char *)]; const char * path_to; char path_to_r_[PADR_(const char *)];
+};
int nosys(struct thread *, struct nosys_args *);
void sys_sys_exit(struct thread *, struct sys_exit_args *);
int sys_fork(struct thread *, struct fork_args *);
@@ -2190,6 +2194,7 @@
int sys_fhreadlink(struct thread *, struct fhreadlink_args *);
int sys_funlinkat(struct thread *, struct funlinkat_args *);
int sys_copy_file_range(struct thread *, struct copy_file_range_args *);
+int sys_shm_rename(struct thread *, struct shm_rename_args *);
#ifdef COMPAT_43
@@ -3098,6 +3103,7 @@
#define SYS_AUE_fhreadlink AUE_NULL
#define SYS_AUE_funlinkat AUE_UNLINKAT
#define SYS_AUE_copy_file_range AUE_NULL
+#define SYS_AUE_shm_rename AUE_NULL
#undef PAD_
#undef PADL_
Index: tests/sys/posixshm/posixshm_test.c
===================================================================
--- tests/sys/posixshm/posixshm_test.c
+++ tests/sys/posixshm/posixshm_test.c
@@ -46,20 +46,36 @@
#define TEST_PATH_LEN 256
static char test_path[TEST_PATH_LEN];
+static char test_path2[TEST_PATH_LEN];
+static unsigned int test_path_idx = 0;
static void
-gen_test_path(void)
+gen_a_test_path(char *path)
{
+ snprintf(path, TEST_PATH_LEN, "%s/tmp.XXXXXX%d",
+ getenv("TMPDIR") == NULL ? "/tmp" : getenv("TMPDIR"),
+ test_path_idx);
- snprintf(test_path, sizeof(test_path), "%s/tmp.XXXXXX",
- getenv("TMPDIR") == NULL ? "/tmp" : getenv("TMPDIR"));
- test_path[sizeof(test_path) - 1] = '\0';
- ATF_REQUIRE_MSG(mkstemp(test_path) != -1,
+ test_path_idx++;
+
+ ATF_REQUIRE_MSG(mkstemp(path) != -1,
"mkstemp failed; errno=%d", errno);
- ATF_REQUIRE_MSG(unlink(test_path) == 0,
+ ATF_REQUIRE_MSG(unlink(path) == 0,
"unlink failed; errno=%d", errno);
}
+static void
+gen_test_path(void)
+{
+ gen_a_test_path(test_path);
+}
+
+static void
+gen_test_path2(void)
+{
+ gen_a_test_path(test_path2);
+}
+
/*
* Attempt a shm_open() that should fail with an expected error of 'error'.
*/
@@ -89,20 +105,18 @@
}
/*
- * Open the test object and write '1' to the first byte. Returns valid fd
+ * Open the test object and write a value to the first byte. Returns valid fd
* on success and -1 on failure.
*/
static int
-scribble_object(void)
+scribble_object(const char *path, char value)
{
char *page;
int fd, pagesize;
- gen_test_path();
-
ATF_REQUIRE(0 < (pagesize = getpagesize()));
- fd = shm_open(test_path, O_CREAT|O_EXCL|O_RDWR, 0777);
+ fd = shm_open(path, O_CREAT|O_EXCL|O_RDWR, 0777);
if (fd < 0 && errno == EEXIST) {
if (shm_unlink(test_path) < 0)
atf_tc_fail("shm_unlink");
@@ -117,7 +131,7 @@
if (page == MAP_FAILED)
atf_tc_fail("mmap failed; errno=%d", errno);
- page[0] = '1';
+ page[0] = value;
ATF_REQUIRE_MSG(munmap(page, pagesize) == 0, "munmap failed; errno=%d",
errno);
@@ -124,6 +138,34 @@
return (fd);
}
+/*
+ * Fail the test case if the 'path' does not refer to an shm whose first byte
+ * is equal to expected_value
+ */
+static void
+verify_object(const char *path, char expected_value)
+{
+ int fd;
+ int pagesize;
+ char *page;
+
+ ATF_REQUIRE(0 < (pagesize = getpagesize()));
+
+ fd = shm_open(path, O_RDONLY, 0777);
+ if (fd < 0)
+ atf_tc_fail("shm_open failed; errno=%d", errno);
+
+ page = mmap(0, pagesize, PROT_READ, MAP_SHARED, fd, 0);
+ if (page == MAP_FAILED)
+ atf_tc_fail("mmap(1)");
+ if (page[0] != expected_value)
+ atf_tc_fail("Renamed object has incorrect value; has %d, "
+ "expected %d\n", page[0], expected_value);
+ ATF_REQUIRE_MSG(munmap(page, pagesize) == 0, "munmap failed; errno=%d",
+ errno);
+ close(fd);
+}
+
ATF_TC_WITHOUT_HEAD(remap_object);
ATF_TC_BODY(remap_object, tc)
{
@@ -132,7 +174,8 @@
ATF_REQUIRE(0 < (pagesize = getpagesize()));
- fd = scribble_object();
+ gen_test_path();
+ fd = scribble_object(test_path, '1');
page = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (page == MAP_FAILED)
@@ -149,6 +192,86 @@
"shm_unlink failed; errno=%d", errno);
}
+ATF_TC_WITHOUT_HEAD(rename_from_anon);
+ATF_TC_BODY(rename_from_anon, tc)
+{
+ int fd;
+
+ gen_test_path();
+ fd = shm_rename(SHM_ANON, test_path);
+ if (fd >= 0)
+ atf_tc_fail("shm_rename from SHM_ANON succeeded unexpectedly");
+}
+
+ATF_TC_WITHOUT_HEAD(rename_from_nonexisting);
+ATF_TC_BODY(rename_from_nonexisting, tc)
+{
+ int fd;
+
+ gen_test_path();
+ fd = shm_rename(test_path, test_path2);
+ if (fd >= 0)
+ atf_tc_fail("shm_rename of nonexisting shm succeeded unexpectedly");
+
+ if (errno != ENOENT)
+ atf_tc_fail("Expected ENOENT to rename of nonexistent shm");
+}
+
+ATF_TC_WITHOUT_HEAD(rename_to_anon);
+ATF_TC_BODY(rename_to_anon, tc)
+{
+ int fd;
+
+ gen_test_path();
+ fd = shm_rename(test_path, SHM_ANON);
+ if (fd >= 0)
+ atf_tc_fail("shm_rename to SHM_ANON succeeded unexpectedly");
+}
+
+ATF_TC_WITHOUT_HEAD(rename_to_existing);
+ATF_TC_BODY(rename_to_existing, tc)
+{
+ char expected_value;
+ int fd;
+ int fd2;
+
+ // Some contents we can verify later
+ expected_value = 'g';
+
+ gen_test_path();
+ fd = scribble_object(test_path, expected_value);
+ close(fd);
+
+ // Give the other some different value so we can detect success
+ gen_test_path2();
+ fd2 = scribble_object(test_path2, 'h');
+ close(fd2);
+
+ ATF_REQUIRE_MSG(shm_rename(test_path, test_path2) == 0,
+ "shm_rename failed; errno=%d", errno);
+
+ // Read back renamed; verify contents
+ verify_object(test_path2, expected_value);
+}
+
+ATF_TC_WITHOUT_HEAD(rename_to_self);
+ATF_TC_BODY(rename_to_self, tc)
+{
+ int fd;
+ char expected_value;
+
+ expected_value = 't';
+
+ gen_test_path();
+ fd = scribble_object(test_path, expected_value);
+ close(fd);
+
+ ATF_REQUIRE_MSG(shm_rename(test_path, test_path) == 0,
+ "shm_rename failed; errno=%d", errno);
+
+ verify_object(test_path, expected_value);
+}
+
ATF_TC_WITHOUT_HEAD(reopen_object);
ATF_TC_BODY(reopen_object, tc)
{
@@ -157,7 +280,8 @@
ATF_REQUIRE(0 < (pagesize = getpagesize()));
- fd = scribble_object();
+ gen_test_path();
+ fd = scribble_object(test_path, '1');
close(fd);
fd = shm_open(test_path, O_RDONLY, 0777);
@@ -613,6 +737,11 @@
{
ATF_TP_ADD_TC(tp, remap_object);
+ ATF_TP_ADD_TC(tp, rename_from_anon);
+ ATF_TP_ADD_TC(tp, rename_from_nonexisting);
+ ATF_TP_ADD_TC(tp, rename_to_anon);
+ ATF_TP_ADD_TC(tp, rename_to_existing);
+ ATF_TP_ADD_TC(tp, rename_to_self);
ATF_TP_ADD_TC(tp, reopen_object);
ATF_TP_ADD_TC(tp, readonly_mmap_write);
ATF_TP_ADD_TC(tp, open_after_link);
Index: usr.bin/truss/syscalls.c
===================================================================
--- usr.bin/truss/syscalls.c
+++ usr.bin/truss/syscalls.c
@@ -470,6 +470,8 @@
{ Ptr | IN, 3 }, { Socklent, 4 } } },
{ .name = "shm_open", .ret_type = 1, .nargs = 3,
.args = { { ShmName | IN, 0 }, { Open, 1 }, { Octal, 2 } } },
+ { .name = "shm_rename", .ret_type = 1, .nargs = 2,
+ .args = { { Name | IN, 0 }, { Name | IN, 1 } } },
{ .name = "shm_unlink", .ret_type = 1, .nargs = 1,
.args = { { Name | IN, 0 } } },
{ .name = "shutdown", .ret_type = 1, .nargs = 2,

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 15, 9:46 PM (10 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27655145
Default Alt Text
D21423.id61414.diff (21 KB)

Event Timeline