typedef struct _HANDLE_CREATOR
{
pcIsHandled IsHandled;
- pcCreateFileA CreateFileA; /* TMP: FIXME: CreateFileA or CreateFile ? */
+ pcCreateFileA CreateFileA;
} HANDLE_CREATOR, *PHANDLE_CREATOR, *LPHANDLE_CREATOR;
BOOL RegisterHandleCreator(PHANDLE_CREATOR pHandleCreator);
#ifndef _WIN32
+#include <assert.h>
+#include <errno.h>
#include <fcntl.h>
+#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>
-#include <errno.h>
-
#include <freerdp/utils/debug.h>
#include <winpr/crt.h>
} COMM_DEVICE;
/* FIXME: get a clever data structure, see also io.h functions */
-static COMM_DEVICE **_CommDevices = NULL;
-
+/* _CommDevices is a NULL-terminated array with a maximun of COMM_DEVICE_MAX COMM_DEVICE */
#define COMM_DEVICE_MAX 128
+static COMM_DEVICE **_CommDevices = NULL;
static HANDLE_CREATOR *_CommHandleCreator = NULL;
-
-static void _CommDevicesInit()
+static pthread_once_t _CommInitialized = PTHREAD_ONCE_INIT;
+static void _CommInit()
{
- /*
- * TMP: FIXME: What kind of mutex should be used here?
- * better have to let DefineCommDevice() and QueryCommDevice() thread unsafe ?
- * use of a module_init() ?
- */
+ /* NB: error management to be done outside of this function */
- if (_CommDevices == NULL)
- {
- _CommDevices = (COMM_DEVICE**)calloc(COMM_DEVICE_MAX+1, sizeof(COMM_DEVICE*));
+ assert(_CommDevices == NULL);
+ assert(_CommHandleCreator == NULL);
+
+ _CommDevices = (COMM_DEVICE**)calloc(COMM_DEVICE_MAX+1, sizeof(COMM_DEVICE*));
- _CommHandleCreator = (HANDLE_CREATOR*)malloc(sizeof(HANDLE_CREATOR));
+ _CommHandleCreator = (HANDLE_CREATOR*)malloc(sizeof(HANDLE_CREATOR));
+ if (_CommHandleCreator)
+ {
_CommHandleCreator->IsHandled = IsCommDevice;
_CommHandleCreator->CreateFileA = CommCreateFileA;
-
+
RegisterHandleCreator(_CommHandleCreator);
}
+
+ assert(_CommDevices != NULL);
+ assert(_CommHandleCreator != NULL);
}
* information, call GetLastError.
*
* ERRORS:
+ * ERROR_DLL_INIT_FAILED
* ERROR_OUTOFMEMORY was not possible to get mappings.
* ERROR_INVALID_DATA was not possible to add the device.
*/
LPTSTR storedDeviceName = NULL;
LPTSTR storedTargetPath = NULL;
- _CommDevicesInit();
+ if (pthread_once(&_CommInitialized, _CommInit) != 0)
+ {
+ SetLastError(ERROR_DLL_INIT_FAILED);
+ goto error_handle;
+ }
+
if (_CommDevices == NULL)
{
- SetLastError(ERROR_OUTOFMEMORY);
+ SetLastError(ERROR_DLL_INIT_FAILED);
goto error_handle;
}
*
* ERRORS:
* ERROR_SUCCESS
+ * ERROR_DLL_INIT_FAILED
* ERROR_OUTOFMEMORY was not possible to get mappings.
* ERROR_NOT_SUPPORTED equivalent QueryDosDevice feature not supported.
* ERROR_INVALID_DATA was not possible to retrieve any device information.
SetLastError(ERROR_SUCCESS);
- _CommDevicesInit();
+ if (pthread_once(&_CommInitialized, _CommInit) != 0)
+ {
+ SetLastError(ERROR_DLL_INIT_FAILED);
+ return 0;
+ }
+
if (_CommDevices == NULL)
{
- SetLastError(ERROR_OUTOFMEMORY);
+ SetLastError(ERROR_DLL_INIT_FAILED);
return 0;
}
/**
* api-ms-win-core-file-l1-2-0.dll:
- *
+ *
* CreateFileA
* CreateFileW
* CreateFile2
#include <unistd.h>
#endif
+#include <assert.h>
#include <time.h>
#include <errno.h>
+#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
* winpr-collections to avoid a circular dependency
* _HandleCreators = ArrayList_New(TRUE);
*/
-static HANDLE_CREATOR **_HandleCreators = NULL;
-
+/* _HandleCreators is a NULL-terminated array with a maximun of HANDLE_CREATOR_MAX HANDLE_CREATOR */
#define HANDLE_CREATOR_MAX 128
+static HANDLE_CREATOR **_HandleCreators = NULL;
+static pthread_once_t _HandleCreatorsInitialized = PTHREAD_ONCE_INIT;
static void _HandleCreatorsInit()
{
- /*
- * TMP: FIXME: What kind of mutex should be used here? use of
- * a module_init()?
- */
+ /* NB: error management to be done outside of this function */
- if (_HandleCreators == NULL)
- {
- _HandleCreators = (HANDLE_CREATOR**)calloc(HANDLE_CREATOR_MAX+1, sizeof(HANDLE_CREATOR*));
- }
+ assert(_HandleCreators == NULL);
+
+ _HandleCreators = (HANDLE_CREATOR**)calloc(HANDLE_CREATOR_MAX+1, sizeof(HANDLE_CREATOR*));
+
+ assert(_HandleCreators != NULL);
}
/**
* Returns TRUE on success, FALSE otherwise.
*
* ERRORS:
+ * ERROR_DLL_INIT_FAILED
* ERROR_INSUFFICIENT_BUFFER _HandleCreators full
*/
BOOL RegisterHandleCreator(PHANDLE_CREATOR pHandleCreator)
{
int i;
- _HandleCreatorsInit();
+ if (pthread_once(&_HandleCreatorsInitialized, _HandleCreatorsInit) != 0)
+ {
+ SetLastError(ERROR_DLL_INIT_FAILED);
+ return FALSE;
+ }
+
+ if (_HandleCreators == NULL)
+ {
+ SetLastError(ERROR_DLL_INIT_FAILED);
+ return FALSE;
+ }
+
for (i=0; i<HANDLE_CREATOR_MAX; i++)
{
#endif /* HAVE_AIO_H */
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
+ DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
int i;
char* name;
if (!lpFileName)
return INVALID_HANDLE_VALUE;
- _HandleCreatorsInit();
+ if (pthread_once(&_HandleCreatorsInitialized, _HandleCreatorsInit) != 0)
+ {
+ SetLastError(ERROR_DLL_INIT_FAILED);
+ return INVALID_HANDLE_VALUE;
+ }
+
if (_HandleCreators == NULL)
+ {
+ SetLastError(ERROR_DLL_INIT_FAILED);
return INVALID_HANDLE_VALUE;
+ }
for (i=0; _HandleCreators[i] != NULL; i++)
{
}
}
- /* * */
+ /* TODO: use of a HANDLE_CREATOR for named pipes as well */
if (!IsNamedPipeFileNameA(lpFileName))
return INVALID_HANDLE_VALUE;