When does the open() function fail with an Invalid argument? - c

I am using fswebcam to capture images from a USB device.
The command is fswebcam -d /dev/v4l/by-id/device-id-of-usb-webcam-index0 /home/myhome/output.jpg.
Usually, it works fine.
But once it gave the following error:
Failed to open /dev/v4l/by-id/device-id-of-usb-webcam-index0: Invalid argument
[1m--- Opening /dev/v4l/by-id/device-id-of-usb-webcam-index0...
[0m[0mTrying source module v4l2...
[0m[31mError opening device: /dev/v4l/by-id/device-id-of-usb-webcam-index0
[0m[31mopen: Invalid argument
[0m[0mTrying source module v4l1...
[0m[31mError opening device: /dev/v4l/by-id/device-id-of-usb-webcam-index0
[0m[31mopen: Invalid argument
[0m[31mUnable to find a source module that can read /dev/v4l/by-id/device-id-of-usb-webcam-index0.
I tried to see when this happens by reading fswebcam's source code at https://github.com/fsphil/fswebcam/blob/master/src_v4l2.c#L817
Basically the code s->fd = open(src->source, O_RDWR | O_NONBLOCK); fails with errno being set to EINVAL.
But I am wondering when would this happen.
I tried making a symlink to an non-existing file, but it didn't work (prints open: No such file or directory)
Is there a way to make the open function return with errno EINVAL?

Related

How to fix "HDF5-DIAG: Error unable to open file"?

When trying to run a MEEP simulation the following error appears:
HDF5-DIAG: Error detected in HDF5 (1.10.5) thread 0:
#000: H5F.c line 509 in H5Fopen(): unable to open file
major: File accessibilty
minor: Unable to open file
#001: H5Fint.c line 1498 in H5F_open(): unable to open file: time = Fri Nov 15 16:56:54 2019
, name = '*.h5', tent_flags = 0
major: File accessibilty
minor: Unable to open file
#002: H5FD.c line 734 in H5FD_open(): open failed
major: Virtual File Layer
minor: Unable to initialize object
#003: H5FDsec2.c line 346 in H5FD_sec2_open(): unable to open file: name = '*.h5', errno = 2, error message = 'No such file or directory', flags = 0, o_flags = 0
major: File accessibilty
minor: Unable to open file
h5topng error: error opening HD5 file
rm: *.h5: No such file or directory
Could somebody enlighten me on how to fix this/understand the error?
Thanks in advance
Disclaimer: I have never worked with MEEP.
The error seems to indicate taht the file doesn't exist:
#003: H5FDsec2.c line 346 in H5FD_sec2_open(): unable to open file: name = '*.h5', errno = 2, error message = 'No such file or directory', flags = 0, o_flags = 0
So this appears to be the core issue.
Going further down the rabbit hole it seems that the file name passed to H5FD_sec2_open() is *.h5 which is most likely an invalid file name. I expect you want to pass something such as foo.h5 or relative/path/to/foo.h5 or /absolute/path/to/foo.h5 to the H5FD_sec2_open() function.
The wildcard is something that is usually not handled/interpreted by these kinds of functions. It's a higher level concept and requires "more filesystem access" to do anything useful with it as whoever receives that wildcard has to get a list of files & directories and figure out which file system entries match this wildcard.
Therefore, my answer would be: Make sure that you pass a valid file path to the corresponding file opening function.
Furthermore, you might want to extend your program so that it checks whether it's a valid file before you pass it to the corresponding MEEP function which allows you to have better error and user feedback control.

How do I read a 'family' of h5 files using python?

These are files in the file system as:
vgg16_weights_tf_dim_ordering_tf_kernels_0.h5
vgg16_weights_tf_dim_ordering_tf_kernels_1.h5
vgg16_weights_tf_dim_ordering_tf_kernels_2.h5
vgg16_weights_tf_dim_ordering_tf_kernels_3.h5
vgg16_weights_tf_dim_ordering_tf_kernels_4.h5
vgg16_weights_tf_dim_ordering_tf_kernels_5.h5
an attempt to open 'vgg16_weights_tf_dim_ordering_tf_kernels_0.h5' causes an error that suggests Family driver should be used
opening with
f = h5py.File('../input/keras-models/vgg16_weights_tf_dim_ordering_tf_kernels_0.h5','r', driver='family')
causes error "file name not unique"
opening with
f = h5py.File('../input/keras-models/vgg16_weights_tf_dim_ordering_tf_kernels_%d.h5','r', driver='family')
causes error "Unable to open file (Family member size should be 102400000. but the size from file access property is 2147483647)"
After some research I found the right way of opening a family of files as:
h5py.File('../input/keras-models/vgg16_weights_tf_dim_ordering_tf_kernels_%d.h5','r', driver='family', memb_size=102400000)
The default memb_size is 2**31-1 (i.e. 2147483647). If file family is written with member size specified as 102400000, one should also open it with the same.

ld searching malformed directory paths

I'm linking to a library on my filesystem using ld.
When I run the command ld -verbose -lmylib, I get the following back:
attempt to open /usr/x86_64-linux-gnu/lib64/libmylib.so failed
attempt to open /usr/x86_64-linux-gnu/lib64/libmylib.a failed
attempt to open //usr/local/lib/x86_64-linux-gnu/libmylib.so failed
attempt to open //usr/local/lib/x86_64-linux-gnu/libmylib.a failed
attempt to open //usr/local/lib64/libmylib.so failed
attempt to open //usr/local/lib64/libmylib.a failed
attempt to open //lib/x86_64-linux-gnu/libmylib.so failed
attempt to open //lib/x86_64-linux-gnu/libmylib.a failed
attempt to open //lib64/libmylib.so failed
attempt to open //lib64/libmylib.a failed
attempt to open //usr/lib/x86_64-linux-gnu/libmylib.so failed
attempt to open //usr/lib/x86_64-linux-gnu/libmylib.a failed
attempt to open //usr/lib64/libmylib.so failed
attempt to open //usr/lib64/libmylib.a failed
attempt to open //usr/local/lib/libmylib.so failed
attempt to open //usr/local/lib/libmylib.a failed
attempt to open //lib/libmylib.so failed
attempt to open //lib/libmylib.a failed
attempt to open //usr/lib/libmylib.so failed
attempt to open //usr/lib/libmylib.a failed
ld: cannot find -lmylib
I'm confused as to why it's trying to open files prefixed with //. This is not the case for another computer of mine. I've tried changing LIBRARY_PATH, LD_LIBRARY_PATH, my PATH, etc. but nothing seems to work. I've looked online, but can't find anything. Where are these paths set?
Thanks.
The problem here is you are trying to link against the library mylib, but this library is not in the system's library search path, or it does not exists at all. You please make it locate at the right place. If the library is in another directory that is not in the library search path, you can add it with -L option to ld, like ld -verbose -L<the directory> -lmylib.
As for the double slash you see, it's not a problem, as more than more slashes are interpreted as one slash on Linux, that is to say, //foo/bar is the same as /foo/bar`, so don't need to worry about it.
As for the difference of the search path, on Fedora, the default search path is:
SEARCH_DIR("/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
While on Ubuntu, it is:
SEARCH_DIR("/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
So Ubuntu start each path with prefix '=', now let's see what ld does for this:
If searchdir begins with "=", then the "=" will be replaced by the sysroot prefix, controlled by the --sysroot option, or specified when the linker is configured.
That means = will be replaced by system root, which most like is / for a Linux system. That's why you see the double slashes on Ubuntu not on Fedora.

DeleteFile() or unlink() calls succeed but doesn't remove file

I am facing this strange problem.
To delete a file unlink() API is called in my code. This call removes the file and succeeds on non-windows platforms. On windows it succeeds (returns 0) but doesn't remove the file.
To experiment I added a loop to call same API repeatedly. In second iteration I got an Permission denied error, Error code =13. Though read/write attributes are set on file and program has full permission to access the file.
I then called DeleteFile() instead of unlink() API. To my surprise I see the same result,call succeeded i.e. returned 1 but file is not removed physically.
I checked through unlocker utility, no other program is accessing the file except the program which is trying to remove this file.
Does anyone has idea what else could be wrong ?
Edit1:
Just to ensure file was not opened at the time of removing it. I saved the handle when file was created and tried to close before removing the file but I got error "'UNOPENED' (Errcode: 9 - Bad file descriptor)". Thus I conclude the file was not open at the time of removing it.
Edit2
As requested, here is the simplified version of code used to create and remove the file.
// Code to create the file
int create_file(const char* path)
{
HANDLE osfh; /* OS handle of opened file */
DWORD fileaccess; /* OS file access (requested) */
DWORD fileshare; /* OS file sharing mode */
DWORD filecreate; /* OS method of opening/creating */
DWORD fileattrib; /* OS file attribute flags */
SECURITY_ATTRIBUTES SecurityAttributes;
SecurityAttributes.nLength= sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor= NULL;
SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);
fileaccess= GENERIC_WRITE;
fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
filecreate= CREATE_NEW;
if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes,
filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE)
{
// error handling
}
}
//Code to delete the file -
int remove_file (const char* name)
{
if ((err = unlink(name)) == -1)
{ //Error handling }
}
Edit3
As pointed by Joachim Pileborg and icabod, that DeleteFile() does not remove file if it is still open. As suggested by Remy Lebeau, to use process explorer. I found that one handle to file was indeed open when I closed that from process explorer file deleted like a charm :)
I had also mentioned in the Edit1 when I tried to close the file I got an error. It happened because the file descriptor I get from createfile() is not the actual handle returned by CreateFile() API instead a logical mapped handle due to underlying code complexities to support other non-windows platforms. Anyways, now I understood the root cause of problem but I was expecting if a file with open handle is passed to DeleteFile() API then it should fail in first attempt rather succeed and wait for open handles to close.
Assuming that you call your Createfile function, then later call your remove_file function... you still have a handle open to the file. The WinAPI function CreateFile, if it succeeds, keeps a handle open on the file. In your provided code, you don't close that handle.
From the documentation on DeleteFile:
The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed. Subsequent calls to CreateFile to open the file fail with ERROR_ACCESS_DENIED.
My guess is that you still have a handle open, and when you close that handle the file will be deleted.
However, your sample code is incomplete, so it is difficult to tell.

How can I improve the error reporting of this C open call in Windows?

As it stands the code looks like this:
fd = open(filename, openflag, perm);
I then call perror on open and receive
open: No error
open: No error
open: No error
open: No error
The final error call is:
die(1, "open_fds: File open error");
Yielding
SIO_ERROR: open_fds: File open error
What can I do to get more meaningful error messages?
Notes: This is for a Windows environment and I'm relatively new to C.
You can use perror or you can use strerror(errno) on Windows and both should work, here's an example of the latter:
int fd = open("some_made_up_file_name.txt", O_RDONLY);
if(fd < 0)
printf("%s\n", strerror(errno));
In this case I'd get:
No such file or directory
Because that file I'm trying to open doesn't exist and I didn't tell it to create in this case. You need to make sure you check the return from open(), < 0 and you have a problem.
As far as I have seen seen, perror works fine in windows also.
Do you know if open did fail (what did it return) & if it did fail, why did it fail in your case? Was the file not there or was it a permissions issue? And why did perror print the "No error" message 4 times?
What is the die function - as far as I know it's not a standard function? What does it do to print an error message?
On windows, you can also use GetLastError to get the error. (other than errno and perror).
You can use FormatMessage to format the error message corresponding to the error code returned by GetLastError.

Resources