read was not declared error message - c++

I am cross compiling a package (libqmi).(With simple compiling it was fine.)
The problem came out when I tried to comply a c++ part.
I got the message that is
"read is not declared".
I know it does not need to be included in case of C, but what about C++?
I tried to add the headers by hand: fcntl.h and unistd.h too, without any solution.
(the compiler found them and included, but the error message is still left)
Do you have any idea what the problem can be behind this?
I do not think the problem is wrong, as it is a realised and good with host compiler.
EDIT:
thanks the comments.
host: Linux, x86,
target: Linux, arm
unistd.h header does not solved the problem:
I also tried type alloc, maybe there is misalloc.
GobiQMICore.cpp: In member function 'virtual std::vector, std::basic_string > > cGobiQMICore::GetAvailableDevices()':
GobiQMICore.cpp:319:39: error: 'read' was not declared in this scope
GobiQMICore.cpp:334:21: error: 'close' was not declared in this scope
the code:
/*===========================================================================
METHOD:
GetAvailableQDLPorts (Public Method)
DESCRIPTION:
Return the set of available Gobi QDL ports
RETURN VALUE:
std::vector <sDeviceID>
===========================================================================*/
std::vector <std::string> cGobiQDLCore::GetAvailableQDLPorts()
{
std::vector <std::string> devices;
std::string path = "/sys/bus/usb/devices/";
std::vector <std::string> files;
DepthSearch( path,
2,
"ttyUSB",
files );
int fileNum = files.size();
for (int i = 0; i < fileNum; i++)
{
// Example "/sys/bus/usb/devices/8-1/8-1:1.1/ttyUSB0"
std::string nodePath = files[i];
int lastSlash = nodePath.find_last_of( "/" );
// This is what we want to return if everything else matches
std::string deviceNode = nodePath.substr( lastSlash + 1 );
// Move down one directory to the interface level
std::string curPath = nodePath.substr( 0, lastSlash );
// Read bInterfaceNumber
int handle = open( (curPath + "/bInterfaceNumber").c_str(),
O_RDONLY );
if (handle == -1)
{
continue;
}
char buff[4];
memset( buff, 0, 4 );
bool bFound = false;
int ret = read( handle, buff, 2 );
if (ret == 2)
{
// Interface 1 or 0
ret = strncmp( buff, "01", 2 );
if (ret == 0)
{
bFound = true;
}
ret = strncmp( buff, "00", 2 );
if (ret == 0)
{
bFound = true;
}
}
close( handle );
if (bFound == false)
{
continue;
}
// Move down one directory to the device level
curPath = curPath.substr( 0, curPath.find_last_of( "/" ) );
// Read idVendor
handle = open( (curPath + "/idVendor").c_str(), O_RDONLY );
if (handle == -1)
{
continue;
}
bFound = false;
ret = read( handle, buff, 4 );
if (ret == 4)
{
ret = strncmp( buff, "05c6", 4 );
if (ret == 0)
{
bFound = true;
}
}
close( handle );
if (bFound == false)
{
continue;
}
// Read idProduct
handle = open( (curPath + "/idProduct").c_str(), O_RDONLY );
if (handle == -1)
{
continue;
}
bFound = false;
ret = read( handle, buff, 4 );
if (ret == 4)
{
ret = strncmp( buff, "920c", 4 );
if (ret == 0)
{
bFound = true;
}
}
close( handle );
if (bFound == false)
{
continue;
}
// Success!
devices.push_back( deviceNode );
}
return devices;
}
T

I know it does not need to be included in case of C, but what about C++?
I think that you should always include the headers you need. I guess your compiler is doing the job for you, if you use the "-Wall" parameter with gcc, you should get a warning.
Under Linux, to know what header you need to include just type man function. Sometime you might get the bash man page, for open you need to indicate the section man 2 read and in the synopsis, you have the required headers. To get those man pages, you also need to install the manpages-dev on Debian based distribution.
To answer to your question, I also had that kind of issue when I was writing C++ programs using a namespace. If you are inside a namespace, try calling this function like that ::read(...)

Related

get packet number in libpcap callback

I'm using libpcap to process the WS output.
My question is: can I have access in the packet number in the pcap_loop callback? Or I will have to use a static variable?
EDIT:
As requested:
long Foo:Main()
{
handle = pcap_open_dead( DLT_EN10MB, MAX_PACKET_SIZE );
if( !handle )
{
}
dumper = pcap_dump_open( handle, fileOut.ToString() );
if( !dumper )
{
}
handle = pcap_open_offline( fileNameStr.ToString(), errbuf );
if( !handle )
{
}
if( pcap_compile( handle, &fp, FltString.ToString(), 0, net ) == PCAP_ERROR )
{
}
// Set filter for JREAP only
if( pcap_setfilter( handle, &fp ) == PCAP_ERROR )
{
}
unchar *uncharThis = reinterpret_cast<unchar*>( this );
// The pcap_loop is implemented like:
// for( int i = 0; i < num_of_packets; i++ )
// ProcessPackets();
// where i is the current packet number to process
int ret_val = pcap_loop( handle, 0, ProcessPackets, uncharThis );
if( ret_val == PCAP_ERROR )
{
}
}
bool Foo::ProcessPackets(unchar *userData, const struct pcap_pkthdr *pkthdr, const unchar *packet)
{
// This function will be called for every packet in the pcap file
// that satisfy the filter condition.
// Inside this function do I have access to the packet number.
// Do I have an access to the variable `i` from the comment above
// Or I will have to introduce a static variable here?
}
libpcap does not keep track of the ordinal numbers of packets, so you'll have to maintain a packet count in your code.

get process inode using netlink

I want to try and correlate an IP packet (using libpcap) to a process. I have had some limited success using the relevant /proc/net/ files but found that on some of the machines i'm using, this file can be many thousands of lines and parsing it is not efficient (caching has alleviated some performance problems).
I read that using sock_diag netlink subsystem could help by directly querying the kernel about the socket I am interested in. I've had limited success with my attempts but have hit a mental block on what is wrong.
For the initial query I have:
if (query_fd_) {
struct {
nlmsghdr nlh;
inet_diag_req_v2 id_req;
} req = {
.nlh = {
.nlmsg_len = sizeof(req),
.nlmsg_type = SOCK_DIAG_BY_FAMILY,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP
},
.id_req = {
.sdiag_family = packet.l3_protocol,
.sdiag_protocol = packet.l4_protocol,
.idiag_ext = 0,
.pad = 0,
.idiag_states = -1,
.id = {
.idiag_sport = packet.src_port,
.idiag_dport = packet.dst_port
}
}
};
//packet ips are just binary data stored as strings!
memcpy(req.id_req.id.idiag_src, packet.src_ip.c_str(), 4);
memcpy(req.id_req.id.idiag_dst, packet.dst_ip.c_str(), 4);
struct sockaddr_nl nladdr = {
.nl_family = AF_NETLINK
};
struct iovec iov = {
.iov_base = &req,
.iov_len = sizeof(req)
};
struct msghdr msg = {
.msg_name = (void *) &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1
};
// Send message to kernel
for (;;) {
if (sendmsg(query_fd_, &msg, 0) < 0) {
if (errno == EINTR)
continue;
perror("sendmsg");
return false;
}
return true;
}
}
return false;
For the receive code I have:
long buffer[8192];
struct sockaddr_nl nladdr = {
.nl_family = AF_NETLINK
};
struct iovec iov = {
.iov_base = buffer,
.iov_len = sizeof(buffer)
};
struct msghdr msg = {
.msg_name = (void *) &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1
};
int flags = 0;
for (;;) {
ssize_t rv = recvmsg(query_fd_, &msg, flags);
// error handling
if (rv < 0) {
if (errno == EINTR)
continue;
if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
break;
perror("Failed to recv from netlink socket");
return 0;
}
if (rv == 0) {
printf("Unexpected shutdown of NETLINK socket");
return 0;
}
for (const struct nlmsghdr* header = reinterpret_cast<const struct nlmsghdr*>(buffer);
rv >= 0 && NLMSG_OK(header, static_cast<uint32_t>(rv));
header = NLMSG_NEXT(header, rv)) {
// The end of multipart message
if (header->nlmsg_type == NLMSG_DONE)
return 0;
if (header->nlmsg_type == NLMSG_ERROR) {
const struct nlmsgerr *err = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(header));
if (err == NULL)
return 100;
errno = -err->error;
perror("NLMSG_ERROR");
return 0;
}
if (header->nlmsg_type != SOCK_DIAG_BY_FAMILY) {
printf("unexpected nlmsg_type %u\n", (unsigned)header->nlmsg_type);
continue;
}
// Get the details....
const struct inet_diag_msg* diag = reinterpret_cast<inet_diag_msg*>(NLMSG_DATA(header));
if (header->nlmsg_len < NLMSG_LENGTH(sizeof(*diag))) {
printf("Message too short %d vs %d\n", header->nlmsg_len, NLMSG_LENGTH(sizeof(*diag)));
return 0;
}
if (diag->idiag_family != PF_INET) {
printf("unexpected family %u\n", diag->idiag_family);
return 1;
}
return diag->idiag_inode;
The Problem:
The diag->udiag_inode value doesn't match the one I see in netstat output or in the /proc/net/ files. Is it supposed too? If not, is it possible to use this approach to retrieve the inode number for the process so that I can then query /proc for the corresponding PID?
Another thing I didn't quite understand is the NLMSG_DONE when checking the nlmsg_type in the header. What I am seeing:
1 - TCP 10.0.9.15:51002 -> 192.168.64.11:3128 [15047]
2 - TCP 192.168.64.11:3128 -> 10.0.9.15:51002 [0]
3 - TCP 10.0.9.15:51002 -> 192.168.64.11:3128 [0]
4 - TCP 192.168.64.11:3128 -> 10.0.9.15:51002 [15047]
5 - TCP 10.0.9.15:51002 -> 192.168.64.11:3128 [0]
6 - TCP 192.168.64.11:3128 -> 10.0.9.15:51002 [0]
7 - TCP 10.0.9.15:51002 -> 192.168.64.11:3128 [15047]
So I get an inode number on first query, then some NLMSG_DONE returns (stepping through code confirmed this was the path). Why don't I get the same result for say lines 1 and 3?
Appreciate any help or advice.
Found the answer and posting in case anyone stumbles across it:
I had a uint16_t as the return type from the recv code when in fact it should have been ino_t or uint32_t. I discovered this when I noticed that a few of the inodes matched correctly after a fresh reboot and then after a while stopped matching with no code changed (inode count obviously incrementing). Using the correct type in the function return sorted the problem (so the code I posted is actually correct!)
I was getting multi part messages. I should have looped whilst NLM_F_MULTI was set in the flags and then left the loop when receiving NLMSG_DONE.

How do I organize the file recursive search with file operations?

I write for myself a small program in C ++, which could perform some operations on files that it finds (in my filter), and that's stumbled on the mechanism of searching for files. At start the program asks the full path, and then by file type recursively looking for them in all subdirectories of the selected directory. The trouble is that after performing an operation (cycle fopen - operation - fclose) can not rename or delete the file. The program simply exits with code 0. It is I sin on the file searching mechanism, as is likely, the function uses image for the time of its implementation and does not delete or rename the file. I tried different options to manage files through WinAPI, std (fstream) and just fopen / fclose. Nothing comes out.
Code snippet:
int main() {
char sPath[MAX_PATH] = "C:\\TmpDir";
char sExt[10] = "doc";
char sEXT[10] = "DOC";
GetFileList(sPath, sExt, sEXT);
printf("Results= %d\n", rez);
system("pause");
return 0;
}
void GetFileList(LPTSTR sPath, LPTSTR sExt, LPTSTR sEXT) {
WIN32_FIND_DATA pFILEDATA;
HANDLE hFile = FindFirstFile(strcat(sPath, "\\*.*"), &pFILEDATA);
sPath[strlen(sPath) - strlen(strstr(sPath, "*.*"))] = '\0';
if (hFile != INVALID_HANDLE_VALUE) {
char * chBuf;
do {
if (strlen(pFILEDATA.cFileName) == 1 && strchr(pFILEDATA.cFileName, '.') != NULL)
if (FindNextFile(hFile, &pFILEDATA) == 0)
break;
if (strlen(pFILEDATA.cFileName) == 2 && strstr(pFILEDATA.cFileName, "..") != NULL)
if (FindNextFile(hFile, &pFILEDATA) == 0)
break;
if (pFILEDATA.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
GetFileList(strcat(sPath, pFILEDATA.cFileName), sExt, sEXT);
sPath[strlen(sPath) - strlen(pFILEDATA.cFileName) - 1] = '\0';
} else {
if ((chBuf = strrchr(pFILEDATA.cFileName, '.'))) {
if (strstr(chBuf + 1, sExt) || strstr(chBuf + 1, sEXT)) {
CharToOem(sPath, sPath);
printf("%s", sPath);
OemToChar(sPath, sPath);
CharToOem(pFILEDATA.cFileName, pFILEDATA.cFileName);
printf("%s\n", pFILEDATA.cFileName);
/* Какая-то операция с файлом.
...
Конец операции с файлом. */
rez++;
}
}
}
} while (FindNextFile(hFile, &pFILEDATA));
}
}

Implement "File open in folder" feature for my C++ application in linux

I'm trying to implement the "Open In Folder" functionality that you seen in firefox and download managers. This is the code that I've come up so far, and I decided to use nautilux program to open the file.
int File::openTempFile(std::string temp_file_dir)
{
std::string file_path = temp_file_dir + "/" ;
file_path = file_path + this->additional_info ;
// if there is already an temporary file then delete it//
if( temporary_file != "" )
{
// :TODO: open temporary file stack //
// so when the application dinit we could remove those //
// remove(temporary_file.c_str() );
}
/* write temporary file */
FILE* fp = fopen (file_path.c_str(), "w");
if( fp== NULL)
return FALSE;
fwrite( m_data, 1, m_size, fp);
fclose(fp);
// now open it using natulus //
char * parmList[] = {strdup("nautilus"),strdup(file_path.c_str() )} ;
int pid;
if(( pid= fork() ) == -1)
perror("fork failed");
if( pid ==0 ){
int a = execvp("nautilus" , parmList);
printf("exevp failed to load the temporary file");
}
temporary_file = file_path ;
return TRUE;
}
but the error is natulux open three windows and can't figure out where is my bug.
Any idea ?

How do I extract a user stream from a WinDbg extension?

I have embedded a custom stream in a dump (i.e. passed the UserStreamParam argument to MiniDumpWriteDump function). Now, I'm trying to extract the stream from a WinDbg extension. (Note that I have verified that I can retrieve the stream using the MiniDumpReadDumpStream function).
I'm using the IDebugAdvanced2::Request method with DEBUG_REQUEST_READ_USER_MINIDUMP_STREAM request. I am able to retrieve data from standard streams. For example, the following snippet will correctly retrieve the contents of the misc info stream.
DEBUG_READ_USER_MINIDUMP_STREAM rums = {};
rums.StreamType = MiscInfoStream;
rums.Buffer = &buf;
rums.BufferSize = sizeof buf;
hr = p->Request(DEBUG_REQUEST_READ_USER_MINIDUMP_STREAM,
&rums, sizeof rums, 0, 0, 0);
However, trying to retrieve my own stream will result in an error (0x80070570, ERROR_FILE_CORRUPT) and WinDbg outputs
Dir entry 11, ??? stream has unknown stream type 6381921
Note that the same message appears as a part of the .dumpdebug output.
Stream 11: type ??? (6381921), size 00000038, RVA 00033FA9
Dir entry 11, ??? stream has unknown stream type 6381921
What is the problem? How do I retrieve contents of my user stream?
very late answer
StreamType cannot be UserDefined StreamTypes
jen-lung chiu of ms posted so in osronline windbg lists long back
do not know if the latest dbgeng has this limitation eliminated
you either retrieve it with a dbghelp function independently
(using dbghelp functions inside windbg extensions are not recommended )
or parse the stream yourself with fopen() fread() like below
userstream:\>type ..\usrstr.cpp
#include <stdio.h>
#include <engextcpp.hpp>
#include <dbghelp.h>
const ULONG MBUFFSIZE = 0x1000;
PVOID Buff = 0;
int __cdecl ReadUserStream (char *dmpfile)
{
PMINIDUMP_HEADER MiniHeader = 0;
PMINIDUMP_DIRECTORY MiniDir = 0;
PMINIDUMP_USER_STREAM userstream = 0;
size_t result = 0;
ULONG Streams =0;
ULONG i = 0;
FILE * fp = fopen(dmpfile,"rb");
if (fp)
{
result = fread(Buff, 1, sizeof(MINIDUMP_HEADER), fp );
if ( result == sizeof(MINIDUMP_HEADER) )
{
MiniHeader = (PMINIDUMP_HEADER) Buff;
Streams = MiniHeader->NumberOfStreams;
for (i = 0; i < Streams; i++ )
{
result = fread( Buff, 1, sizeof(MINIDUMP_DIRECTORY), fp );
if ( result == sizeof(MINIDUMP_DIRECTORY) )
{
MiniDir = (PMINIDUMP_DIRECTORY) Buff;
if ( MiniDir->StreamType > LastReservedStream )
{
userstream = (PMINIDUMP_USER_STREAM)Buff;
ULONG savedbuffsize = userstream->BufferSize;
ULONG savedtype = userstream->Type;
PCHAR savedbufferptr = (PCHAR)userstream->Buffer;
long pos = ftell(fp);
fseek(fp, (long)savedbufferptr,SEEK_SET);
result = fread( Buff, 1, savedbuffsize, fp );
if ( result == savedbuffsize )
{
printf(
"\n"
"Datastream Type = %.8x\n"
"Buffer Size = %.8x\n"
"Buffer = %p\n"
"Buffer content = %s\n"
"\n",
savedtype,
savedbuffsize,
savedbufferptr,
Buff
);
fseek(fp,pos,SEEK_SET);
continue;
}
else
{
printf(
"failed to read buffer contents at offset %p of
user stream %x\n",
savedbufferptr,
savedtype);
fseek(fp,pos,SEEK_SET);
continue;
}
}
}
else
{
printf("failed to fread Minidump directory exiting \n");
goto getout;
}
}
}
else
{
printf("failed to fread Minidump header exiting \n");
goto getout;
}
}
else
{
printf("failed to open dmp file exiting \n");
goto getout;
}
getout:
if (fp)
fclose(fp);
return 0;
}
int __cdecl main (int argc, char * argv[])
{
if (argc !=2)
{
printf("Usage %s %s\n",argv[0],"somedump.dmp");
return 0;
}
Buff = malloc( MBUFFSIZE );
if (Buff)
{
ReadUserStream(argv[1]);
free(Buff);
return 0;
}
else
{
printf("malloc failed exiting\n");
return 0;
}
}
output from an userdump that has userStreams in it
(oleg staradumov debuginfo.com writeuserstream.cpp )
userstream:\>usrstr.exe
Usage usrstr.exe somedump.dmp
userstream:\>usrstr.exe test.dmp
Datastream Type = 00010000
Buffer Size = 00000021
Buffer = 000010B6
Buffer content = This is the first data stream...
Datastream Type = 00010001
Buffer Size = 00000023
Buffer = 000010D7
Buffer content = and this is the second data stream
I found this topic while looking for a method to read out user stream from the dbg file.
#blabb 's answer is correct in basics and helped me a lot, but it has a two flaws:
You should use the MINIDUMP_HEADER.StreamDirectoryRva to locate the MINIDUMP_DIRECTORY list.
You should not convert the MINIDUMP_DIRECTORY entry to MINIDUMP_USER_STREAM, because that's an error (MINIDUMP_USER_STREAM is a bigger struct than MINIDUMP_DIRECTORY, so you are reading uninitialized memory there) Use the MINIDUMP_DIRECTORY to locate the needed part of the stream.
Even if not tested, it should work if you fill StreamType with a custom value (greater than LastReservedStream = 0xFFFF) instead of MiscInfoStream.