I am trying to use low level IO (Read) to read in standard input for a command. After getting that command I try to pass it into execvp so that it can carry out the command but it is not working. I think the problem is I am not sure how to pass it into execvp properly. It worked before with command line arguments but I cant get standard input working.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char* argv[])
{
int r;
char b1[4096];
char command[4096];
r = read(STDIN_FILENO, b1, 4096);
memcpy(command, b1, r);
command[r] = '\0';
//printf("%s\n", command);
char* progname = command;
//char* progname = argv[1];
pid_t pid;
if ((pid = fork()) < 0) perror("fork");
else if (pid == 0) { // child process
if (execvp(progname, argv + 1) == -1) {
perror("execvp");
return EXIT_FAILURE;
} // if
} // if
else {
fprintf(stderr, "Please specify the name of the program to exec as a command line argument\n");
return EXIT_FAILURE;
} // if
} // main
Related
Using Poco-1.12.4-release and g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, The recommended example code for DatagramSocket Receive in this doc:
https://pocoproject.org/slides/200-Network.pdf
compiles with this error:
dgs.cpp: In function ‘int main(int, char**)’:
dgs.cpp:34:33: error: no matching function for call to ‘Poco::Net::DatagramSocket::DatagramSocket(Poco::Net::SocketAddress&)’
34 | Poco::Net::DatagramSocket dgs(sa);
What happened? Is there a fix for this example?
Thanks
The code is:
// DatagramSocket receive example
#include "Poco/Net/DatagramSocket.h"
#include "Poco/Net/SocketAddress.h"
#include <iostream>
int main(int argc, char** argv)
{
Poco::Net::SocketAddress sa(Poco::Net::IPAddress(), 514);
Poco::Net::DatagramSocket dgs(sa);
char buffer[1024];
for (;;)
{
Poco::Net::SocketAddress sender;
int n = dgs.receiveFrom(buffer, sizeof(buffer)-1, sender);
buffer[n] = '\0';
std::cout << sender.toString() << ": " << buffer << std::endl;
}
return 0;
}
I tried this:
Poco::Net::SocketAddress sa(Poco::Net::IPAddress(), 514);
Poco::Net::DatagramSocket dgs(Poco::Net::SocketAddress::IPv4);
dgs.connect(sa);
It compiles, but is it correct?
I have a sample program which creates a pthread, waits for the thread to join. The thread will invoke phread_cond_timedwait() to wait for 2 seconds. On Linux platforms, the sample code works fine. On FreeBSD, the call returns immediately with EPERM error code.
pthread_condition_timedwait.cpp
#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
void *thread_handler(void *ptr){
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
struct timespec ts;
struct timeval tp;
gettimeofday(&tp, NULL);
ts.tv_sec = tp.tv_sec;
ts.tv_nsec = tp.tv_usec*1000;
ts.tv_sec += 2;
//Invoke pthread_cond_timedwait() to wait for 2 seconds
int rcode = pthread_cond_timedwait(&cond, &mutex, &ts);
if (rcode == ETIMEDOUT)
printf("Terminated due to time out\n");
else if (rcode == EPERM)
printf("Terminated due to EPERM\n");
else
printf("Return code is %d\n", rcode);
return NULL;
}
int main(int argc, char** argv){
pthread_t thread;
// start the thread
pthread_create(&thread, NULL, &thread_handler, NULL);
// wait for thread to finish
pthread_join(thread, NULL);
return 0;
}
EPERM is returned if the thread that calls timedwait does not own the mutex. You must lock the mutex before calling timedwait. Also, move the static initialization of mutex and condvar to file scope.
UPDATE: If you initialize the mutex to be an error-checking mutex, Linux will also terminate with EPERM (since it is UB to call pthread_cond_wait/timedwait without holding the mutex).
Modified code below:
//#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex;
void *thread_handler(void *ptr){
struct timespec ts;
struct timeval tp;
gettimeofday(&tp, NULL);
ts.tv_sec = tp.tv_sec;
ts.tv_nsec = tp.tv_usec*1000;
ts.tv_sec += 2;
//Invoke pthread_cond_timedwait() to wait for 2 seconds
int rcode = pthread_cond_timedwait(&cond, &mutex, &ts);
if (rcode == ETIMEDOUT)
printf("Terminated due to time out\n");
else if (rcode == EPERM)
printf("Terminated due to EPERM\n");
else
printf("Return code is %d\n", rcode);
return NULL;
}
int main(int argc, char** argv){
pthread_mutexattr_t mta;
pthread_mutexattr_init(&mta);
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex, &mta);
pthread_t thread;
// start the thread
pthread_create(&thread, NULL, &thread_handler, NULL);
// wait for thread to finish
pthread_join(thread, NULL);
return 0;
}
Tested on kernel SMP Debian 4.9.82-1+deb9u3 (2018-03-02) x86_64 GNU/Linux, distro Debian GNU/Linux buster/sid.
I've got an application where I will be using a standalone C programming to read a CAN bus port with a socket. The user interface on this is Qt/QML code. I would like to use a non-blocking approach to call the bin program and either return nothing or return a string of the CAN packet.
The application will be low speed (just monitoring key presses, etc) so speed is not an issue. The current approach involves writing data from the socket program to a file, then having ANOTHER C program take the file and echo the string back to QML. UGH! Seems very messy. A simple Go/NoGo call would be easier. Here's the code I've got so far.
Thanks for any comments.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
// Returns 0 if no errors, > 0 if errors found
int main(void) {
struct ifreq ifr;
struct can_frame frame;
struct sockaddr_can addr;
int s; // CAN socket descriptor
int nbytes; // Number of bytes read from CAN socket
char run_daemon = 0; // Set to 1 to run as a daemon process
char show_errors = 0; // Set to 1 to print errors
char *ifname = "can0"; // Define the CAN driver for use
if (run_daemon) // Skip the daemon call if not enabled
daemon(1,1);
if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
if (show_errors)
perror("Error while opening RAW socket");
return 1;
}
strcpy (ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
if (show_errors)
perror("Error in socket bind");
return 2;
}
// Loop here for daemon process
while (1) {
// Read CAN frame data
nbytes = read(s, &frame, sizeof(struct can_frame));
// If data is ready, process it
if (nbytes > 0) {
// Print all relevent frame data to QML
printf("%d ",frame.can_id);
printf("%d ",frame.can_dlc);
if(frame.can_dlc>0) printf("%d ",frame.data[0]);
if(frame.can_dlc>1) printf("%d ",frame.data[1]);
if(frame.can_dlc>2) printf("%d ",frame.data[2]);
if(frame.can_dlc>3) printf("%d ",frame.data[3]);
if(frame.can_dlc>4) printf("%d ",frame.data[4]);
if(frame.can_dlc>5) printf("%d ",frame.data[5]);
if(frame.can_dlc>6) printf("%d ",frame.data[6]);
if(frame.can_dlc>7) printf("%d ",frame.data[7]);
printf("\n");
}
if (!run_daemon) { // Exit if daemon is not running
close(s); // Close the CAN socket
return 0;
}
}
return 0; // Should never get here !!!
}
I want to start a process from a QT app and catch its termination event. Its done with the method QProcess::start(). But unlike in startDetached(), the standard output of the process is redirected to a buffer. I don't want that.
I can't find how to disable it. An ugly workaround is to call setStandardOutputFile("/dev/stdout")
test.h
#ifndef MY_TEST_H
#define MY_TEST_H
#include <QCoreApplication>
class MyApp : public QCoreApplication {
Q_OBJECT
private Q_SLOTS:
void subprocessStarted();
void subprocessFinished(int);
public:
MyApp( int & argc, char ** argv );
};
#endif
test.cpp
#include "test.h"
#include <QProcess>
#include <QCoreApplication>
#include <stdio.h>
#define ENTRY printf("%s\n", __PRETTY_FUNCTION__)
MyApp::MyApp( int & argc, char ** argv ) : QCoreApplication(argc, argv) {
ENTRY;
QProcess *process = new QProcess();
//process->setStandardOutputFile("/dev/stdout");
process->start("/bin/echo aaa");
bool b;
b = connect(process, SIGNAL(started()), SLOT(subprocessStarted()));
printf("connect started %d\n", b);
b = connect(process, SIGNAL(finished(int)), SLOT(subprocessFinished(int)));
printf("connect finished %d\n", b);
}
void MyApp::subprocessStarted() {
ENTRY;
}
void MyApp::subprocessFinished(int ret) {
ENTRY;
printf("%d\n", ret);
}
int main(int argc, char *argv[]) {
ENTRY;
MyApp a(argc, argv);
return a.exec();
}
Does QProcess::closeReadChannel(ProcessChannel channel) work for you?
Closes the read channel channel. After calling this function, QProcess
will no longer receive data on the channel. Any data that has already
been received is still available for reading. Call this function to
save memory, if you are not interested in the output of the process.
Like this-
QProcess *process = new QProcess();
process->start("/bin/echo aaa");
process->closeReadChannel(QProcess::StandardOutput);
process->closeReadChannel(QProcess::StandardError);
I want use qt to control some other windows, so I write this code:
#define protected public //just for test
...
WId id = 0x00000001 //some real wid
QWidget w;
w.create(id, false, false);
w.hide();
after I run this code, the window crashes, and I got:
:X Error: BadAccess (attempt to access private resource denied) 10
I'm using ubuntu10.04 with qt4, anyone has sample in QWidget::create?
this is my approach, still has bug though.
#include <sys/select.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <regex.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#define SIZE_USEHINTS (1L << 0)
Display *display = 0;
void initDisplay()
{
if (display == 0)
display = XOpenDisplay(getenv("DISPLAY"));
}
int _is_success(const char *funcname, int code) {
if (code != 0)
fprintf(stderr, "%s failed (code=%d)\n", funcname, code);
return code;
}
int window_change(Window wid, int x, int y, int w, int h) {
initDisplay();
XWindowChanges wc;
wc.x = x;
wc.y = y;
wc.width = w;
wc.height = h;
int ret = XConfigureWindow(display, wid, CWX | CWY | CWWidth | CWHeight, &wc);
XFlush(display);
return _is_success("XConfigureWindow", ret == 0);
}