windows8 - _dup,_dup2 - c++

I use win8 Consumer preview build 8250 for executing a program, which works OK on win7
The program uses the following macros/functions:
#if defined(_WIN32)
#include <io.h>
#define streamDup(fd1) _dup(fd1)
#define streamDup2(fd1,fd2) _dup2(fd1,fd2)
#endif
static int acquireOutputStream()
{ int fd = streamDup(fileno(stdout));
FILE* f = freopen("tmp","w",stdout);
return fd; }
static void releaseOutputStream(int fd)
{ fflush(stdout);
streamDup2(fd,fileno(stdout));
close(fd);
}
The program performs the following:
for (int i = 0; i < 1000;++i) {
int fd = acquireOutputStream();
printf("redirect %d\n",i);
releaseOutputStream(fd);
printf("test %d\n",i);
}
Every time I run it ,it prints to file tmp random number of correct "redirect j" printings :
After it ,the file is empty for the remaining executions.(f pointer is never NULL in the acquireOutputStream)"test j" is always printed correctly.
What could be a problem? Is it a known issue on win 8?

There is one small issue i see with your code.
static void releaseOutputStream(int fd)
{ fflush(stdout);
streamDup2(fd,fileno(stdout));
close(fd);
}
In this function you do not close stdout prior to the dup2 call (fclose(stdout)).
Please add more detail to the question on exactly what you are seeing when running this code. It would help in diagnosing the issue.

Related

Adafruit Fona establishes connection with echo server, but doesn't send over any data

Using mbed OS and stm32 nucleo board with Adafruit Fona 3g, I am trying to send data to a server via 3g connection. I am using the .cpp file and .h file posted here: https://os.mbed.com/users/Nels885/code/Adafruit_FONA_3G/file/b18cfba4283a/
The code seems to get stuck on getTCPtimeout. I am having trouble figuring out why this is the case.
I have tried commenting out the getTCPtimeout function to see the results and the code runs through completely, but never establishes a connection with the server.
#include "mbed.h"
#include "Adafruit_FONA.h"
#define FONA_RST D4
#define FONA_TX D1
#define FONA_RX D0
#define FONA_RI D7 //not used
char replybuffer[255];
Adafruit_FONA_3G fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI);
Serial pc(USBTX, USBRX);
int main()
{
fona.TCPinitialize();
pc.printf ("initialize \n");
char *Timeout = "10000000";
fona.getTCPtimeout(Timeout);
pc.printf ("timeout \n");
char * Server = "47.218.188.133";
uint16_t Port = 23;
fona.TCPconnect(Server,Port);
pc.printf ("connect \n");
char * Packet = "Pick Up %";
fona.TCPsend(Packet);
pc.printf ("send \n");
fona.TCPclose();
pc.printf ("close \n");
}
Edit: I was running the code and noticed that after fixing the above issue, the code would get stuck TCPSend function, specifically right before
packet[0] = 0;
which is shown down here:
bool Adafruit_FONA_3G::TCPsend(char *packet)
{
if (strlen(packet) > 0) {
mySerial.printf("%s", packet);
//mySerial.printf("%s\r\n", packet);
readline();
packet[0] = 0;
return true;
} else return false;
}
When commenting out the line, the code would run all the way through. I am still in the process of testing to see if the code still functions as intended, but my question is what exactly is the purpose of packet[0] = 0;?
Adafruit_FONA_3G::getTCPtimeout() assumes that you pass it a writable buffer of size > 20. You're passing a read-only buffer of smaller size. So, replace
char *Timeout = "10000000";
with
char Timeout[21];

cross-platform code for singleton process?

I've got a situation to develop a code that can have only one instance per machine any time. And my code should be platform independent. Till this it is fine, but the problem is that I cannot have any other files except my binary. I've developed a code using fcntl, my logic is that I'll lock my binary itself, so every time the code runs it checks if it could lock and returns if it can't. This logic worked fine in ubuntu, solaris machines, but in windows I found that this logic no longer works as I can't open the running exe file. Here I attached my code where I got stuck. Please excuse me if you feel it's not the correct portal to ask, or if you feel my research is of no use. Any suggestion will be of great help to me.
#include<iostream>
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#define PATH "<my binary path>"
using namespace std;
int main(){
int lockfd;
FILE *FP = fopen(PATH,"wb");
if (!FP)
{
if(errno==16){
cout<<"programme is currently running hence I quit\n";// windows
}else{
cout<<"error while opening the given file\n";
cout<<"errno = "<<errno<<"\n";
}
return 1;
}else{
lockfd = fileno(FP);
}
cout<<lockfd<<"\n";
cout<<"errno = "<<errno<<"\n";
struct flock lock;
lock.l_start = 0;
lock.l_len = 0;
lock.l_type = F_WRLCK;//F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_pid = getpid();
int rc = fcntl(lockfd, F_SETLK, &lock);
cout<<"rc = "<<rc<<"\n";
cout<<"errno = "<<errno<<" eagain ="<<EAGAIN<<"\n";
if (rc == -1 && errno == EAGAIN) {
cout<<"cant lock now hence I quit\n";
return 0;
}else{
cout<<"lock done\n";
sleep(10);
//rest of the code//
}
}
The simpliest edit to make would be
#ifndef WIN32
#define PATH "/export/home/dath/Desktop/singleTon.bin"
#else
#define PATH "<some path in C that you want>"
#endif
Which forces the path to be one thing for windows, and something else for all other platforms.
That said there are other cleaner ways of doing this such as shared memory which would mean that you wouldn't have to worry about leaving files around the place or hard-coding their path.

Communication with Arduino using Linux

This is the first time I'm communicating with Arduino using my computer. I use Ubuntu 14.04. This is the C program for writing to the file. The Arduino shows up ttyACM0.
While compiling using gcc the compiler shows an error saying:
Segmentation fault(core dumped)
How do I rectify this error.
#include<unistd.h>
#include<stdio.h>
int main() {
char data[] = {'f','b','r'}; //Random data we want to send
FILE *file;
file = fopen("/dev/ttyACM0","w"); //Opening device file
int i = 0;
for(i = 0 ; i < 3 ; i++) {
fprintf(file,"%c",data[i]); //Writing to the file
fprintf(file,"%c",','); //To separate digits
sleep(1);
}
fclose(file);
}
Pardon my ignorance. I tried researching on it. Couldn't make it work. Thanks in advance for your help.
You're getting a NULL return from the fopen() that NULL is being passed to fprintf() which is expecting a valid FILE* and messing up causing the SEGV.
If you use fopen you should check what it returns so you can give the user a something more useful than "segmentation fault".
The probable cause of the fopen() failure is you don't have permission to play with the serial port.
Normally you need the group dialout to be able to access the serial port.
As root do:
usermod -a -G dialoutyourusername
Then log out and back in so you get the new group.
Consider using minicom or microcom (on any of the several other serial terminal programs) to access the serial port instead of writing your own.
I also suggest you have the Arduino send a hello message when it boots up so you can be sure you have the right baud rate etc...
You did not put any success check on the return value of fopen("/dev/ttyACM0","w");. In case fopen() fails, using file further is undefined behavior, causing segmentation fault. Do something like
file = fopen("/dev/ttyACM0","w"); //Opening device file
if (file)
{
//do something with file
}
else
return 0;
Also, add a return 0 before ending main().
// the following code:
// compiles cleanly
// performs appropriate error checking
// has proper return statement
#include <unistd.h> // sleep()
#include <stdio.h> // fopen(), fclose(), fprintf(), perror()
#include <stdlib.h> // exit() and EXIT_FAILURE
int main()
{
char data[] = {'f','b','r'}; //Random data we want to send
FILE *file;
if( NULL == (file = fopen("/dev/ttyACM0","w") ) ) //Opening device file
{ // then fopen failed
perror("fopen failed for ttyACM0" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
int i = 0;
for(i = 0 ; i < 3 ; i++)
{
if( 0 >= fprintf(file,"%c",data[i]) ) //Writing to the file
{ // fprintf failed
perror("fprintf data failed" );
exit( EXIT_FAILURE );
}
// implied else, fprintf successful for data
if( 0 >= fprintf(file,"%c",',') ) //To separate digits
{ // then, fprintf failed
perror( "fprintf for comma failed");
exit( EXIT_FAILURE );
}
// implied else, fprintf successful for comma
sleep(1);
} // end for
fclose(file);
return(0);
} // end function: main
On failure fopen returns NULL, so you are potentially dereferencing a NULL pointer, the correct way of doing that, is checking the result of fopen. I would however suggest low level IO for this kind of thing something like
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main()
{
char data[] = {'f','b','r'}; //Random data we want to send
int fd;
int i;
fd = open("/dev/ttyACM0", O_WRONLY); //Opening device file
if (fd == -1)
{
perror("cannot open /dev/ttyACM0");
return -1;
}
for(i = 0 ; i < 3 ; i++)
{
write(fd, &(data[i]), 1);
write(fd, ",", 1);
sleep(1);
}
close(fd);
return 0;
}
on error open returns a special value -1 so you should abort writing to it.
I'm pretty sure in your case there will be a permission denied error, since normally the /dev/tty* belong to group dialout and they have group write permission by default, but since probably your user doesn't belong to that group you don't have write access to /dev/ttyACM0.

inotify notifies of a new file wrongly multiple times

Using inotify to monitor a directory for any new file created in the directory by adding a watch on the directory by
fd = inotify_init();
wd = inotify_add_watch(fd, "filename_with_path", IN_CLOSE_WRITE);
inotify_add_watch(fd, directory_name, IN_CLOSE_WRITE);
const int event_size = sizeof(struct inotify_event);
const int buf_len = 1024 * (event_size + FILENAME_MAX);
while(true) {
char buf[buf_len];
int no_of_events, count = 0;
no_of_events = read(fd, buf, buf_len);
while(count < no_of_events) {
struct inotify_event *event = (struct inotify_event *) &buf[count];
if (event->len) {
if (event->mask & IN_CLOSE_WRITE) {
if (!(event->mask & IN_ISDIR)) {
//It's here multiple times
}
}
}
count += event_size + event->len;
}
When I scp a file to the directory, this loops infinitely. What is the problem with this code ? It shows the same event name and event mask too. So , it shows that the event for the same, infinite times.
There are no break statements. If I find an event, I just print it and carry on waiting for another event on read(), which should be a blocking call. Instead, it starts looping infinitely. This means, read doesn't block it but returns the same value for one file infinitely.
This entire operation runs on a separate boost::thread.
EDIT:
Sorry all. The error I was getting was not because of the inotify but because of sqlite which was tricky to detect at first. I think I jumped the gun here. With further investigation, I did find that the inotify works perfectly well. But the error actually came from the sqlite command : ATTACH
That command was not a ready-only command as it was supposed to. It was writing some meta data to the file. So inotify gets notification again and again. Since they were happening so fast, it screwed up the application.I finally had to breakup the code to understand why.
Thanks everyone.
I don't see anything wrong with your code...I'm running basically the same thing and it's working fine. I'm wondering if there's a problem with the test, or some part of the code that's omitted. If you don't mind, let's see if we can remove any ambiguity.
Can you try this out (I know it's almost the same thing, but just humor me) and let me know the results of the exact test?
1) Put the following code into test.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/inotify.h>
int main (int argc, char *argv[])
{
char target[FILENAME_MAX];
int result;
int fd;
int wd; /* watch descriptor */
const int event_size = sizeof(struct inotify_event);
const int buf_len = 1024 * (event_size + FILENAME_MAX);
strcpy (target, ".");
fd = inotify_init();
if (fd < 0) {
printf ("Error: %s\n", strerror(errno));
return 1;
}
wd = inotify_add_watch (fd, target, IN_CLOSE_WRITE);
if (wd < 0) {
printf ("Error: %s\n", strerror(errno));
return 1;
}
while (1) {
char buff[buf_len];
int no_of_events, count = 0;
no_of_events = read (fd, buff, buf_len);
while (count < no_of_events) {
struct inotify_event *event = (struct inotify_event *)&buff[count];
if (event->len){
if (event->mask & IN_CLOSE_WRITE)
if(!(event->mask & IN_ISDIR)){
printf("%s opened for writing was closed\n", target);
fflush(stdout);
}
}
count += event_size + event->len;
}
}
return 0;
}
2) Compile it with gcc:
gcc test.c
3) kick it off in one window:
./a.out
4) in a second window from the same directory try this:
echo "hi" > blah.txt
Let me know if that works correctly to show output every time the file is written to and does not loop as your code does. If so, there's something important your omiting from your code. If not, then there's some difference in the systems.
Sorry for putting this in the "answer" section, but too much for a comment.
My guess is that read is returning -1 and since you dont ever try to fix the error, you get another error on the next call to read which also returns -1.

How can I redirect stdout to some visible display in a Windows Application?

I have access to a third party library that does "good stuff." It issues status and progress messages to stdout. In a Console application I can see these messages just fine. In a Windows application they just go to the bit bucket.
Is there a fairly simple way to redirect stdout and stderr to a text control or other visible place. Ideally, this would not require any recompiles of the third party code. It would just intercept the steams at a low level. I'd like a solution where I just #include the header, call the initialization function and link the library as in...
#include "redirectStdFiles.h"
void function(args...)
{
TextControl* text = new TextControl(args...);
initializeRedirectLibrary(text, ...);
printf("Message that will show up in the TextControl\n");
std::cout << "Another message that also shows up in TextControl\n";
}
Even better would be if it used some interface that I could override so it is not tied to any particular GUI library.
class StdFilesRedirector
{
public:
writeStdout(std::string const& message) = 0;
writeStderr(std::string const& errorMessage) = 0;
readStdin(std::string &putReadStringHere) = 0;
};
Am I just dreaming? Or does anyone know of something that can do something like this?
Edit after two answers: I think using freopen to redirect the files is a good first step. For a complete solution there would need to be a new thread created to read the file and display the output. For debugging, doing a 'tail -f' in a cygwin shell window would be enough. For a more polished application... Which is what I want to write... there would be some extra work to create the thread, etc.
You need to create pipe (with CreatePipe()), then attach stdout to it's write end with SetStdHandle(), then you can read from pipe's read end with ReadFile() and put text you get from there anywhere you like.
You can redirect stdout, stderr and stdin using freopen.
From the above link:
/* freopen example: redirecting stdout */
#include <stdio.h>
int main ()
{
freopen ("myfile.txt","w",stdout);
printf ("This sentence is redirected to a file.");
fclose (stdout);
return 0;
}
You can also run your program via command prompt like so:
a.exe > stdout.txt 2> stderr.txt
You're probably looking for something along those lines:
#define OUT_BUFF_SIZE 512
int main(int argc, char* argv[])
{
printf("1: stdout\n");
StdOutRedirect stdoutRedirect(512);
stdoutRedirect.Start();
printf("2: redirected stdout\n");
stdoutRedirect.Stop();
printf("3: stdout\n");
stdoutRedirect.Start();
printf("4: redirected stdout\n");
stdoutRedirect.Stop();
printf("5: stdout\n");
char szBuffer[OUT_BUFF_SIZE];
int nOutRead = stdoutRedirect.GetBuffer(szBuffer,OUT_BUFF_SIZE);
if(nOutRead)
printf("Redirected outputs: \n%s\n",szBuffer);
return 0;
}
This class will do it:
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#ifndef _USE_OLD_IOSTREAMS
using namespace std;
#endif
#define READ_FD 0
#define WRITE_FD 1
#define CHECK(a) if ((a)!= 0) return -1;
class StdOutRedirect
{
public:
StdOutRedirect(int bufferSize);
~StdOutRedirect();
int Start();
int Stop();
int GetBuffer(char *buffer, int size);
private:
int fdStdOutPipe[2];
int fdStdOut;
};
StdOutRedirect::~StdOutRedirect()
{
_close(fdStdOut);
_close(fdStdOutPipe[WRITE_FD]);
_close(fdStdOutPipe[READ_FD]);
}
StdOutRedirect::StdOutRedirect(int bufferSize)
{
if (_pipe(fdStdOutPipe, bufferSize, O_TEXT)!=0)
{
//treat error eventually
}
fdStdOut = _dup(_fileno(stdout));
}
int StdOutRedirect::Start()
{
fflush( stdout );
CHECK(_dup2(fdStdOutPipe[WRITE_FD], _fileno(stdout)));
ios::sync_with_stdio();
setvbuf( stdout, NULL, _IONBF, 0 ); // absolutely needed
return 0;
}
int StdOutRedirect::Stop()
{
CHECK(_dup2(fdStdOut, _fileno(stdout)));
ios::sync_with_stdio();
return 0;
}
int StdOutRedirect::GetBuffer(char *buffer, int size)
{
int nOutRead = _read(fdStdOutPipe[READ_FD], buffer, size);
buffer[nOutRead] = '\0';
return nOutRead;
}
Here's the result:
1: stdout
3: stdout
5: stdout
Redirected outputs:
2: redirected stdout
4: redirected stdout
When you create a process using CreateProcess() you can choose a HANDLE to which stdout and stderr are going to be written. This HANDLE can be a file to which you direct the output.
This will let you use the code without recompiling it. Just execute it and instead of using system() or whatnot, use CreateProcess().
The HANDLE you give to CreateProcess() can also be that of a pipe you created, and then you can read from the pipe and do something else with the data.
You could do something like this with cout or cerr:
// open a file stream
ofstream out("filename");
// save cout's stream buffer
streambuf *sb = cout.rdbuf();
// point cout's stream buffer to that of the open file
cout.rdbuf(out.rdbuf());
// now you can print to file by writing to cout
cout << "Hello, world!";
// restore cout's buffer back
cout.rdbuf(sb);
Or, you can do that with a std::stringstream or some other class derived from std::ostream.
To redirect stdout, you'd need to reopen the file handle. This thread has some ideas of this nature.
This is what I'd do:
CreatePipe().
CreateProcess() with the handle from CreatePipe() used as stdout for the new process.
Create a timer or a thread that calls ReadFile() on that handle every now and then and puts the data read into a text-box or whatnot.
Here we'll set a new entry point consoleMain that overrides your own one.
Determine the entry point of your application. In VisualStudio, select Project Properties/Linker/Advanced/Entry Point. Let us call it defaultMain.
Somewhere in your source code declare the original entry point (so we can chain to it) and the new entry point. Both must be declared extern "C" to prevent name mangling.
extern "C"
{
int defaultMain (void);
int consoleMain (void);
}
Implement the entry point function.
__declspec(noinline) int consoleMain (void)
{
// __debugbreak(); // Break into the program right at the entry point!
AllocConsole(); // Create a new console
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
freopen("CON", "r", stdin); // Note: "r", not "w".
return defaultMain();
}
Add your test code somewhere, e.g. in a button click action.
fwprintf(stdout, L"This is a test to stdout\n");
fwprintf(stderr, L"This is a test to stderr\n");
cout<<"Enter an Integer Number Followed by ENTER to Continue" << endl;
_flushall();
int i = 0;
int Result = wscanf( L"%d", &i);
printf ("Read %d from console. Result = %d\n", i, Result);
Set consoleMain as the new entry point (Project Properties/Linker/Advanced/Entry Point).
Thanks to the gamedev link in the answer by greyfade, I was able to write and test this simple piece of code
AllocConsole();
*stdout = *_tfdopen(_open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE), _O_WRONLY), _T("a"));
*stderr = *_tfdopen(_open_osfhandle((intptr_t) GetStdHandle(STD_ERROR_HANDLE), _O_WRONLY), _T("a"));
*stdin = *_tfdopen(_open_osfhandle((intptr_t) GetStdHandle(STD_INPUT_HANDLE), _O_WRONLY), _T("r"));
printf("A printf to stdout\n");
std::cout << "A << to std::cout\n";
std::cerr << "A << to std::cerr\n";
std::string input;
std::cin >> input;
std::cout << "value read from std::cin is " << input << std::endl;
It works and is adequate for debugging. Getting the text into a more attractive GUI element would take a bit more work.