I have a program called trickle that gives a warning and in its source code there is:
if (stat(sockname, &sb) == -1 &&
(errno == EACCES || errno == ENOENT))
warn("Could not reach trickled, working independently");
But the message I've got is:
trickle: Could not reach trickled, working independently: No such file or directory
Where does this No such file or directory come from?
I think that when you get a error value that is stocked in errno, the function warn can use it as a precision.
In this particular case I bet it's the ENOENT for Error NO ENTry that is in errno.
From man warn(3):
The err(), verr(), warn(), and vwarn() functions append an error message obtained from strerror(3) based on the global variable errno, preceded by another colon and space unless the fmt argument is NULL.
That message is coming from the second part of your if (..) comparison.
The code has executed a stat() system call, on sockname.
However, stat() returned ENOENT, which translates to "No such file or directory"
You need to find out how sockname is constructed to see whether it should have
been valid.
The error is coming from the stat function and is being reported as part of the warn function. In more detail, from the warn documentation:
The Fn err and Fn warn family of functions display a formatted error
message on the standard error output. In all cases, the last
component of the program name, a colon character, and a space are
output. If the Fa fmt argument is not NULL, the printf(3) -like
formatted error message is output. The output is terminated by a
newline character.
The Fn err , Fn verr , Fn warn , and Fn vwarn functions append an
error message obtained from strerror(3) based on a code or the global
variable errno preceded by another colon and space unless the Fa fmt
argument is NULL enter code here
So the "No such file or directory" is coming from the stat operation because it can't find sockname and is being passed to the warn function via a code.
Related
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?
I created my own shell and trying to redirect the STDERR to output file.
I did :
dup2(output_fd, 2);
and when I am executing child, I am using
error_message = strerror(errno);
write(STDERR_FILENO, error_message, strlen(error_message));
but the problem is I am getting this error message only :
No such file or directory
whereas I should be getting
ls: cannot access '/no/such/file': No such file or directory
running program : ls /no/such/file > output
ls is printing the message ls: cannot access 'stuff': by itself - in ls.c file_failure(... "cannot access") call and file_failure() definition and error() is a standard function from error.h. There's even no strerror call in ls sources - error() in glibc sources calls it.
So write the message yourself, use fprintf(stderr to format your message, or you may use GNU extension erorr() if you want.
strerror should return just "No such file or directory" and this is the standard message from strerror for ENOENT. There is errno -l to list errors with strings in terminal and here is list of errors in glibc sources.
So, I tried to find an answer to this question unsuccessfully.
I know what to do and how to manage such a case - by using fluss/NULL etc. afterward. But checking it is tricky to me.
So, basically:
open some file(successfully) - let's call the pointer: file.
after some code running...
fclose(file);
Now, how can I check after(before it's also an option) closing the file - that it really happened?
What is the condition? By demand, I need to handle this case by printing some specific errors.
You can use the following snippet:
#include <errno.h>
if(fclose(file) != 0)
{
fprintf(stderr, "Error closing file: %s", strerror(errno));
}
From the man pages, we see that an error in closing a file using fclose() sets the global variable errno to a value indicating what error occurred. The function strerror() takes this value of errno and outputs a string to help indicate what the error actually was.
I am using an execv function to run a program called code.x.
code.x has a part where it guarantees its failure by Assertion.
My code that runs execl is:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
int main()
{
pid_t pid;
char *args[] = { "./code.x",NULL };
pid = fork();
if (pid > 0) {
wait(NULL);
printf("%s\n", strerror(errno));
printf("done\n");
}
else if (pid == 0) {
printf("%s\n", strerror(errno));
execv(args[0], args);
printf("should fail");
}
else {
printf("forkfail");
}
return 1;
}
the code prints
Success
code.x: code.c:15: main: Assertion '0 == 1' failed.
Success
done
"should fail" is never printed and WEXITSTATUS(status) shows that the exit status is 0.
The exec family of functions replace the calling process with a new program in its initial state loaded from an executable file. They can only fail if this replacement fails, e.g. due to the requested file not existing or the invoking user not having permissions to access/execute it.
If an assertion failure in the program ./code.x you're invoking happens, this is long past the point where execv could have failed; at this point, the original program state where execv was performed no longer exists, because it was already replaced. The parent process will see it exit via a wait-family function, and can inspect the status reported by the wait-family function to determine why it exited.
exec* functions succeed if the program starts running. Your program did start running.
An assertion failure causes the program to abort, exit with a signal. The Linux manual page wait(2) explains that:
WEXITSTATUS(wstatus)
returns the exit status of the child. This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as
the argument for a return statement in main(). This macro should be employed only if WIFEXITED returned true.
If you didn't check that WIFEXITED(status) is true, then WEXITSTATUS(status) is garbage.
Instead, check WIFSIGNALED(status) and if true, get the signal - WTERMSIG(status), which should equal to SIGABRT.
execv successfully did its job. The process ./code.x executed, then exited because of an assertiong.
The exec family of functions don't care about the process's return value. Once the process starts, the calling process is effectively terminated and gone.
Exec will only return if for some reason the process couldn't be started at all. Specifically, only these errors (taken from the man page) will cause exec to return and set errno to one of these values:
E2BIG The total number of bytes in the environment (envp) and argument list (argv) is too large.
EACCES Search permission is denied on a component of the path prefix of filename or the name of a script interpreter. (See also path_resolution(7).)
EACCES The file or a script interpreter is not a regular file.
EACCES Execute permission is denied for the file or a script or ELF interpreter.
EACCES The filesystem is mounted noexec.
EAGAIN (since Linux 3.1)
Having changed its real UID using one of the set*uid() calls, the caller was—and is now still—above its RLIMIT_NPROC resource limit (see
setrlimit(2)). For a more detailed explanation of this error, see NOTES.
EFAULT filename or one of the pointers in the vectors argv or envp points outside your accessible address space.
EINVAL An ELF executable had more than one PT_INTERP segment (i.e., tried to name more than one interpreter).
EIO An I/O error occurred.
EISDIR An ELF interpreter was a directory.
ELIBBAD An ELF interpreter was not in a recognized format.
ELOOP Too many symbolic links were encountered in resolving filename or the name of a script or ELF interpreter.
ELOOP The maximum recursion limit was reached during recursive script interpretation (see "Interpreter scripts", above). Before Linux 3.8, the
error produced for this case was ENOEXEC.
EMFILE The per-process limit on the number of open file descriptors has been reached.
ENAMETOOLONG filename is too long.
ENFILE The system-wide limit on the total number of open files has been reached.
ENOENT The file filename or a script or ELF interpreter does not exist, or a shared library needed for the file or interpreter cannot be found.
ENOEXEC An executable is not in a recognized format, is for the wrong architecture, or has some other format error that means it cannot be executed.
ENOMEM Insufficient kernel memory was available.
ENOTDIR A component of the path prefix of filename or a script or ELF interpreter is not a directory.
EPERM The filesystem is mounted nosuid, the user is not the superuser, and the file has the set-user-ID or set-group-ID bit set.
EPERM The process is being traced, the user is not the superuser and the file has the set-user-ID or set-group-ID bit set.
EPERM A "capability-dumb" applications would not obtain the full set of permitted capabilities granted by the executable file. See capabilities(7).
ETXTBSY The specified executable was open for writing by one or more processes.
The Exec function family replaces the existing process image with a new process image. This is why it is required to fork before spawning another process, because the currently running process is completely replaced, this includes the program counter, which keeps track of the next instruction to execute.
printf("should fail");
is never excecuted because the instant you called execv(args[0], args), the program counter was moved to execute args[0], thus leaving behind the execution path that would have resulted in that print statement.
Exec returns -1 on the condition that it encountered an error while replacing the image, and has absolutely no relation to the return value of the program being executed. This is because the two processes, after Exec is called, are not coordinating with each other at all. Remember: the fork() command created a new address space, which means that these processes are now running in separate domains on separate executables.
Some documentation may be of help:
http://man7.org/linux/man-pages/man3/exec.3.html
Hope this helped.
In a script I often call the function Rcplex(), which prints "CPLEX environment opened" and "Closed CPLEX environment" to the console. Since the function is called rather frequently, it prints this very often, which is quite annoying. Is there a way to suppress this? I tried sink(), suppressWarnings/Messages or invisible(catch.output()) but none of these did the trick. I proceeded to check the code of Rcplex() and found where the printing to the console happens. Rcplex() calls an underlying C-function (Rcplex.c). In the code of rcplex.c I located the commands which cause the printing:
REprintf("CPLEX environment opened\n");
REprintf("Closed CPLEX environment\n");
Is there a way to capture the output from REprintf() so that it does not get printed to the R-console? One way would obviously be to mess around with the Rcplex.c file and delete the corresponding lines. However, this would not be a very clean solution, which is why I'm asking for another way to capture the output from C-functions.
You had problems using sink() and capture.output() normally because sink() does not redirect output from REprintf, as we see in comments from the source code for REprintf:
/* =========
* Printing:
* =========
*
* All printing in R is done via the functions Rprintf and REprintf
* or their (v) versions Rvprintf and REvprintf.
* These routines work exactly like (v)printf(3). Rprintf writes to
* ``standard output''. It is redirected by the sink() function,
* and is suitable for ordinary output. REprintf writes to
* ``standard error'' and is useful for error messages and warnings.
* It is not redirected by sink().
However, we can use type = "message" to deal with this; from help("capture.output"):
Messages sent to stderr() (including those from message, warning and
stop) are captured by type = "message". Note that this can be "unsafe" and should only be used with care.
First I make a C++ function with the same behavior you're dealing with:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector example_function(NumericVector x) {
REprintf("CPLEX environment opened\n");
REprintf("Closed CPLEX environment\n");
// As mentioned by Dirk Eddelbuettel in the comments,
// Rcpp::Rcerr goes into the same REprintf() stream:
Rcerr << "Some more stuff\n";
return x;
}
If I call it from R normally, I get:
example_function(42)
CPLEX environment opened
Closed CPLEX environment
Some more stuff
[1] 42
However, I could instead do this:
invisible(capture.output(example_function(42), type = "message"))
[1] 42
And while the output is is printed to the console, the message is not.
Warning
I would be remiss if I didn't mention the warning from the help file I quoted above:
Note that this can be "unsafe" and should only be used with care.
The reason is that this will eliminate all output from actual errors as well. Consider the following:
> log("A")
Error in log("A") : non-numeric argument to mathematical function
> invisible(capture.output(log("A"), type = "message"))
>
You may or may not want to therefore send the captured output to a text file in case you have to diagnose something that went wrong. For example:
invisible(capture.output(log("A"), type = "message", file = "example.txt"))
Then I don't have to see the message in the console, but if I need to check example.txt afterward, the message is there:
Error in log("A") : non-numeric argument to mathematical function