Segmentation fault setup semaphore function - c

I got the shared_memory.c file where I'm declaring my functions. One of the functions will be setupSemaphoreRead().
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <fcntl.h>
#include "shared_memory.h"
//more code...
int setupSemaphoreRead(){
sem_unlink(SEM_CONSUMER_FNAME);
sem_unlink(SEM_PRODUCER_FNAME);
sem_t *sem_prod = sem_open (SEM_PRODUCER_FNAME, O_CREAT | O_EXCL, 0666, 0);
if (sem_prod == SEM_FAILED) {
perror("sem_open/producer");
return -1;
}
sem_t *sem_cons = sem_open (SEM_CONSUMER_FNAME, O_CREAT | O_EXCL, 0666, 1);
if (sem_cons == SEM_FAILED) {
perror("sem_open/consumer");
return -1;
}
return 1;
}
//more code...
I got the signature declared at my header file
int setupSemaphoreRead();
//filenames for two semaphores
#define SEM_PRODUCER_FNAME "myproducer"
#define SEM_CONSUMER_FNAME "myconsumer"
In my main read program I'm trying to use the function in the fallowing way:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "shared_memory.h"
...
sem_t *sem_cons;
sem_t *sem_prod;
setupSemaphoreRead();
...
I don't get any error when compiling the code, but when executing I got Segmentation fault (core dumped)

setupSemaphoreRead() assigns to sem_t * local variables. When it returns those variables are out of scope. It has no access to variables of the same name in the other scope. You need to study more how variable scopes work in C. A typical way to do what you're trying to do is have a function accept double-pointer arguments like:
int setupSemaphoreRead(sem_t** sem_cons, sem_t** sem_prod) {
*sem_cons = ...
..
and use it like:
sem_t* sem_cons;
sem_t* sem_prod;
int ret = setupSempahoreRead(&sem_cons, &sem_prod);
// Make sure to check the value of ret

You have
sem_t *sem_prod
both inside the function and inside main. In other words - they are different variables, i.e. the variables in main are not updated by the function.

Related

Getter & Setter in C

i'm facing a problem in C where i'm trying to use some getter and setter to share a variable between multiple source file.
I declare here my variable (ok_button) with a getter and a setter:
variable.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include "../libhd_src/libhd.h"
int ok_button;
void set_ok_button(int value){
ok_button=value;
printf("Setting ok");
}
int get_ok_button(){
return ok_button;
}
Here, when i push a button, it sets the variable to 1. (Can't upload the full code of this source file, but i see in my logs that the function set_ok_button is correctly execuded when i press (i see the printf "Setting OK" everytime i press my button))
button.c
#include "../libhd_src/libhd.h"
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
void * button_back_center_short(void *arg){
set_ok_button(1);
return 0;
}
And here, i simply check the value of my variable with the getter function.
read.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include "../../libhd_src/libhd.h"
int main(int argc, char **argv){
while(1){
printf("Value %d", get_ok_button());
usleep(500000);
}
}
The problem is that the value shown in read.c is always "0" even when i press my button and set the value to 1...
Does someone understand what's wrong ? Feel free to tell me if you see a better solution to do that :)
I think your problem may be that you have multiple set_ok_button and get_ok_button functions in different files. Make sure you only have them defined in one file, and in a header add 2 lines declaring (but not defining) the functions:
void set_ok_button(int value);
int get_ok_button();

handling warning: implicit declaration of function ‘sigignore’

Here's my code:
#include <sys/types.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
int main(int argc, char** argv) {
sigignore(SIGTERM);
return 0;
}
Why do I get the following warning and how could I remove it?
implicit declaration of function ‘sigignore’
[-Wimplicit-function-declaration] sigignore(SIGTERM);
The program must be compiled like this: gcc -o foo.o foo.c.
Thanks
Man sigignore tells you to use #define _XOPEN_SOURCE 500 to enable sigignore. More on X/Open can be found here
The function you want to call has been marked as obsolete 15 years ago. The normal way to discourage people from using those functions (without actually breaking programs) is to have the implementation of the function left in the standard library, but remove the declaration from header files (or at least make it hard to enable).
Use sigaction or sigprocmask (depending on what you actually want to accomplish).

"‘sockaddr_in’ undeclared (first use in this function)" error despite including the requisite headers

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <ifaddrs.h>#include <net/if.h>
#include <stdarg.h>
#define BACKLOG 10
void * get_in_addr(struct sockaddr *sa){
if(sa->sa_family == AF_INET){
return &((sockaddr_in *)sa)->sin_addr;
}
else if(sa->sa_family == AF_INET6){
return &((sockaddr_in6 *)sa)->sin6_addr;
}
}
I am using the sockaddr_in struct in my code to chekc whether an incoming connection is an IPv4 or an IPV6 address. I get the error "‘sockaddr_in’ undeclared (first use in this function)" here despite including the netinet/in.h header in my code. Is there something that I am not seeing here?
sockaddr_in is not typedef, so try using it with struct like following
(struct sockaddr_in *)

Storage size of sockaddr_in variable isn't known

I have a piece of code that used to work in some environment a long time ago. I'm pretty sure it was a FreeBSD machine so I got FreeBSD 8.3 and I'm trying to make this file but it's not working.
When I try to compile it it complains with:
f.c: In function 'tcp'>
f.c:24: error: storage size of 'socket_stru' isn't known
f.c:29: error: 'IPPROTO_TCP' undeclared (first use in this function)
...
I've been looking around and I see these are all specified in the sys/socket.h file. This is my actual file:
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
#include "f.h"
int tcp4 (in_addr_t ip, int port, int qsize )
{
struct sockaddr_in socket_stru; // line 24
socket_stru.sin_family = AF_INET;
socket_stru.sin_port = htons(port);
socket_stru.sin_addr.s_addr = ip;
int actual_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // line 29
...
I feel like my code somehow doesn't "read" the sys/socket.h file so it doesn't know about socket_stru and IPPROTO_TCP, but I'm just really lost.
Any ideas?
None of the other answers worked for me. After taking a look inside the sys/socket.h file, I didn't even see a definition for struct sockaddr_in.
What worked for me was to #include one of the following files when using the corresponding struct sockaddr_* type:
if you're using struct sockaddr_in, #include <netinet/in.h>
if you're using struct sockaddr_un, #include <sys/un.h>
if you're using struct sockaddr_ns, #include <netns/ns.h>
if you're using struct sockaddr_ndd, #include <sys/ndd_var.h>
More information on the header files for socket programming can be found here.
I cut and paste your code into a file (removing only the #include f.h and closed off the function call.) It compiles just fine on Linux.
I suspect there may be header files differences on BSD. For socket programming, I typically include ALL these header files. And I know my socket code compiles on BSD as well. I suspect one of these header files brings in the definition for sockaddr_in. I recall when I ported by socket code to BSD, I had to explicitly add a few of these.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <stdarg.h>
/* the next two includes probably aren't relevant for you, but I typically use them all anyway */
#include <math.h>
#include <sys/termios.h>
Hope this helps
I had the same problem, but the following include fixed the issue for me
#include <arpa/inet.h>
Just add #include <resolv.h> to your source and you are good to go.
According to freebsd developer's handbook you need
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

Reading Garbage with shmget

I have created two processes. One of them creates a shared memory chunk and the other tries to read it. There are no compilation errors with this code but somehow Process 2 behaves weird.
Process 1:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#define nDEVICES 3
#define DEVICE_NAME_LIMIT 20
typedef struct d_list
{
char d_name[DEVICE_NAME_LIMIT];
int d_id;
}device_mapping;
int main()
{
key_t shared_memkey_D=ftok(".", 'D');
int shared_memid_D=shmget(shared_memkey_D, nDEVICES*sizeof(device_mapping), 0777|IPC_CREAT|IPC_EXCL);
device_mapping *DEVICES = (device_mapping*)shmat(shared_memid_D,0,0);
strcpy(DEVICES[0].d_name, "DISK");
strcpy(DEVICES[1].d_name, "PORT");
strcpy(DEVICES[2].d_name, "PRINTER");
DEVICES[0].d_id=1;
DEVICES[1].d_id=3;
DEVICES[2].d_id=2;
}
Process 2:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>
#define nDEVICES 3
#define DEVICE_NAME_LIMIT 20
typedef struct d_list
{
char d_name[DEVICE_NAME_LIMIT];
int d_id;
}device_mapping;
int main()
{
key_t shared_memkey_D=ftok(".", 'D');
int shared_memid_D=shmget(shared_memkey_D, nDEVICES*sizeof(device_mapping), 0777);
device_mapping *DEVICES = (device_mapping*)shmat(shared_memid_D,0,0);
int i=0;
for (i=0; i<nDEVICES; i++)
printf("%s\t%d\n", DEVICES[i].d_name, DEVICES[i].d_id);
}
Process 2 is reading all garbage and I cannot figure out what is going wrong after several attempts. Please help.
EDIT:
I had copied the wrong program here. I have made the corrections. Its still giving me garbage.
Process 2 prints the following:
DISK 11038
?FG+ 3
#?FG+ 2
/* process 1 */
typedef struct d_list
{
char d_name[DEVICE_NAME_LIMIT];
int d_id;
}device_mapping;
and
/* process 2 */
typedef struct d_list
{
char * d_name;
int d_id;
}device_mapping;
are not the same.
Change device_mapping definition for process 2 to be the same as for process 1, using characters arrays but character pointers.
For process 1 d_name uses DEVICE_NAME_LIMIT bytes, for process 2 d_name uses 4 bytes (32bit) or 8 bytes (64bit).
I'd put the common structure definitions into a shared header file, which is included by both pocesses' sources.

Resources