4

i am currently developing an application on ubunto and calling shm_open, currently the default path is within /var/run/shm. however i need to change this to /tmp. simply trying the following does not work:

fd = shm_open( "/tmp/test", O_RDWR | O_CREAT, 0777 );

can anyone please advise?

godzilla
  • 3,005
  • 7
  • 44
  • 60
  • What is the error code returned by querying `errno`? – Jason Jun 19 '12 at 14:11
  • if you mean fd - it returns 3 – godzilla Jun 19 '12 at 14:16
  • Okay, so that's a valid file-descriptor ... why are you saying it's not working? – Jason Jun 19 '12 at 14:17
  • sorry my mistake, when i get rid of /tmp it returns 3. however when executing the above -1 is returned – godzilla Jun 19 '12 at 14:18
  • Okay, so what happens when you call `perror(NULL);` after `shm_open` returns `-1`? – Jason Jun 19 '12 at 14:20
  • i get the following message: No such file or directory – godzilla Jun 19 '12 at 14:23
  • The problem is there is no directory like `/dev/shm/tmp/` ... so you can't create a file called `/dev/shm/tmp/test` since the `tmp` directory doesn't exist. @Mihai answer is correct if you must use `/tmp`, otherwise you can simply use `test`, and that will create `/dev/shm/test`. – Jason Jun 19 '12 at 14:28
  • Here is another link you can try: http://fixunix.com/sgi/112129-linux-shm_open-bad-file-descriptor-sgi-runs-well.html – Jason Jun 19 '12 at 14:31
  • well i wish to have persistent files after reset so ideally i need them within /tmp not within /dev/tmp, is there a way around this? – godzilla Jun 19 '12 at 14:32
  • 2
    That's not the way shared memory objects work ... on Linux they are by default created inside of `/dev/shm`, and if you want them somewhere else, you have to mount a `tmpfs` file-system in that desired directory. – Jason Jun 19 '12 at 14:33
  • please correct me if i am wrong, i need to do a mount | grep shm within the /tmp directory? – godzilla Jun 19 '12 at 14:34
  • Yeah, that part is a little confusing, see @Hristo answer ... if you wanted to create the `tmpfs` mount at `/tmp`, you would actually do that within `fstab` – Jason Jun 19 '12 at 14:39
  • any articles on this to help me on that way? This is all new to me – godzilla Jun 19 '12 at 14:49

2 Answers2

12

From the man page of shm_open(3):

name specifies the shared memory object to be created or opened. For portable use, a shared memory object should be identified by a name of the form /somename; that is, a null-terminated string of up to NAME_MAX (i.e., 255) characters consisting of an initial slash, followed by one or more characters, none of which are slashes.

The name parameter of shm_open(3) is an object name, not a file path! It just happens that GLIBC places all shared memory objects in /dev/shm or /var/run/shm by prepending the path to the object name and calling open() on the resulting name. If you specify /tmp/test as the shared object name then Linux would try to open or create /var/run/shm/tmp/test. Open with O_CREAT creates new files but does not create new directories.

Your test will work if your first create the directory /var/run/shm/tmp before the call to shm_open("/tmp/test", ...). Remember to remove it once you have finished working with the shared memory object. And also note that using object name with two slashes inside might not be portable to other Unix systems.

Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
  • Where can I set the destination path eg: `/dev/shm`? – DDS Dec 13 '22 at 17:50
  • @DDS you can't. On Linux, it searches for a `tmpfs` mount which is usually mounted under `/dev/shm` or `/var/run/shm`. – Hristo Iliev Dec 14 '22 at 12:13
  • in my case either /var/volatile and /run are tempfs and my layout is like this: /tmp -> /var/tmp -> /var/volatile/tmp – DDS Dec 15 '22 at 10:02
2

You need to mount a tmpfs filesystem in /tmp for this:

mihai@keldon:~$ mount | grep shm
shm on /dev/shm type tmpfs (rw,nosuid,nodev,relatime)

Otherwise, it is not possible.

Mihai Maruseac
  • 20,967
  • 7
  • 57
  • 109