LINUX shm_open::Bad file descriptor / (SGI Runs Well)

Hello,

Does anyone know why I get the message on the subject line when I execute the following code on Linux and/or how to fix it?

The routine appears to run nicely on SGI!

Note: The program compiles on Linux with the -lrt option.

Thank you, Christopher Lusardi

------------------------- Routine ---------------------------

#include #include #include #include #include #include #include #include

int initialize () { int my_size; void *my_ptr; int my_memory;

my_size = 0x100000; /* number of bytes */

my_memory = shm_open ("/var/tmp/my_memory", (O_RDWR | O_CREAT), (S_IRWXO | S_IRWXG | S_IRWXU)); /* r/w others group users */

chmod ("/var/tmp/my_memory",(S_IRWXG | S_IRWXU)); /* g/u */

ftruncate (my_memory,my_size); /* Truncate CREATE file! */ if ( my_memory == -1 ) { perror (shm_open:"); exit (1); }

ptr = (void *) mmap (NULL,my_size,(PROT_READ | PROT_WRITE), (MAP_SHARED),my_memory,0); /* memory */

if ( ptr == MAP_FAILED ) { perror ("mmap"); exit (1); }

if ( close (shmd) ) { perror ("close"); exit (1); }

return (ptr); }

/********************* Caller Routine **********************/

int main () { (void) initialize (); /* check stubbed routine */ }

Reply to
Christopher M. Lusardi
Loading thread data ...

the following is a mistake, and is confusing you.

The problem is that either the chmod or the ftruncate could have changed errno. And likely did.

Test my_memory only *immediately* after the shm_open if you want the perror to report anything even remotely meaningful. And test the result codes from chmod and ftruncate (immediately after each operation, of course)!

David Anderson

Reply to
David Anderson

Hello,

After changing my code to use the file "my_memory" instead of "/var/tmp/my_memory", it compiled and ran on Linux!

How can I change the code to use "/var/tmp/my_memory" instead of "my_memory"?

Can you find anything else wrong with my code?

Thanks for reading my postings, Christopher Lusardi

Reply to
Christopher M. Lusardi

: After changing my code to use the file "my_memory" instead of : "/var/tmp/my_memory", it compiled and ran on Linux! : : How can I change the code to use "/var/tmp/my_memory" instead of : "my_memory"? : : Can you find anything else wrong with my code?

shm_open creates shared memory objects, not files. You should therefore not assume that shm objects will appear in the filesystem namespace either at all or where you might expect them to appear.

It is therefore incorrect to make a call to chmod(), you should call fchmod() instead.

The puzzle, of course, is what is the most correct name for the shm object? The linux manpage suggests that the portable solution is for the name to contain only a leading slash and no other slashes, thus the name would be "/my_memory".

Unfortunately IRIX does place the SHM objects directly into the filesystem namespace, so "/my_memory" would attempt to create the file in the root directory of the filesystem, which is undesired.

In linux, shm objects are usually created in a separate ram-based filesystem mounted at /dev/shm. This filesystem (for obvious reasons) does not contain a "var/tmp/" directory, and is in fact usually very empty.

I would suggest the following code: (you should also make the corrections that David Anderson suggests)

Cut Here --88-- Cut Here

#include #include #include #include #include #include #include #include

#ifdef __sgi #define SHM_NAMESPACE "/var/tmp/" #else #define SHM_NAMESPACE "/" #endif

void * initialize() { int my_size; void *my_ptr; int my_memory;

my_size = 0x100000; /* number of bytes */

my_memory = shm_open(SHM_NAMESPACE "my_memory", (O_RDWR | O_CREAT), (S_IRWXO | S_IRWXG | S_IRWXU)); /* r/w others group users */

fchmod(my_memory, (S_IRWXG | S_IRWXU)); /* g/u */

ftruncate(my_memory, my_size); /* Truncate CREATE file! */

if (my_memory == -1) { perror("shm_open:"); exit(1); }

my_ptr = (void *) mmap(NULL, my_size, (PROT_READ | PROT_WRITE), (MAP_SHARED), my_memory, 0); /* memory */

if (my_ptr == MAP_FAILED) { perror("mmap"); exit(1); }

if (close(my_memory)) { perror("close"); exit(1); }

return (my_ptr); }

/********************* Caller Routine **********************/

int main() { (void) initialize(); /* check stubbed routine */ }

Cut Here --88-- Cut Here

Cheers - Tony 'Nicoya' Mantler :)

--
Tony 'Nicoya' Mantler -- Master of Code-fu -- nicoya@ubb.ca
--  http://nicoya.feline.pp.se/  --  http://www.ubb.ca/  --
Reply to
Tony 'Nicoya' Mantler

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.