Two processes substracting a number using pipe - process

Having difficulty to make two processes comunicate through pipe and substract a number alternatively.
Output should be like:
process1: 9
process2: 8
process1: 7...
What I've did so far:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int p2c[2];
int c2p[2];
int n = 9;
pipe(p2c);
pipe(c2p);
write(p2c[1], &n, sizeof(int));
if(fork() == 0) {
read(p2c[0], &n, sizeof(int));
printf("Got from parent: %d", n);
n--;
write(c2p[1], &n, sizeof(int));
close(p2c[0]);
close(p2c[1]);
close(c2p[0]);
close(c2p[1]);
exit(0);
}
else{
read(c2p[0], &n, sizeof(int));
printf("Got from child: %d", n);
n--;
write(p2c[1], &n; sizeof(int));
close(p2c[0]);
close(p2c[1]);
close(c2p[0]);
close(c2p[1]);
}
return 0;
}
Whith the output:
Got from parent:9
Got from child:8
What's the proper way to get these two processes substract the number till 0?

It makes sense that you're only getting "Got from parent:9 Got from child:8" as a result, you need, you need a while or for loop for both child and parent processes to get what you're expecting, and the stop conditions for those loops are (n < 0) after decrementing n or the write end of pipe get closed:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int p2c[2];
int c2p[2];
int n = 9;
pipe(p2c);
pipe(c2p);
// this is important to prevent deadlock situation, at least one of both processes
// must start a write operation before while loop, unless the read will block and
// and each process still waiting the other to write something on the pipe
write(p2c[1], &n, sizeof(int));
if(fork() == 0) {
int readStatus;
while(1){
readStatus=read(p2c[0], &n, sizeof(int));
// when read returns 0, this means the write end of pipe was closed, so we have to break the loop
// because no more data to recieve
if(readStatus == 0) break;
printf("Got from parent: %d\n", n);
n--;
// we check if n less than 0, if yes we are finished
if(n < 0) break;
write(c2p[1], &n, sizeof(int));
}
close(p2c[0]);
close(p2c[1]);
close(c2p[0]);
close(c2p[1]);
exit(0);
}
else{
int readStatus;
while(1){
readStatus= read(c2p[0], &n, sizeof(int));
if(readStatus == 0) break;
printf("Got from child: %d\n", n);
n--;
if(n < 0) break;
write(p2c[1], &n, sizeof(int));
}
close(p2c[0]);
close(p2c[1]);
close(c2p[0]);
close(c2p[1]);
}
return 0;
}

Related

stringstream segmentation fault

Using linux and g++.
This works:
stringstream ss;
for (int k = 1; k < 1000; k++){
}
This should also works but result in "segmentation fault":
for (int k = 1; k <1000; k++){
stringstream ss;
}
Why?
Thank you Antonio Perez for your reply.
Actually my code was exactly this:
#pragma pack(1)
#include <sstream>
#include <iostream>
int main(){
for (int i = 0; i < 2; i++){
std::stringstream ss;
}
}
Amazingly if I displace the #pragma pack(1) like this:
#include <sstream>
#pragma pack(1)
#include <iostream>
int main(){
for (int i = 0; i < 2; i++){
std::stringstream ss;
}
}
...then no error occurs!
Is there a possible (non-bug) reason for why sstream does not permit packing of its structure?

UDP socket server/client on different machine won't communicate

these code are from https://www.geeksforgeeks.org/udp-server-client-implementation-c/. it runs well when run server and client on same machine.
but if run on two different machine in same network( they can ping each other). then server won't receive Hello from client.
I noticed that both server and client set address INADDR_ANY. this means any machine in the local network, Am I right?
and I tried on client side specify server's ip address. server still won't get message from client.
please give me some clue.
thank you.
server.c
// Server side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// Bind the socket with the server address
if ( bind(sockfd, (const struct sockaddr *)&servaddr,
sizeof(servaddr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
int len, n;
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, ( struct sockaddr *) &cliaddr,
&len);
buffer[n] = '\0';
printf("Client : %s\n", buffer);
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &cliaddr,
len);
printf("Hello message sent.\n");
return 0;
}
client.c
// Client side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from client";
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n, len;
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, (struct sockaddr *) &servaddr,
&len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd);
return 0;
}
in client.c
make following change. ( 192.168.1.1 ) is server's IP address. then they talk.
//servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_addr.s_addr = inet_addr("192.168.1.1");

App keeps crashing with malloc issue objective c and c

Question- I want to be able to run my c code over and over again however after the first execution of it in my objective c it crashes and I receive an error in xcode "Thread 1 EXC_BAD_ACESSS (code=1, address=0x0)". It's really strange because the first time I run it works then any time after that it dies on me. Any help would be greatly appreciated.
Here is my c code
funcc.c
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define BUFLEN 1024
#define MYFREE(x) free(x); x = NULL;
char const *ipcc;
char *statuss;
char *both_words;
char *s1;
char *s2;
char *results;
void concat()
{
**// THIS IS THE LINE I RECIEVE THE EXC_BAD_ACCESS ERROR/////************** results
results = malloc(strlen(s1)+strlen(s2)+1);
strcpy(results, s1);
strcat(results, s2);
both_words = results;
return;
}
char* P(const char *ipAddr)
{
int pipe_arr[2];
char buf[BUFLEN];
pipe(pipe_arr);
if(fork() == 0)
{
dup2(pipe_arr[1], STDOUT_FILENO);
execl("/sbin/ping", "ping", "-c 1", ipAddr, (char*)NULL);
}
else //parent
{
wait(NULL);
read(pipe_arr[0], buf, BUFLEN);
char *xxx = deblank(buf);
char *input = xxx;
char delimiter[] = " ";
char *i, *j, *remainder, *context;
int inputLength = strlen(input);
char *inputCopy = (char*) calloc(inputLength + 1, sizeof(char));
strncpy(inputCopy, input, inputLength);
i = strtok_r (NULL, delimiter, &context);
j = strtok_r (NULL, delimiter, &context);
remainder = context;
s1 = i;
s2 = j;
concat();
char *sx = search(both_words);
//getchar();
}
close(pipe_arr[0]);
close(pipe_arr[1]);
return both_words;
}
void ConnectionMain(){
char *val = P(ipcc);
printf("%s\n", val);
char *valb = "0packets";
if(strcmp(val, valb) == 0)
{
printf("%s\n", "noconnection");
statuss = "noconnection";
//free(concat);
//return "noconneciton";
}
else
{
printf("%s\n", "connected");
statuss = "connected";
//free(concat);
//return "connected";
}
s1 = NULL;
s2 = NULL;
results = NULL;
both_words = NULL;
ipcc = NULL;
}
funcc.h
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
extern const char *ipcc;
extern char *statuss;
//const char *TestConnection(const char *ip);
void ConnectionMain();
Here is my objective c code
ViewCtrl.m
- (void)checkconnection
{
ConnectionMain();
//const char *ipc = [ip UTF8String];
//TestConnection(ipc);
char *statuss1 = "noconnection";
NSString* xx = [NSString stringWithUTF8String:statuss];
//printf("%s\n", statuss);
if(strcmp(statuss, statuss1) == 0)
{
_ip_label.stringValue = #"No Connection";
//I TRIED SETTING THESE BACK TO NULL BUT STILL NO LUCK
// I ALSO TRIED FREE(CONCAT) STILL NO LUCK
ipcc = NULL;
statuss = NULL;
statuss1 = NULL;
}
else
{
//I TRIED SETTING THESE BACK TO NULL BUT STILL NO LUCK
// I ALSO TRIED FREE(CONCAT) STILL NO LUCK
_ip_label.stringValue = #"Connection Success";
ipcc = NULL;
statuss = NULL;
statuss1 = NULL;
}
}
- (IBAction)ipButtonClicked:(id)sender {
//THIS IS WHERE I EXECUTE MY C CODE///////*********
NSString *ip_text = _ip_text_box.stringValue;
const char *ipxx = [ip_text cStringUsingEncoding:NSUTF8StringEncoding];
ipcc = ipxx;
[self checkconnection];
}

Converting int to bytes and switching endian efficiently

I have to do some int -> byte conversion and switch to big endian for some MIDI data I'm writing. Right now, I'm doing it like:
int tempo = 500000;
char* a = (char*)&tempo;
//reverse it
inverse(a, 3);
[myMutableData appendBytes:a length:3];
and the inverse function:
void inverse(char inver_a[],int j)
{
int i,temp;
j--;
for(i=0;i<(j/2);i++)
{
temp=inver_a[i];
inver_a[i]=inver_a[j];
inver_a[j]=temp;
j--;
}
}
It works, but it's not real clean, and I don't like that I'm having to specify 3 both times (since I have the luxury of knowing how many bytes it will end up).
Is there a more convenient way I should be approaching this?
Use the Core Foundation byte swapping functions.
int32_t unswapped = 0x12345678;
int32_t swapped = CFSwapInt32HostToBig(unswapped);
char* a = (char*) &swapped;
[myMutableData appendBytes:a length:sizeof(int32_t)];
This should do the trick:
/*
Quick swap of Endian.
*/
#include <stdio.h>
int main(){
unsigned int number = 0x04030201;
char *p1, *p2;
int i;
p1 = (char *) &number;
p2 = (p1 + 3);
for (i=0; i<2; i++){
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return 0;
}
You can pack it into a function in whatever way you want to use it. The bitwise swap should compile into some pretty neat assembly :)
Hope it helps :)
int tempo = 500000;
//reverse it
inverse(&tempo);
[myMutableData appendBytes:(char*)tempo length:sizeof(tempo)];
and the inverse function:
void inverse(int *value)
{
char inver_a = (char*)value;
int j = sizeof(*value); //or u can put 2
int i,temp;
// commenting this j--;
for(i=0;i<(j/2);i++)
{
temp=inver_a[i];
inver_a[i]=inver_a[j];
inver_a[j]=temp;
j--;
}
}

Get a list of all available network interfaces (en0, en1, en2, etc) with Cocoa?

In my Cocoa application I want to show the user a list of available network interfaces, like Wireshark does:
What is the best way of getting such a list? Does Apple provide a framework for this, or must I use a C API from the standard library or another library?
Better than wrapping ifconfig you shall check the reference of SCNetworkConfiguration which is part of Core Foundation.
Check SCNetworkInterfaceXxx functions for details.
related answer:
Using Cocoa / Objective-C, get currently connected network's security type in Mac OS X
The following code will get all the interfaces from OS X through System Configuration, then use standard C functions to get the IP addresses (where available).
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define IFT_ETHER 0x6
#include <SystemConfiguration/SCDynamicStore.h>
+(void)getInterfaces
{
SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)#"FindCurrentInterfaceIpMac", NULL, NULL);
CFPropertyListRef global = SCDynamicStoreCopyValue (storeRef,CFSTR("State:/Network/Interface"));
id primaryInterface = [(__bridge NSDictionary *)global valueForKey:#"Interfaces"];
for (NSString* item in primaryInterface)
{
if(get_iface_address([item UTF8String]))
{
NSString *ip = [NSString stringWithUTF8String:get_iface_address([item UTF8String])];
NSLog(#"interface: %# - %#",item,ip);
} else
NSLog(#"interface: %#",item);
}
}
static char * get_iface_address (char *interface)
{
int sock;
uint32_t ip;
struct ifreq ifr;
char *val;
if (!interface)
return NULL;
/* determine UDN according to MAC address */
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror ("socket");
return NULL;
}
strcpy (ifr.ifr_name, interface);
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl (sock, SIOCGIFADDR, &ifr) < 0)
{
perror ("ioctl");
close (sock);
return NULL;
}
val = (char *) malloc (16 * sizeof (char));
ip = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
ip = ntohl (ip);
sprintf (val, "%d.%d.%d.%d",
(ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF);
close (sock);
return val;
}
#include <SystemConfiguration/SCDynamicStore.h>
SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)#"FindCurrentInterfaceIpMac", NULL, NULL);
CFPropertyListRef global = SCDynamicStoreCopyValue (storeRef,CFSTR("State:/Network/Interface"));
id primaryInterface = [(__bridge NSDictionary *)global valueForKey:#"Interfaces"];
for (NSString* item in primaryInterface)
{
NSLog(#"%#", item);
}
Your quickest and best bet is to write a wrapper for ifconfig command.