« first day (4032 days earlier)      last day (1117 days later) » 

4:58 AM
@fra-san Sure. The question is what the failure conditions are.
@fra-san Yes, something like that. The actual message looks like:
> Command 'lsx' not found, did you mean:
command 'sx' from deb lrzsz
command 'lvx' from deb alliance
command 'lsh' from deb lsh-client
command 'lyx' from deb lyx
command 'lsm' from deb lsm
command 'lsc' from deb livescript
command 'lex' from deb flex
command 'lex' from deb flex-old
command 'osx' from deb opensp
command 'ls' from deb coreutils
command 'lsw' from deb suckless-tools
Try: apt install <deb name>
Perhaps the message is shell-specific? I guess in the case of the C program, it's not going through the shell?
 
2 hours later…
7:28 AM
@FaheemMitha I just gave you the quote from the man page a while back: "The exec() functions return only if an error has occurred. The return value is -1, and errno is set to indicate the error."
@FaheemMitha the failure conditions are whatever prevents it from successfully executing the given program. Like that program not existing. There's also a list of the error codes in the man page...
7:52 AM
> The behavior of execlp() and execvp() when errors occur while
attempting to execute the file is historic practice, but has not
traditionally been documented and is not specified by the POSIX
standard. BSD (and possibly other systems) do an automatic sleep
and retry if ETXTBSY is encountered. Linux treats it as a hard
error and returns immediately.
From man exec. The standard doesn't seem to say anything about this case. So I guess it's sort-of Linux specific behavior.
@ilkkachu Yes, on man 2 execve. E.g.
> ETXTBSY
The specified executable was open for writing by one or more processes.
> On success, execve() does not return, on error -1 is returned, and errno is set appropriately.
Also from man 2 execve.
But errorno doesn't get returned to parent in this case via the wait mechanism, it seems.
It gets lost.
8:06 AM
@FaheemMitha no... because the process calling exec*() doesn't exit. The function just returns with an error. Just as normal. int ret = execlp(...); printf("execlp() returned %d, errno is %d (%s)\n", ret, errno, strerror(errno)); exit(1);
8:28 AM
@MichaelHomer ok, though I can't see them mentioning null pointers there. That seems to be about function pointers in general, and I can't see how that would automatically relate. It's far easier to require that one single value ((void *) 0) could be converted to another (whatever null pointer value for the function pointer would be), than to require that any and all values could be losslessly converted in both directions.
Anyway, the type of a plain constant 0 is int, and its internal representation is already different from that of any pointer, even in POSIX systems, so some conversion is needed anyway. (And we can't just use plain 0 as the terminator in execl() either, since the compiler doesn't know what to convert to.)
@MichaelHomer again, (void *) 0 is explicitly listed as a possible null pointer constant, so I can't see why that would be an extension? The standard draft I linked does mention conversions between void * and function pointers as an extension, though, but I'm still not talking about function pointers or void *s in general, just nulls.
I tried to look at SE for language lawyering about that, but all I found just now was this one which hilariously discusses if ((void *) 0) (with the extra parens) is a null pointer constant in the same way (void *) 0, without anyone ever questioning the latter is. stackoverflow.com/questions/26477209/… Anyway, I'm not sure I have much more on this without looking for more input from actual language lawyers.
8:56 AM
@ilkkachu It's related because function pointers are not compatible with object pointers in either direction; the value of the pointer is not relevant, the cast is an error. 0 is a null pointer constant when it's of any pointer type, unrelated to the integer zero. (void *)0 is certainly a null pointer value that's interconvertible with all object pointers and not (in baseline C) with function pointers. I don't know what else to tell you.
@FaheemMitha command-not-found lsx
9:46 AM
@ilkkachu Yes, agreed. I'm not saying it's unexpected, but it's a bit annoying. Also, the behavior differs if the file is not found, as opposed to whether the file is executed with an error. In the former case it returns. In the latter it does not, and gives an exit code of 127. But for Bash it gives 127 for both.
So, more concretely:
execlp("lsx", "lsx", "-la", "zarko.tex", (char *)NULL);
In this case, execlp returns with error. No error code or anything else it passed from the failed attempt to run lsx. The exit code is returned from the end of main, usually 0, or from _exit, if that is called.
execlp("sh", "sh", "-c", "./nopath", (char *)NULL);
In this case execlp does not return. However, the exit code 127 from the failed attempt is passed on to the parent via waitpid.
These two cases are different, but not that different. They both error out and don't actually produce any results.
In the former case, the question then becomes how to obtain the error code.
@MichaelHomer Yes, I realise it's running a Debian-specific command.
@ilkkachu Where does one obtain errno from?
In this first case, it seems to me to be lost to the void. (No pun intended.)
It seems one way to handle this would be to put a shell in the middle, as an intermediary to pick up the pieces.
In the first place, that is. In the second case, it's already there.
 
2 hours later…
11:35 AM
@FaheemMitha Looking at man 3p errno, if you include errno.h errno will be available after each call to any function that sets it. Simply as in ilkkachu's example.
@fra-san Oh. I don't have that included, unless it's included in one of the other headers, which is obviously possible. But man 3p errno is a Perl man page.
Let me see what Stevens says about it, if anything.
Actually a better example than the sh -c one above is:
execlp("ls", "ls", "-lah", "/nopath", (char *)0);
This execlp call also does not return. And gives an exit code of 2, which is the same as shell.
Since it seems that most, if not all people here are familiar with this stuff, I'm tempted to take a poll, along the lines of: how do you know about this?
@FaheemMitha Sorry, right, manpage sections aren't uniformly defined across systems (on Arch, 3p is POSIX and 3perl is Perl). But, in my message, man 3p errno was a link to the man7.org online page.
@fra-san OK. Yes, Stevens has it in Ch 1.
Still not clear if everything in Stevens is Unix-specific or not. Some of it seems quite general. And how much of that is Posix.
And man errno works. As does man 3 errno.
@FaheemMitha Yes, I was pointing to the POSIX page because it's shorter. (And adding the section because man -f errno shows four distinct hits on my system).
11:55 AM
@fra-san Two hits here. Clearly you have more man pages installed.
Errno (3perl)        - System errno constants
errno (3)            - number of last error
I see there is a manpages-posix which I don't have installed.
@FaheemMitha Especially, I have errno(1) from the moreutils package, which would be shown by default when running man errno.
Also manpages-posix-dev.
@fra-san Another package I don't have installed.
It's relatively uncommon for me to not find something installed on my system. It was originally installed in 2013, and stuff accumulates.
Ok, up to 4 now. Yay.
Errno (3perl)        - System errno constants
errno (3)            - number of last error
errno (1)            - look up errno names and descriptions
errno (3posix)       - error return value
 
7 hours later…
7:09 PM
@ilkkachu Thanks for the tip. I got the error message.
7:41 PM
@FaheemMitha Again, the 127 is produced by the shell as part of its command execution; if you want it as well, you need to generate it in your subprocess. It's not related to waitpid or really even exec. You've chosen to return zero
It's not a natural thing, it's a specific behaviour that the shell is defined to produce
@MichaelHomer Yes, thank you. I understand. I probably don't need it. As long as some error is returned.
Then you haven't had a problem for days
I guess that error took that form because I was calling sh.
@MichaelHomer Just trying to figure things out.
You and Tim should start a club
@MichaelHomer That's an uncalled for remark.
7:46 PM
I like Tim! A couple of questions on the site would have been a lot more efficient, though
Someone needs to explain to the POSIX people how inadequate popen really is.
8:02 PM
@MichaelHomer ouch
 
2 hours later…
9:36 PM
popen is a convenience function for when you don't want to do the whole fork-exec thing.
And are doing something relatively simple.

« first day (4032 days earlier)      last day (1117 days later) »