How use 'fcntl' on Windows with and MinGW? - c++

I'm trying to port a TCP application (specifically tcpsockets), however im getting this error:
error: 'fcntl' was not declared in this scope
I already wrote those includes
#ifdef WIN32
#define _WIN32_WINNT 0x0600 //enable
#include <Ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
typedef int socklen_t;
void close(int socket){closesocket(socket);}
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
Which solved most part of the references, however fcntl was not found.
How can I find a proper reference to it? Or naybe is there another windows method that could replace it?

fcntl() does not exist on Windows. For sockets, the equivalent function is ioctlsocket(). However, file controls on sockets in Linux are very different than in Windows, so not all of the fcntl() commands you are using may port to Windows, or may require different APIs.

Not sure why you are trying to use native sockets. But if there's no real reason, have a look at QTcpSocket instead. It's the Qt class for sockets and works on all platforms.

Related

Linux: Conflicts using inotify with fcntl

I'm having a strange linking issue after I included inotify in my program to monitor changes to a filesystem. The project includes <fcntl.h> in many other source files. However, when I include <sys/inotify.h> in the source file which is doing the directory monitoring, I get this error:
/usr/include/fcntl.h:30:1: error: expected initializer before ‘extern’
__BEGIN_DECLS
My project uses CMake, although that doesn't seem to be relevant for finding inotify. It IS finding the inotify declarations to my knowledge, since when I included , it threw an error that inotify_init() and the other functions I used were not defined. Inotify includes fcntl and is partially built on top of some of the functionality there, so my first thought was that it's importing a different version of fcntl than the rest of my program.
In ObjectManager.h:
#ifndef MANAGE_OBJECT_H
#define MANAGE_OBJECT_H
#include "config.h"
//includes all lua headers under extern 'C'
#include <lua.hpp>
#include <list>
#include <unordered_map>
#include <pthread.h>
class ObjectManager //...
The only thing that changed was ObjectManager.cc, with the addition of sys/notify and the implementation of the watcher (not included because this is a linking issue):
#include "config.h"
#include "ObjectManager.h"
#include "Control.h"
#ifdef OBJECT_MANAGER_ENABLED
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <vector>
#include <unistd.h>
#include <fstream>
#include <sys/inotify.h>
//... inotify implementation
Where Control.h declares #include <fcntl.h>.
This is the closest issue I found, related to some problems in the implementation of different fcntl headers for userspace usage. https://lkml.org/lkml/2008/9/16/98
The same problem occurs on Linux 2.6 running on Centos 6 and Linux 4.0 running on Centos 7.
Any ideas on what is causing this error and how to successfully include inotify?
Resolution: A function definition lacked a semicolon at the END of ObjectManager.h right before a #endif, and the resulting GCC error that propagated through the next includes in a complicated manner, resulting in a strange preprocessor error in fcntl.h.

Can't find mkdir() function in dirent.h for windows

I am using dirent.h 1.20 (source) for windows in VC2013.
I can't find mkdir() in it.
How am I supposed to use it? Or can I create a directory somehow only using dirent.h?
simplest way that helped without using any other library is.
#if defined _MSC_VER
#include <direct.h>
#elif defined __GNUC__
#include <sys/types.h>
#include <sys/stat.h>
#endif
void createDir(string dir) {
#if defined _MSC_VER
_mkdir(dir.data());
#elif defined __GNUC__
mkdir(dir.data(), 0777);
#endif
}
Update: Since C++17, <filesystem> is the portable way to go. For earlier compilers, check out Boost.Filesystem.
The header you are linking to is effectively turning your (POSIX) dirent.h calls into (native) Windows calls. But dirent.h is about directory entries, i.e. reading directories, not creating ones.
If you want to create a directory (mkdir()), you need either:
A similar wrapping header turning your (POSIX) mkdir() call into the corresponding (native) Windows function calls (and I cannot point out such a header for you), or
use the Windows API directly, which might be pragmatic but would lead to a really ugly mix of POSIX and Windows functions...
// UGLY - these two don't belong in the same source...
#include <dirent.h>
#include <windows.h>
// ...
CreateDirectory( "D:\\TestDir", NULL );
// ...
Another solution would be to take a look at Cygwin, which provides a POSIX environment running on Windows, including Bash shell, GCC compiler toolchain, and a complete collection of POSIX headers like dirent.h, sys/stat.h, sys/types.h etc., allowing you to use the POSIX API consistently in your programming.
Visual Studio includes the <direct.h> header.
This header declares _mkdir and _wmkdir, which can be used to create a directory, and are part of the C libraries included with Visual Studio.
The other "easy" option would be to use Windows API calls as indicated by DevSolar.
You can use sys/types.h header file and use
mkdir(const char*) method to create a directory
Following is the sample code
#include<stdio.h>
#include<string.h>
#include <unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
int main()
{
if(!mkdir("C:mydir"))
{
printf("File created\n");
}
else
printf("Error\n");
}
mkdir is deprecated. Give #include <direct.h> as a header file. then write
_mkdir("C:/folder")

Confused about Winsock2.dll vs Winsock2.h?

I am a little confused, I am trying to make a program with no external dependencies (so it could be easily ported to UNIX for example) that has socket connection abilities. But I am unsure of what I should be using?
Is there a standard library on Windows XP, 7, 8 that can be linked against that can output a single exe that can run alone (not depend on a DLL to function)? For example on UNIX I can link against socket and use sys/socket.h and have like 95% of UNIX's without doing anything.
Same code just won't do for both. But you can use #ifdef WIN32 to make the preprocessor consider Windows stuff only when compiling under Windows.
In the headers:
#ifdef WIN32
// Windows exclusive dependencies go here
#include <windows.h>
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")
#define close(s) closesocket(s)
#else
// Linux exclusive dependencies go here
#include <sys/socket.h>
#endif
And inside main() you will need to do something like this:
#ifdef WIN32
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
I believe this is all, the rest of the API is widely compatible with the UNIX way of using sockets.

libssh2_config.h not created when installing libssh2

The title more or less describes the problem I'm having on my Ubuntu box.
I followed the following steps in installing libssh2, as given in the instructions:
./configure
make
make check (all 3 tests passed)
sudo make install (I have to use sudo due to permissions)
I then try to use some of the examples given in libssh2 page and they all have the following:
#include "libssh2_config.h"
Which isn't found. The following 3 files are created in usr/local/include:
libssh2.h
libssh2_publickey.h
libssh2_sftp.h
Is there anything I am doing wrong?
Thank you!
I still can't figure out why the file isn't created, but it is not really necessary, since removing the following #ifdefs:
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
and simply replacing (on linux) with:
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
as well as removing the rest of #ifdefs in the code solves the problem.
libssh2_config.h is in the example dir, you need to copy into your projects.
There are libssh2_config.h files in the win32 dir, the vms dir and the os400 dir. You need to copy one of these into your projects.

Visual studio C++: How to make parts of code not be seen by the windows compiler?

So jenerally I have small C++ project based on OpenSource crossplatform libs. So it probably would compile under linux. So I hited the point when I need to implement some defenatly platform specific class functions.
I have a class header with all functions declarations and cpp file with realisations. So first: how to declare my platform specific functions in header so when I'll try to compile under linux it will not try to compile windows specific ones... and when on windows compiler will not try to compile linux functions include headers etc.
So for windows I need some how wrap such super specific functions
HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
void DisplayDeviceInformation(IEnumMoniker *pEnum)
And some headers
#include <windows.h>
#include <dshow.h>
#pragma comment(lib, "strmiids")
While for linux I have such headers
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/videodev.h>
And I have function with name of void PrintCamerasList() which I wanna have one for bouth platfrms realisations for which I have seprate.
I hope you see what I need. So generally I need some example using my functions or once you can invent - let your imagination flow!)
So why do I need it all - I am creating some console app using OpenCV and I need to list user cameras names. OpenCV cannot do this on its own. so I asked how to do it for bouth platforms of my intrest - windows and linux
You want to look into platform specific macros and surround for example your MSVC specific code with some #ifdef _WIN32 / #endif pairs.
Take a look at http://predef.sourceforge.net/ for an extensive list of pre-defined macros various compilers provide to distinguish between operating systems, compilers, and processor architectures. They will allow you to distinguish between more than just Win32 and Linux if necessary.
Common practice is to use a compiler flag such as
#ifdef WIN_32
// Windows stuff...
#else
// Linux stuff
#endif
Check for the exact values of what windows flag is defined either in your compiler or in the headers you include