While trying to open a semaphore sem_open fails. errno is 22 (), which perror describes as "Invalid argument". I've checked the format of the name (which I think is correct), as well as the flags (O_CREAT and O_EXCL seem pretty hard to mess up. What am I not seeing?
Platform is OS X 10.7. I would have preferred to use a nameless semaphore, but the OS doesn't support sem_init.
int name_counter = 0;
// In order to create a unique semaphore, we iterate until we find a name that
// does not already exist.
do {
char name[48] = {0};
sprintf(name, "xyz_sem_%d", name_counter++);
job_semaphore = sem_open(name, O_CREAT | O_EXCL, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, 0);
} while(errno == EEXIST);
if(0 != errno)
perror("Error opening xyz semaphore");
assert(0 == errno);
I've tried both
sem_open(name, O_CREAT | O_EXCL);
and
sem_open(name, O_CREAT | O_EXCL, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, 0);
to open the semaphore, but get the same result with each. What am I missing?
EDIT: the version above with only two parameters is wrong- the man page says that when including O_CREAT, you must provide all 4 parameters.
EDIT2: errno is only valid when the function returns an error code. In this case, I should have looked at errno only when sem_open returned SEM_FAILED. I didn't do this, and was examining errno when a perfectly good semaphore had been returned. Problem solved.
Before trying sem_open, try sem_unlink()
name should have a leading slash. Try put a "/" in front of name.
ie. sprintf(name, "/xyz_sem_%d", name_counter++);
Related
I am trying atm to create a shared memory file for my process. The filename constists of several parts to identify the process the SHM belongs to and whats its content. An example would be:
shm_pl_dev_system_25077
I create all the files in a directory I created in /tmp where I have full write and read permissions.
So the complete Path would be:
/tmp/pl_dev/shm_pl_dev_system_25077
I create several files there, some fifo pipes and other stuff and also the shm. The only Problem I get is that shm_open will always return the errno 63 (ENAMETOOLONG).
Can you tell me what the issue here is?
Here is the code:
handle_ = ::shm_open(shm_name.get(), O_RDWR, 0755);
if (handle_ == -1 && errno == ENOENT)
{
// SHM does not yet exists, so create it!
handle_ = ::shm_open(shm_name.get(), O_CREAT | O_RDWR, 0755);
if (handle_ != -1) {
created_ = true;
}
else
{
if (!silent_)
{
log.error("Couldn't create the SHM (%d).", errno);
}
return false;
}
}
Okay. As it seems OSX is very limited in the filename of SHMs... The maximum length for a filename currently is 31 chars per section (see PSHMNAMELENGTH in /usr/include/sys/posix_shm.h)
I have a user app that opens a file and then calls CreateFileMapping. I have a driver that creates/opens the file which I have traced and successfully executes. The problem is that CreateFileMapping always returns error 193. I have successfully mapped against other files so I'm thinking must be an issue on the driver side. Windows 8.1 x64 (driver obviously 64bit) and the application as well. I have used dependency walker to check any dll issues and all seem to be fine.
Driver snippet:
InitializeObjectAttributes(&fileAttributes,
&fileName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, // RootDirectory
NULL // SecurityDescriptor
);
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
return STATUS_INVALID_DEVICE_STATE;
status = ZwCreateFile(
&context->FileHandle,
SYNCHRONIZE | FILE_GENERIC_WRITE | FILE_GENERIC_READ | DELETE,
&fileAttributes,
&ioStatus,
NULL, // alloc size = none
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN_IF,
FILE_RANDOM_ACCESS |
FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE |
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DEVICE_SECURE_OPEN,
NULL, // eabuffer
0 // ealength
);
User app snippet:
LPCWSTR dev_path = L"\\\\.\\testdisk.txt";
fd = CreateFile(dev_path, FILE_GENERIC_READ | FILE_GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, // FILE_SHARE_DELETE
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fd == INVALID_HANDLE_VALUE)
{
error("open device %ls failed, %s (%u)\n", dev_path, strerror(errno), GetLastError());
exit(EXIT_FAILURE);
}
mapFile = CreateFileMapping(
fd,
NULL,
PAGE_READWRITE,
0, // maximum object size (high-order DWORD)
1, // maximum object size (low-order DWORD)
NULL);
Edit 1:
The filename in the driver is #define DEV_PATH L"\\DosDevices\\C:\\testdisk.txt"
The symbolic link is #define DEV_SYMBOLIC_LINK L"\\DosDevices\\testdrive.txt" using the function WdfDeviceCreateSymbolicLink
and I set the device name to #define DEV_NAME L"\\Device\\testdrive.txt" using the function WdfDeviceInitAssignName
Edit 2:
I have updated the device and file paths. I still get 193 error when accessing the file from user space \\.\qqdevice\test.txt and if I use C:\qqdevice\test.txt then the file gets created but the driver never gets notified.
#define DEV_NAME L"\\Device\\qqdevice"
#define DEV_SYMBOLIC_LINK L"\\DosDevices\\qqdevice"
#define DEV_FILE_PATH L"\\DosDevices\\C:\\qqdevice\\test.txt"
My goal is to have a program that sleeps in the background but can be activated by the user via some "hotkey". From digging around the Xlib manual and the Xlib O'reilly manual, I gather that the correct way to to this is with XGrabKey. However my understanding of the process is incorrect as a simple proof of concept does not work.
My understanding is that if I call XGrabKey with the root window as the grab_window, and owner_events false, then whenever my hotkey is pressed the event will be sent only to the root window. If I then select KeyPress events from the root window, and then listen for X events, I should get a key press event when the hotkey is pressed. I've pasted a minimal example below.
What I expect is that when the program is run, regardless of what window has focus, if Ctrl+Shift+K is pressed, my program should output "Hot key pressed!" in the console, and then terminate.
Furthermore, it is my understanding that if the XGrabKey fails, the default error handler will display a message, and since it does not I am assuming that the call succeeds.
Obviously, my understanding is flawed somehow. Can anyone point me in the right direction?
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
using namespace std;
int main()
{
Display* dpy = XOpenDisplay(0);
Window root = DefaultRootWindow(dpy);
XEvent ev;
unsigned int modifiers = ControlMask | ShiftMask;
int keycode = XKeysymToKeycode(dpy,XK_Y);
Window grab_window = root;
Bool owner_events = False;
int pointer_mode = GrabModeAsync;
int keyboard_mode = GrabModeAsync;
XGrabKey(dpy, keycode, modifiers, grab_window, owner_events, pointer_mode,
keyboard_mode);
XSelectInput(dpy, root, KeyPressMask );
while(true)
{
bool shouldQuit = false;
XNextEvent(dpy, &ev);
switch(ev.type)
{
case KeyPress:
cout << "Hot key pressed!" << endl;
XUngrabKey(dpy,keycode,modifiers,grab_window);
shouldQuit = true;
default:
break;
}
if(shouldQuit)
break;
}
XCloseDisplay(dpy);
return 0;
}
Your program works here. My guess is you have another modifier active, such as NumLock. GrabKey only works on the exact modifier mask.
For example here is some (GPL) code from metacity window manager
/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
static void
meta_change_keygrab (MetaDisplay *display,
Window xwindow,
gboolean grab,
int keysym,
unsigned int keycode,
int modmask)
{
unsigned int ignored_mask;
/* Grab keycode/modmask, together with
* all combinations of ignored modifiers.
* X provides no better way to do this.
*/
meta_topic (META_DEBUG_KEYBINDINGS,
"%s keybinding %s keycode %d mask 0x%x on 0x%lx\n",
grab ? "Grabbing" : "Ungrabbing",
keysym_name (keysym), keycode,
modmask, xwindow);
/* efficiency, avoid so many XSync() */
meta_error_trap_push (display);
ignored_mask = 0;
while (ignored_mask <= display->ignored_modifier_mask)
{
if (ignored_mask & ~(display->ignored_modifier_mask))
{
/* Not a combination of ignored modifiers
* (it contains some non-ignored modifiers)
*/
++ignored_mask;
continue;
}
if (meta_is_debugging ())
meta_error_trap_push_with_return (display);
if (grab)
XGrabKey (display->xdisplay, keycode,
modmask | ignored_mask,
xwindow,
True,
GrabModeAsync, GrabModeSync);
else
XUngrabKey (display->xdisplay, keycode,
modmask | ignored_mask,
xwindow);
if (meta_is_debugging ())
{
int result;
result = meta_error_trap_pop_with_return (display, FALSE);
if (grab && result != Success)
{
if (result == BadAccess)
meta_warning (_("Some other program is already using the key %s with modifiers %x as a binding\n"), keysym_name (keysym), modmask | ignored_mask);
else
meta_topic (META_DEBUG_KEYBINDINGS,
"Failed to grab key %s with modifiers %x\n",
keysym_name (keysym), modmask | ignored_mask);
}
}
++ignored_mask;
}
meta_error_trap_pop (display, FALSE);
}
With your mask ControlMask | ShiftMask you will not get the key if another modifier key is held. This sounds okay in the first place, but there's a pitfall: NumLock, CapsLock and alike all are treated as modifiers, too.
You have two options:
You call XGrabKey() multiple times, once for each explicit combination that you're interested in.
You call XGrabKey() with AnyModifier and use event.xkey.state to check whether the modifiers are as you expected.
The header file <X.h> defines ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask and AnyModifier.
The keys are:
Mask | Value | Key
------------+-------+------------
ShiftMask | 1 | Shift
LockMask | 2 | Caps Lock
ControlMask | 4 | Ctrl
Mod1Mask | 8 | Alt
Mod2Mask | 16 | Num Lock
Mod3Mask | 32 | Scroll Lock
Mod4Mask | 64 | Windows
Mod5Mask | 128 | ???
Warning I found out about the ModNMask keys by trying and I do not know if this is valid on all machines / configurations / versions / operating systems.
In your case, you probably want to make sure that ShiftMask | CtrlMask is set, Mod1Mask | Mod4Mask are clear, and the others to be ignored.
I'd do this to setup the key grab:
XGrabKey(dpy, keycode, AnyModifier, grab_window, owner_events, pointer_mode, keyboard_mode);
And this to check whether the right modifiers are set:
switch (ev.type) {
case KeyPress:
if ((ev.xkey.state & (ShiftMask | CtrlMask | Mod1Mask | Mod4Mask)) == (ShiftMask | CtrlMask))
// ...
}
If you're using/targeting gtk on X11, there's a C library with a much simpler interface:
https://github.com/engla/keybinder
Includes Python, Lua and Vala bindings. (Also mentioned here.)
We want to write to "foo.txt" in a given directory. If "foo.txt" already exists, we want to write to "foo-1.txt", and so on.
There are a few code snippets around that try and answer this question, but none are quite satisfactory. E.g. this solution at CocoaDev uses NSFileManager to test if a path exists to create a safe path. However, this leads to obvious race conditions between obtaining a path and writing to it. It would be safer to attempt atomic writes, and loop the numeric suffix on failure.
Go at it!
Use the open system call with the O_EXCL and O_CREAT options. If the file doesn't already exist, open will create it, open it, and return the file descriptor to you; if it does exist, open will fail and set errno to EEXIST.
From there, it should be obvious how to construct the loop that tries incrementing filenames until it returns a file descriptor or constructs a filename too long. On the latter point, make sure you check errno when open fails—EEXIST and ENAMETOOLONG are just two of the errors you could encounter.
int fd;
uint32_t counter;
char filename[1024]; // obviously unsafe
sprintf(filename, "foo.txt");
if( (fd = open(filename, O_CREAT | O_EXCL | O_EXLOCK, 0644)) == -1 && errno == EEXIST )
{
for( counter = 1; counter < UINT32_MAX; counter++ ) {
sprintf(filename, "foo-%u.txt", counter);
if( (fd = open(filename, O_CREAT | O_EXCL | O_EXLOCK, 0644)) == -1 && errno == EEXIST )
continue;
else
break;
}
}
if( fd == -1 && counter == UINT32_MAX ) {
fprintf(stderr, "too many foo-files\n");
} else if( fd == -1 ) {
fprintf(stderr, "could not open file: %s\n", strerror(errno));
}
// otherwise fd is an open file with an atomically unique name and an
// exclusive lock.
How about:
Write the file to a temporary directory where you know there's no risk of collision
Use NSFileManager to move the file to the preferred destination
If step 3 fails due to a file already existing, add/increment a numeric suffix and repeat step 2
You'd be basically re-creating Cocoa's atomic file write handling, but adding in the feature of ensuring a unique filename. A big advantage of this approach is that if the power goes out or your app crashes mid-write, the half-finished file will be tucked away in a tmp folder and deleted by the system; not left for the user to try and work with.
What are the Win32 APIs to use to programically delete files and folders?
Edit
DeleteFile and RemoveDirectory are what I was looking for.
However, for this project I ended up using SHFileOperation.
I found the sample code at CodeGuru helpful.
There are two ways to approach this. One is through the File Services (using commands such as DeleteFile and RemoveDirectory) and the other is through the Windows Shell (using SHFileOperation). The latter is recommended if you want to delete non-empty directories or if you want explorer style feedback (progress dialogs with flying files, for example). The quickest way of doing this is to create a SHFILEOPSTRUCT, initialise it and call SHFileOperation, thus:
void silently_remove_directory(LPCTSTR dir) // Fully qualified name of the directory being deleted, without trailing backslash
{
SHFILEOPSTRUCT file_op = {
NULL,
FO_DELETE,
dir,
"",
FOF_NOCONFIRMATION |
FOF_NOERRORUI |
FOF_SILENT,
false,
0,
"" };
SHFileOperation(&file_op);
}
This silently deletes the entire directory. You can add feedback and prompts by varying the SHFILEOPSTRUCT initialisation - do read up on it.
I think you want DeleteFile and RemoveDirectory
See uvgroovy's comment above. You need 2 nulls at the end of the 'dir' field.
int silently_remove_directory(LPCTSTR dir) // Fully qualified name of the directory being deleted, without trailing backslash
{
int len = strlen(dir) + 2; // required to set 2 nulls at end of argument to SHFileOperation.
char* tempdir = (char*) malloc(len);
memset(tempdir,0,len);
strcpy(tempdir,dir);
SHFILEOPSTRUCT file_op = {
NULL,
FO_DELETE,
tempdir,
NULL,
FOF_NOCONFIRMATION |
FOF_NOERRORUI |
FOF_SILENT,
false,
0,
"" };
int ret = SHFileOperation(&file_op);
free(tempdir);
return ret; // returns 0 on success, non zero on failure.
}
I believe DeleteFile does not send the file to the Recycle Bin. Also, RemoveDirectory removes only empty dirs. SHFileOperation would give you the most control over what and how to delete and would show the standard Windows UI dialog boxes (e.g. "Preparing to delete etc.) if needed.
/* function used to send files and folder to recycle bin in win32 */
int fn_Send_Item_To_RecycleBin(TCHAR newpath[])
{
_tcscat_s(newpath, MAX_PATH,_T("|"));
TCHAR* Lastptr = _tcsrchr(newpath, _T('|'));
*Lastptr = _T('\0'); // Replace last pointer with Null for double null termination
SHFILEOPSTRUCT shFileStruct;
ZeroMemory(&shFileStruct,sizeof(shFileStruct));
shFileStruct.hwnd=NULL;
shFileStruct.wFunc= FO_DELETE;
shFileStruct.pFrom= newpath;
shFileStruct.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
return SHFileOperation(&shFileStruct);
}
For C++ programming, if you're willing to work with third-party libraries,
boost::filesystem::remove_all(yourPath)
is much simpler than SHFileOperation.