What's the line after execve for since it doesn't return on success? - execve

26: execve(prog[0],prog,env);
27: return 0;
execve() does not return on success, and the text, data, bss, and
stack of the calling process are overwritten by that of the program
loaded.
what's return 0; for?

I suggest it is to cease this compiler warning.
$ cat | gcc -W -Wall -x c -
int main(){}
^D
<stdin>: In function 'main':
<stdin>:1:1: warning: control reaches end of non-void function
This also will make happy static analyzers and IDE warnings about same thing.

That line is in case execve() somehow fails and does return. Theoretically, it never should happen, but it does sometimes. Often, the return value is set to some random number to signify that there was an error.

Related

How to get return error code of popen?

I want the error code which return by 'popen'.
Popen command is as below:
fp = popen("/system/bin/pgrep -f "/system/bin/ffmpeg -loglevel quiet -re -i /data/misc/qmmf/LiveStreaming_FIFO_1.264 -codec copy -f rtsp -rtsp_transport tcp rtsp://11.11.11.11:554/live/stream1?wowzatoken=B-VDkZmspHh-G49SQIKghznGAHryq5zNc3NE7KEDgx8=" ","r");
I am getting the PID of the currently running ffmpeg process and am reading this popen() using a file pointer in an array. Then, read the PID(char by chat and using atoi()) and kill that PID.
Checking the (fp == NULL), but not getting NULL pointer.
Mainly, I want to kill that ffmpeg process. Not all running ffmpeg process, but the specific one which distinguishes by its name.
Are there any other ways apart from this?
Any suggestions would helpful.
Assuming a Linux system, man 3 popen explains the programming interface. popen() will return NULL when fork/pipe call fail or memory cannot be allocated. On success I/O stream pointer is returned. The value of the variable doesn't change unless a new value is assigned to the variable.
To wait for the process to terminate, you should use pclose(), which will return -1 on error. Additionally, both functions set errno if an error occurs.
If you need to reliably get the child process' PID, you need to do fork() call in your code and use it's return value. Since you won't be using popen(), you also need to set up pipe(s) in your code.
I don't know that I fully understand your question, but this is what the man page says about popen() errors:
RETURN VALUE
The popen() function returns NULL if the fork(2) or pipe(2) call fails, or if it cannot allocate memory.
ERRORS
The popen() function does not set errno if memory allocation fails. If the underlying fork(2) or pipe(2) fails, errno is set appropriately. If the type argument is invalid, and this condition is detected, errno is set to EINVAL.
Are you checking errno in addition to checking the return value?

Ghostscript for PS integrity test: terminate at EOF, return error unless stack is empty

To test the integrity of PostScript files, I'd like to run Ghostscript in the following way:
Return 1 (or other error code) on error
Return 0 (success) at EOF if stack is empty
Return 1 (or other error code) otherwise
I could run gs in the background, and use a timeout to force termination if gs hangs with items left on the stack. Is there an easier solution?
Ghostscript won't hang if you send files as input (unless you write a program which enters an infinite loop or otherwise fails to reach a halting state). Having items on any of the stacks won't cause it to hang.
On the other hand, it won't give you an error if a PostScript program leaves operands on the operand stack (or dictionaries on the dictionary stack, clips on the clip stack or gstates on the graphics state stack). This is because that's not an error, and since PostScript interpreters normally run in a job server loop its not a problem either. Terminating the job returns control to the job server loop which does a save and restore round the total job, thereby clearing up anything left behind.
I'd suggest that if you really want to do this you need to adopt the same approach, you need to write a PostScript program which executes the PostScript program you want to 'test', then checks the operand stack (and other stacks if required) to see if anything is left. Note that you will want to execute the test program in a stopped context, as an error in the course of the program will clearly potentially leave stuff lying around.
Ghostscript returns 0 on a clean exit and a value less than 0 for errors, if I remember correctly. You would need to use signalerror in your test framework in order to raise an error if items are left at the end of a program.
[EDIT]
Anything supplied to Ghostscript on the command line by either -s or -d is defined in systemdict, so if we do -sInputFileName=/test.pdf then we will find in systemdict a key /InputFileName whose value is a string with the contents (/test.pdf). We can use that to pass the filename to our program.
The stopped operator takes an executable array as an argument, and returns either true or false depending on whether an error occurred while executing the array (3rd Edition PLRM, p 697).
So we need to run the program contained in the filename we've been given, and do it in a 'stopped' context. Something like this:
{InputFileName run} stopped
{
(Error occurred\n) print flush
%% Potentially check $error for more information.
}{
(program terminated normally\n) print flush
%% Here you could check the various stacks
} ifelse
The following, based 90% on KenS's answer, is 99% satisfactory:
Program checkIntegrity.ps:
{Script run} stopped
{
(\n===> Integrity test failed: ) print Script print ( has error\n\n) print
handleerror
(ignore this error which only serves to force a return value of 1) /syntaxerror signalerror
}{
% script passed, now check the stack
count dup 0 eq {
pop (\n===> Integrity test passed: ) print Script print ( terminated normally\n\n) print
} {
(\n===> Integrity test failed: ) print Script print ( left ) print
3 string cvs print ( item(s) on stack\n\n) print
Script /syntaxerror signalerror
} ifelse
} ifelse
quit
Execute with
gs -q -sScript=CodeToBeChecked.ps checkIntegrity.ps ; echo $?
For the last 1% of satisfaction I would need a replacement for
(blabla) /syntaxerror signalerror
It forces exit with return code 1, but is very verbous and distracts from the actual error in the checked script that is reported by handleerror. Therefore a cleaner way to exit(1) would be welcome.

Valgrind not returning program's return value using lackey

So say I have a very simple C program like this:
int main(){
return 1;
}
I compile it into a.out. If I run
valgrind ./a.out
I can get a return value of 1. But if I run
valgrind --tool=lackey ./a.out
I get a return value of 0. So my question is, how can I get the return value of the program while using valgrind with lackey?
lackey outputs a (confusing/useless) 'valgrind exit code' which is
as far as I can see in the valgrind source always equal to 0.
Of all the valgrind tools, only lackey is using this useless code.
However, the 'real' exit status (i.e. seen by the shell) is by
default the exit status of your program:
$ valgrind --tool=lackey a.out
...
==7033== Exit code: 0
$ echo $?
1
For tools that are reporting errors (e.g. memcheck), you can change
the exit code of the program if the tool detected an error, using the
option:
--error-exitcode=<number> exit code to return if errors found [0=disable]

Linux ioctl return value interpreted by who?

I'm working with a custom kernel char device which sometimes returns large negative values (around the thousands, say -2000) for its ioctl().
In userspace, I don't get these values returned from the ioctl call. Instead I get a return value of -1 back with errno set to the negated value from the kernel module (+2000).
As far as I can read and google, __syscall_return() is the macro which is supposed to interpret negative return values as errors. But, it only seems to look for values between -1 and -125. So I didn't expect these large negative values to be translated.
Where are these return values translated? Is it expected behaviour?
I am on Linux 2.6.35.10 with EGLIBC 2.11.3-4+deb6u6.
The translation and move to errno occur on the libc level. Both Gnu libc and μClibc treat negative numbers down to at least -4095 as error conditions, per http://www.makelinux.net/ldd3/chp-6-sect-1
See https://github.molgen.mpg.de/git-mirror/glibc/blob/85b290451e4d3ab460a57f1c5966c5827ca807ca/sysdeps/unix/sysv/linux/aarch64/ioctl.S for the Gnu libc implementation of ioctl.
So, with the help of BRPocock I will report my findings here.
The linux kernel will do a error check for all syscalls along the lines of (from unistd.h):
#define __syscall_return(type, res) \
do { \
if ((unsigned long)(res) >= (unsigned long)(-125)) { \
errno = -(res); \
res = -1; \
} \
return (type) (res); \
} while (0)
Libc will also do an error check for all syscalls along the lines of (from syscall.S):
.text
ENTRY (syscall)
PUSHARGS_6 /* Save register contents. */
_DOARGS_6(44) /* Load arguments. */
movl 20(%esp), %eax /* Load syscall number into %eax. */
ENTER_KERNEL /* Do the system call. */
POPARGS_6 /* Restore register contents. */
cmpl $-4095, %eax /* Check %eax for error. */
jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
ret /* Return to caller. */
PSEUDO_END (syscall)
Glibc gives a reason for the 4096 value (from sysdep.h):
/* Linux uses a negative return value to indicate syscall errors,
unlike most Unices, which use the condition codes' carry flag.
Since version 2.1 the return value of a system call might be
negative even if the call succeeded. E.g., the `lseek' system call
might return a large offset. Therefore we must not anymore test
for < 0, but test for a real error by making sure the value in %eax
is a real error number. Linus said he will make sure the no syscall
returns a value in -1 .. -4095 as a valid result so we can savely
test with -4095. */
__syscall_return seems to be missing from newer kernels, I haven't researched that yet.

strcpy causing EXC_BAD_ACCESS?

I am making a command-line tool using Xcode 4.
I get the EXC_BAD_ACCESS error on the line with strcpy:
char *invalidOption = NULL;
strcpy(invalidOption, argv[2]);
argv[1] is -v (a "valid" option) and argv[2] is -z (an "invalid" option).
I then need to change "invalidOption" for display reasons (printing the "error" message).
Any ideas as to why this is happening?
Please let me know if you need any more details.
strcpy doesn't allocate any memory for you. You're trying to copy your string to NULL, which causes undefined behaviour. You need something like:
char invalidOption[10];
strcpy(invalidOption, argv[2]);
Just make sure that invalidOption is big enough to hold the whole string (including null terminator) or you'll end up with the same problem. You can use dynamic allocation if necessary.