In C, is it possible to have a struct nested within another struct? How would I access the fields of the inner struct? Take the struct for kinfo_proc for example:
struct kinfo_proc {
struct extern_proc kp_proc; /* proc structure */
struct eproc {
struct proc *e_paddr; /* address of proc */
struct session *e_sess; /* session pointer */
struct _pcred e_pcred; /* process credentials */
struct _ucred e_ucred; /* current credentials */
struct vmspace e_vm; /* address space */
pid_t e_ppid; /* parent process id */
pid_t e_pgid; /* process group id */
short e_jobc; /* job control counter */
dev_t e_tdev; /* controlling tty dev */
pid_t e_tpgid; /* tty process group id */
struct session *e_tsess; /* tty session pointer */
#define WMESGLEN 7
char e_wmesg[WMESGLEN+1]; /* wchan message */
segsz_t e_xsize; /* text size */
short e_xrssize; /* text rss */
short e_xccount; /* text references */
short e_xswrss;
int32_t e_flag;
#define EPROC_CTTY 0x01 /* controlling tty vnode active */
#define EPROC_SLEADER 0x02 /* session leader */
#define COMAPT_MAXLOGNAME 12
char e_login[COMAPT_MAXLOGNAME]; /* short setlogin() name */
#if CONFIG_LCTX
pid_t e_lcid;
int32_t e_spare[3];
#else
int32_t e_spare[4];
#endif
} kp_eproc;
};
How would I go about trying to get the e_ppid of a newly made kinfo_proc instance?
You would be creating something like :
struct kinfo_proc test1;
test1.kp_eproc.e_ppid /// Access it like this.
Related
how to use long options via getopt_long:
for example like this:
--wide-option
I have --wide and -w.
And on --wide-option it gives the following error:
"unrecognized option"
int main(int argc, char **argv)
{
struct option opts[] =
{
{"wide", 1, 0, 'w'},
{
0, 0, 0, 0
}
};
int option_val = 0;
int counter = 10;
int opindex = 0;
while ((option_val = getopt_long(argc, argv, "w:", opts, &opindex)) != -1)
{
switch (option_val)
{
case 'w':
if (optarg != NULL)
counter = atoi(optarg);
for (int i = 0; i < counter; i++)
printf("Hello world\n");
break;
default:
return 0;
}
}
return 0;
}
If you look at the cat source code (here), you can see that --number and --number-nonblank are two different options (-b and -n). (near line 555).
If you want to do the same, you can that way:
#include <getopt.h>
#include <stdio.h>
int main(int argc, char **argv)
{
struct option opts[] =
{
{"wide", 1, 0, 'w'},
{"wide-option", 0, 0, 'o'}, /* declare long opt here */
{
0, 0, 0, 0
}
};
int option_val = 0;
int counter = 10;
int opindex = 0;
while ((option_val = getopt_long(argc, argv, "w:o", opts, &opindex)) != -1) /* the case here (I arbitrary choose 'o') */
{
switch (option_val)
{
case 'w':
if (optarg != NULL)
counter = atoi(optarg);
printf("option --wide %d found!\n", counter);
for (int i = 0; i < counter; i++)
printf("Hello world\n");
break;
case 'o': /* and take the case into account */
printf("option --wide-option found!\n");
break;
default:
return 0;
}
}
return 0;
}
I have this function and once in a while it causes a buffer overflow error at the line in bold which is memcpy(&(sin6->sin6_addr), &(inet->address[0]), 16);
Tried executing this function outside of the application, it never caused an issue. What do you all think why would an app crash at this call?
struct mariyo_inet {
uint8_t length; /* Generally 4 or 16- the length of the address, in bytes. */
uint8_t netmask; /* The number of significant bits in the address. */
uint8_t address[16]; /* The address itself. */
} __attribute__((packed));
void mariyo_inet_to_sockaddr(struct mariyo_inet *inet, struct sockaddr *sock, socklen_t *len, uint16_t port_ne)
{
if (inet->length == 16) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sock;
sin6->sin6_family = AF_INET6;
sin6->sin6_port = port_ne;
#ifndef __linux__
sin6->sin6_len = sizeof(*sin6);
#endif
if (len) *len = sizeof(*sin6);
**memcpy(&(sin6->sin6_addr), &(inet->address[0]), 16);**
} else if (inet->length == 4) {
struct sockaddr_in *sin = (struct sockaddr_in *) sock;
sin->sin_family = AF_INET;
sin->sin_port = port_ne;
#ifndef __linux__
sin->sin_len = sizeof (*sin);
#endif
if (len) *len = sizeof(*sin);
memcpy(&(sin->sin_addr),
&(inet->address[0]),
4);
}
}
Here is the application stacktrace,
#7 0x00000000007c94b9 in mariyo_inet_to_sockaddr (inet=inet#entry=0x7ff31a7da940, sock=sock#entry=0x7ff31a7da900, len=len#entry=0x7ff31a7da8f0, port_ne=port_ne#entry=0) at mariyo.c:4959
sin6 = 0x7ff31a7da900
#8 0x000000000062847a in enzyme_mconn_icmp_transmit_cb () at enzyme_mconn_icmp.c:522
ret = <optimized out>
mconn_icmp = <optimized out>
icmp_buf_len = <optimized out>
icmp_linear_buf = 0x61d000d6cec8 "E"
iph = 0x61d000d6cec8
iph_len = <optimized out>
icmp_hdr = <optimized out>
icmpreq_cookie = 0x604000845f68
icmpinfo = 0x619000355298
icmpfail_cookie = <optimized out>
ip_tlen = 1228
#9 0x0000000000603595 in enzyme_mconn_dequeue_data (mconn=mconn#entry=0x624010002b90, need_to_lock=0) at enzyme_mconn.c:547
ret = 0
tx_len = 1228
__FUNCTION__ = "enzyme_mconn_dequeue_data"
#10 0x0000000000608ee5 in enzyme_mconn_send_data_to_client (mconn=mconn#entry=0x624010002b90, buf=buf#entry=0x60e000188218, buf_len=buf_len#entry=1228, need_to_lock=need_to_lock#entry=1) at enzyme_mconn.c:668
res = 0
enq_len = <optimized out>
drop_len = <optimized out>
__FUNCTION__ = "enzyme_mconn_send_data_to_client"
#11 0x0000000000609b42 in enzyme_client_process_rx_data (mconn=mconn#entry=0x624010003148, buf=buf#entry=0x60e000188218, buf_len=buf_len#entry=1228) at enzyme_mconn.c:952
peer = 0x624010002b90
res = <optimized out>
__FUNCTION__ = "enzyme_client_process_rx_data"
ip_proto = <optimized out>
This is how it looks at the caller,
int mariyo_string_to_inet(const char *in_str, struct mariyo_inet *inet)
{
char tmp[51];
//
// filling tmp here from in_str
//
/* IPv4 + IPv6 in same address == bad */
if (saw_dot || saw_colon) {
if (saw_colon) {
/* IPv6 (Note: Supports IPv4 in IPv6) */
if (!inet_pton(AF_INET6, tmp, &(inet->address[0]))) {
//fprintf(stderr, "%s:%d: Could not parse IP address <%s>\n", __FILE__, __LINE__, tmp);
return 1;
}
if (!slash) netmask = 128;
if (netmask > 128) {
//fprintf(stderr, "%s:%d: Bad netmask > 128 on IP address <%s>\n", __FILE__, __LINE__, in_str);
return 1;
}
inet->length = 16;
}
return 0;
}
{
.....
socklen_t sock_len;
struct mariyo_inet inet_ip;
struct sockaddr sock_addr;
memset(&inet_ip, 0, sizeof(struct mariyo_inet));
mariyo_string_to_inet(icmpinfo->probe_info.dest_ip, &inet_ip);
memset(&sock_addr, 0, sizeof(struct sockaddr));
mariyo_inet_to_sockaddr(&inet_ip, &(sock_addr), &sock_len, 0);
....
}
struct sockaddr is not guaranteed to be large enough (and usually isn't) to hold an IPv6 address.
Use struct sockaddr_storage instead.
I am modding a game script where I can locate something in my minimap by getting the specific x,y coordinates. For that, I made a file that stores those values like this :
LocationName
X position
Y position
So, I came out with that code to read them
for line in file:lines() do
if string.find(line, Location) then
var1 = file:read("*line")
var2= ??????????????
end
end
The X position can be easily read using the read("*line"), But how am I supposed to read the Y position that is underneath?
This works fine:
var1 = file:read("*line")
var2 = file:read("*line")
In this program the char *token is initialized with a weird garbage value.I am unable to sort it out. Here's the source code:
#include<iostream>
#include<string.h>
#include<stdlib.h>
void fetch_value(char *string,int pos,char *dest)
{
char *token;
int i=0;
token=strtok(string,",");
if(pos>1)
{
token=strtok(NULL,",");
while(i<pos-1){
token=strtok(NULL,",");
printf("token =%s\n",token);
i++;
}
strcpy(dest,token);
}
else
{
strcpy(dest,token);
}
}
int main(void)
{
char checking[100];
memset(checking,0x00,sizeof(checking));
fetch_value("14174000100,35679700322,35679700322,35679700322,
35679700322,14174000999,919440710210000,1",0,checking);
printf("checking=%s\n",checking);
return 0;
}
Your help, feedback or suggestions is greatly appreciated.
The first argument of strtok must be modifiable. Your code passes a string literal, which is not modifiable. This leads to undefined behavior.
The simplest modification that will fix the problem is as follows:
char numList[] = "14174000100,35679700322,35679700322,35679700322,35679700322,14174000999,919440710210000,1";
fetch_value(numList, 0, checking);
You should also note that strtok is an older function which is not reentrant, because it uses static variables to save its state. In the new code you should use the reentrant version of the function - strtok_r, which requires you to pass memory for saving the state.
Do this instead:
int main(void)
{
char checking[100];
memset(checking,0x00,sizeof(checking));
char string[] = "14174000100,35679700322,35679700322,35679700322,
35679700322,14174000999,919440710210000,1";
//now string can be modified.
fetch_value(&string[0],0,checking);
printf("checking=%s\n",checking);
return 0;
}
How can I rearrange an array if I know where to put each element in array without using temporary array?
I guess, This has something to do with cyclic permutation but I cannot figure out how they can be linked each other. Wiki page seems irrelevant to me(http://en.wikipedia.org/wiki/Cyclic_permutation)
If you know both where to put each element in the array, and also which element of the array belongs at a specific index, then you can use that information to optimise your rearrangement. Otherwise you can iterate over all the array elements exchanging them into the correct location until they are all correctly placed.
void permuteObjects(Object[] elements, int[] positions)
{
for (int i = 0; i < elements.length; ++i) {
while (positions[i] != i) {
swapObjects(elements, i, positions[i]);
swapIntegers(positions, i, positions[i]);
}
}
}
If you can boil down the "re-arrangement" of your array to single permutations, i.e. to swapping the values of two elements then you can use the XOR to perform the swap without additional variable.
Here a sample code from the linked Wikipedia article:
void xorSwap (int *x, int *y) {
if (x != y) {
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
Why not just use a temporary array and terminate it by setting it to null?
Maybe take a look at http://docs.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html
HashMaps dynamicly increase when adding new items.
Use like this:
HashMap<Integer, WhatEverYouWantToStore> = new HashMap<Integer, WhatEverYouWantToStore>();
Maybe try this:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class sort {
public static void main(String[] args) {
List list = new ArrayList();
String country[] = { "India", "Japan", "USA", "UK", "Nepal" };
for (int i = 0; i < 5; i++) {
list.add(country[i]);
}
Collections.sort(list);
Iterator i = list.iterator();
while (i.hasNext()) {
System.out.print(i.next() + "\t");
}
}
}