close() on shared memory in osx causes invalid argument error - c

The following code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
int
main(int argc, char **argv)
{
char *p;
int shm_fd;
int error;
size_t len;
if ((shm_fd = shm_open("/somename", O_CREAT | O_RDWR, 0666)) < 0) {
perror("shm_open");
exit(1);
}
error = close(shm_fd);
if (error < 0) {
perror("close");
}
return 0;
}
Works fine on fedora22 x86_64, freebsd 10.2 x86_64. But it fails on OSX 10.10 with
close: Invalid argument
What is wrong with the call on OSX?

Related

I try to print array of integer after I used memcpy in c

Here is my code I tried also to do casting in mmap but it didn't work.
I need that after I use in memcpy *src include array of the shared from integer type and that printf print array of integer(the pid in code). with %d in printf the code not compile and when I use 5p its print me hexadecimal address
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main(int argc, char const *argv[])
{
int shared[3];
void* src = mmap(0,num, PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_SHARED, fd, 0);
if (src == MAP_FAILED)
{
fprintf(stderr, "mmap() failed\n");
exit(EXIT_FAILURE);
}
//placement of shared array and print
for(int i = 0; i < num; i++)
{
if ((pid = fork()) < 0)
{
perror("fork error\n");
}
else
{
//Placement of pid to shared array
shared[i]=getpid();
}
//need to change the permission in map, create a virtual memory
}
memcpy(src,shared, num+1);
printf("%d\n",src);
close(fd);
return 0;
}

msgget function is not implemented

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFF_SIZE 1024
typedef struct {
long data_type;
int data_num;
char data_buff[BUFF_SIZE];
} t_data;
int main(){
key_t msqid;
int ndx = 0;
t_data data;
msqid = msgget( (key_t)1234, IPC_CREAT | 0666);
if ( -1 == msqid)
{
perror( "msgget() fail");
exit( 1);
}
return 0;
}
and next, i do
gcc -o parent parent.c
and next,
./parent
but the result is
msgget() fail: Function not implemented
I don't know why the msgget function is not implemented even though this is just simple code.
How can i fix my code??

infinite loop in shared memory

Within a Ubuntu virtal machine, I have created two c programs called "server" and "client". When I run server with an input (some integer) and then run client afterwards, client will output the integer that I gave to server. This is working with shared memory. My problem is, after client receives the info, it sets a variable to "CONSUMED", and server has a loop that waits for that to happen, but it never seems to work correctly. This all works if I remove the loop altogether, but I need it in there to be able to ensure that client receives the integer and I don't just continue without it happening.
Here is my code for server.c:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include "shm.h"
int main(int argc, char* argv[]){
int retVal = 0;
ShmData *addr;
if(argc != 2){
printf("please enter 1 argument.\n");
return 0;
}
int fd = shm_open("shm.h", O_CREAT | O_RDWR , 0666);
if(fd == -1){
printf("!!!error with shm_open.\n");
}
if(ftruncate(fd, sizeof(ShmData)) == -1){
printf("!!!error with ftruncate.\n");
}
addr = mmap(0, sizeof(ShmData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(addr == MAP_FAILED){
printf("!!!error with mmap.\n");
}
addr->status = INVALID;
addr->data = atoi(argv[1]);
addr->status = VALID;
printf("[Server]: Server data Valid... waiting for client\n");
while(addr->status != CONSUMED){
sleep(1); //THIS LOOP NEVER EXITS
}
printf("[Server]: Server Data consumed!\n");
munmap(addr, 0);
if(close(fd) == -1){
printf("!!!error with close.\n");
}
shm_unlink("smh.h");
printf("[Server]: Server exiting...\n\n\n");
return(retVal);
}
Here is my code for client.c:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include "shm.h"
int main(int argc, char* argv[]){
int retVal = 0;
int fd = shm_open("shm.h", O_CREAT | O_RDWR , 0666);
if(fd == -1){
printf("!!!error with shm_open.\n");
}
ShmData *addr;
addr = mmap(0, sizeof(ShmData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
printf("[Client]: Waiting for valid data ...\n");
while(addr->status != VALID){
sleep(1);
}
printf("[Client]: Received %d\n", addr->data);
addr->status = CONSUMED;
munmap(addr, 0);
printf("[Client]: Client exiting...\n");
return(retVal);
}
And here is the shm.h file:
enum StatusEnum{INVALID, VALID, CONSUMED};
typedef struct{
enum StatusEnum status;
int data;
}ShmData;
I've been banging my head against the computer screen for a long time but I still don't see anything wrong with my code. How can I get this loop to succeed and exit?

Reading and writng with named pipes C

I'm writing a program that should run indefinitely maintaining the value of a variable. Two other programs could change the value of the variable. I use named pipes to receive and send the variable value to external programs.
Here is my code for the manager of the variable.
manager.c:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
char a = 'a';
void *editTask(void *dummy)
{
int fd;
char* editor = "editor";
mkfifo(editor, 0666);
while(1)
{
fd = open(editor, O_RDONLY);
read(fd, &a, 1);
close(fd);
}
}
void *readTask(void *dummy)
{
int fd;
char* reader = "reader";
mkfifo(reader, 0666);
while(1)
{
fd = open(reader, O_WRONLY);
write(fd,&a,1);
close(fd);
}
}
int main()
{
pthread_t editor_thread, reader_thread;
pthread_create(&editor_thread, NULL, editTask, NULL);
pthread_create(&reader_thread, NULL, readTask, NULL);
pthread_join (editor_thread, NULL);
pthread_join (reader_thread, NULL);
return 0;
}
This program uses pthreads to separately get external values for the variable and to communicate the current value of the variable to external programs.
The program that is able to write values to the variable is:
writer.c:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char** argv)
{
if(argc != 2)
{
printf("Need an argument!\n");
return 0;
}
int fd;
char * myfifo = "editor";
fd = open(myfifo, O_WRONLY);
write(fd, argv[0], 1);
close(fd);
return 0;
}
The program that could read the current value is:
reader.c:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd;
char * myfifo = "reader";
fd = open(myfifo, O_RDONLY);
char value = 'z';
read(fd, &value, 1);
printf("The current value of the variable is:%c\n",value);
close(fd);
return 0;
}
I ran these programs in my Ubuntu system as follows:
$ ./manager &
[1] 5226
$ ./writer k
$ ./reader
bash: ./reader: Text file busy
Why doesn't my system allow me to run this program?
Thank you.
You are trying to call both the FIFO and the reader program "reader".
Also, you have no error checking. You have no idea whether those calls to mkfifo and open succeeded or not. Adding this is critical before you attempt to do any troubleshooting.

problem with O_DIRECT IO with aligned stack buffer

The following code fails when the buffer is on the stack, but succeeds when it's allocated on the heap. I tested it on RHEL 5.3 with a Raid drive. Is it possible to use O_DIRECT with stack buffers?
#define _GNU_SOURCE
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <malloc.h>
#define K 1024
#define ALIGNMENT (4*K)
#define RDSIZE (16*K)
#define BLOCKSIZE (512*K)
int main()
{
int flags = O_RDONLY | O_LARGEFILE;
int n = 0;
int fd = 0;
char* buf = (char *) memalign(ALIGNMENT, BLOCKSIZE);
//char buf[BLOCKSIZE] __attribute__((__aligned__(ALIGNMENT)));
assert(((long)buf) % ALIGNMENT == 0);
fd = open("test", flags | O_DIRECT);
if (fd < 0) {
perror("file open");
return -1;
}
n = read(fd, buf, RDSIZE);
if (n < 0) {
perror("file read");
return -1;
}
printf("%d\n", n);
close(fd);
}
UPDATE: Same code when compiled with Intel CC succeeds.
Check your stack size 512K is quite a lot.
If the problem is gcc misaligning buf, try this portable version instead:
char x_buf[BLOCKSIZE+PAGE_SIZE];
char *buf = buf + (PAGE_SIZE-1 & -(uintptr_t)x_buf);

Resources