I am using sigaction for a signal and I am using a simple struct for that. I actually took it from the man page. Can someone explain to me what does the second line in the struct do? Also there is an error there:
error: expected declaration specifiers or '...' before 'siginfo_t'
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <assert.h>
#include <getopt.h>
#include <signal.h>
#include <sys/time.h>
#define _POSIX_C_SOURCE 200112L
#define MAX_WORD 256
void parseFile (FILE * fp, FILE *sketcher);
void handle_timeout(int signal);
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
You are not supposed to declare the struct sigaction yourself. It is provided in the man page for your information, but it is actually declared by <signal.h>.
The second line in the struct defines a function pointer (as does the first, but with a different type).
Related
I'm trying to write a webserver in C, and I have a header file called route.h. Inside route.h I have the line typedef void (*RouteHandler)(struct HTTPRequest *, struct HTTPResponse *); which I believe creates the typedef RouteHandler which is a function that returns nothing, and takes two pointers to structs as arguments. Also inside route.h is this struct:
struct RouteTableEntry {
enum HTTPMethod method;
char *route;
RouteHandler handler;
};
This code compiles just fine, however when I try and use the typedef in a different header, server.h, I get the compiler error: server.h:27:8: error: unknown type name ‘RouteHandler’.
Here is my code:
route.h
#ifndef ROUTE_H_GUARD_
#define ROUTE_H_GUARD_
#include <stdlib.h>
#include "http.h"
#include "server.h"
typedef void (*RouteHandler)(struct HTTPRequest *, struct HTTPResponse *);
struct RouteTableEntry {
enum HTTPMethod method;
char *route;
RouteHandler handler;
};
...
#endif
server.h
#ifndef SERVER_H_GUARD_
#define SERVER_H_GUARD_
#include <stdint.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <pthread.h>
#include "http.h"
#include "route.h"
...
extern RouteHandler get_handler(enum HTTPMethod method, char *route, RouteHandler handler);
...
#endif
(I've reduced the code to just the relevant parts - if the full thing is necessary I will post the rest)
Your route.h itself includes server.h, and this before the beginning of the scope of the typedef. It is while processing that inclusion of server.h that the compiler complains, rightly, that there is no declaration of type RouteHandler in scope.
If indeed route.h and server.h each require something that the other declares then it is time to refactor. You haven't provided enough details for us to offer specific suggestions, but the kind of circular dependency you presently have will cause you continuing grief.
On the other hand, if route.h actually doesn't need anything from server.h then it ought not to be including it.
I am checking socket options and I got this error when I compile. I tried to google it and it looks like no one has encountered this problem before.
#include <netinet/tcp.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
static char *sock_str_flag(union val *, int);
struct sock_opts {
const char *opt_str;
int opt_level;
int opt_name;
char *(*opt_val_str)(union val *, int);
}sock_opts[] = {
{ "SO_USELOOPBACK", SOL_SOCKET, SO_USELOOPBACK, sock_str_flag } //this is the error
};
The socket option SO_USELOOPBACK is not a POSIX standard. The man page setsockopt() describes the nature of SO_USELOOPBACK in detail.
The SO_USELOOPBACK is a [Digital] standard. Text paragraphs preceded by [Digital] document features that are included in the DIGITAL UNIX software but are not currently specified by any standard that applies to the interface being described. Use these features when source code portability across multiple UNIX platforms is less important than the capabilities that the features provide.
For portability, you need to have ifdef checks.
struct sock_opts {
const char *opt_str;
int opt_level;
int opt_name;
char *(*opt_val_str)(union val *, int);
}sock_opts[] = {
/* .... */
#ifdef SO_USELOOPBACK
{"SO_USELOOPBACK", SOL_SOCKET, SO_USELOOPBACK, sock_str_flag }
#endif
/* .... */
};
I am following the code in Chapter 3 of "Learning Linux Binary Analysis". The code is, "A simple ptrace-based debugger".
I am trying to write this in my Raspberry Pi 3, which has an ARM processor. I know that the error means that I have not included the correct header file, but I cannot find what the correct header file is.
I get this error message:
field ‘pt_reg’ has incomplete type struct user_regs_struct pt_reg
After doing some research, I found asm/ptrace.h, which includes some macros for the registers struct specific to ARM. Am I on the right track? How in the world can I make this work with an ARM processor?
Here are the headers:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <elf.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/stat.h>
#include <sys/ptrace.h>
#include <sys/mman.h>
typedef struct handle {
Elf64_Ehdr *ehdr;
Elf64_Phdr *phdr;
Elf64_Shdr *shdr;
uint8_t *mem;
char *symname;
Elf64_Addr symaddr;
struct user_regs_struct pt_reg;
char *exec;
} handle_t;
Hey guys I am messing around with signals, and have a weird error:
I want to set a value to the member sa_sigaction but IDE and compiler seem to not find it..
#define _POSIX_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <bits/siginfo.h>
struct sigaction new_action;
void SIGUSR1_handler(int sig, siginfo_t *siginfo, void *context) {
......
}
memset(&new_action, '\0', sizeof(new_action)); //cleaning the memory
new_action.sa_sigaction = SIGUSR1_handler; //setting the handler for the signal
new_action.sa_flags = SA_SIGINFO;
I only posted the relevant part of the code.
Can anybody help me out here?
EDIT: And how can I put something in the siginfo struct or context pointer?
You don't specify your OS so I can't be sure, but I think the problem is that you're inadvertently requesting an ancient version of POSIX that lacks it via the following incorrect feature test macro usage:
#define _POSIX_SOURCE
The _POSIX_SOURCE macro itself is deprecated; you should be using _POSIX_C_SOURCE and defining it to the version of the API you want. To ensure the availability of a working sigaction, you probably want:
#define _POSIX_C_SOURCE 200809L
since it was (if I recall correctly) an XSI extension in earlier versions of the standard. Alternatively you might use:
#define _XOPEN_SOURCE 600 /* or 700 */
since the functionality you want was available as an XSI extension in Issue 6.
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.