From: Phred Phungus on
I'm curious about the following description:

#include <unistd.h>

long
pathconf(const char *path, int name);



DESCRIPTION

The pathconf(), lpathconf() and fpathconf() system calls provide a
method
for applications to determine the current value of a configurable
system
limit or option variable associated with a pathname or file
descriptor.

For pathconf() and lpathconf(), the path argument is the name of a
file
or directory. For fpathconf(), the fd argument is an open file
descrip-
tor. The name argument specifies the system variable to be queried.
Symbolic constants for each name value are found in the include file
<unistd.h>.

The lpathconf() system call is like pathconf() except in the case
where
the named file is a symbolic link, in which case lpathconf() returns
information about the link, while pathconf() returns information about
the file the link references.

The available values are as follows:

...

_PC_NAME_MAX
The maximum number of bytes in a file name.

_PC_PATH_MAX
The maximum number of bytes in a pathname.

Why are these ultimate two values integers?

Thanks for your comment and cheers,
--
fred
From: David Schwartz on
On Feb 22, 9:40 pm, Phred Phungus <Ph...(a)example.invalid> wrote:

>       _PC_NAME_MAX
>               The maximum number of bytes in a file name.
>
>       _PC_PATH_MAX
>               The maximum number of bytes in a pathname.
>
> Why are these ultimate two values integers?

You mean over something like pathconf(foo, "PC_NAME_MAX")? Efficiency.
Passing pointers and strings between kernel and user space is much
more expensive than passing an integer. So when an integer will do,
that's what is done.

To pass an integer, you simply put the integer in a register or push
it onto the stack. The kernel then checks to make sure that integer
isn't too small or too big and then dispatches through a table. (If
the integer is 1, it uses the first entry. If 2, the second.)

To pass a string, you push a pointer onto the stack, the kernel then
checks if the pointer points to legal memory space inside the process,
then the kernel has to find the end of the string while being careful
not to stray past the legal bounds of the process' memory. Then the
kernel has to somehow find the entry matching that string using a hash
table or lots of expensive string compares.

So the integer is a win all around.

DS
From: Phred Phungus on
David Schwartz wrote:
> On Feb 22, 9:40 pm, Phred Phungus <Ph...(a)example.invalid> wrote:
>
>> _PC_NAME_MAX
>> The maximum number of bytes in a file name.
>>
>> _PC_PATH_MAX
>> The maximum number of bytes in a pathname.
>>
>> Why are these ultimate two values integers?
>
> You mean over something like pathconf(foo, "PC_NAME_MAX")? Efficiency.
> Passing pointers and strings between kernel and user space is much
> more expensive than passing an integer. So when an integer will do,
> that's what is done.
>
> To pass an integer, you simply put the integer in a register or push
> it onto the stack. The kernel then checks to make sure that integer
> isn't too small or too big and then dispatches through a table. (If
> the integer is 1, it uses the first entry. If 2, the second.)
>
> To pass a string, you push a pointer onto the stack, the kernel then
> checks if the pointer points to legal memory space inside the process,
> then the kernel has to find the end of the string while being careful
> not to stray past the legal bounds of the process' memory. Then the
> kernel has to somehow find the entry matching that string using a hash
> table or lots of expensive string compares.
>
> So the integer is a win all around.
>
> DS

An interesting read, DS, I'm always interested in low-level analysis,
but I think my query is at the level of the unix specification. If
you'd read me before, you would know how new I am to *nix.

Another way to ask my question might be this. When I run this command:

gcc e4.c -E -x c - >text1.txt

, and search for _PC_PATH_MAX

, I was expecting to see

#define _PC_PATH_MAX 42

, but the search turned up nothing. Why?
--
fred
From: Nicolas George on
Phred Phungus wrote in message <7uh9suFq2tU1(a)mid.individual.net>:
> Another way to ask my question might be this. When I run this command:
>
> gcc e4.c -E -x c - >text1.txt
>
> , and search for _PC_PATH_MAX
>
> , I was expecting to see
>
> #define _PC_PATH_MAX 42
>
> , but the search turned up nothing. Why?

There are two good reasons for that.

First, you ask for -E, which is the output of the preprocessor, where all
preprocessing directives have been interpreted. You will not find _any_
#define directive in the output of gcc -E. Instead, you could expect to
read this:

path_max = pathconf(theDir,42);

where _PC_PATH_MAX has been replaced by its value. If you want the macro
definitions, you have to add -dM to -E.

The other reason is that, at least on GNU systems, the symbolics constants
for pathconf are defined as an enumerated type, somewhere in
bits/confname.h. And on top of that, the header defines macro that expand to
themselves, to allow #ifdef tests.

Enumerated types behave exactly like the integers they represent, but they
add information to debugging tools. For example the compiler can emit a
warning about missing switch cases, and a good debugger can print the
constant name instead of the integer value.
From: Ersek, Laszlo on
In article <4b8394bf$0$22732$426a74cc(a)news.free.fr>, Nicolas George <nicolas$george(a)salle-s.org> writes:

> Enumerated types behave exactly like the integers they represent, but they
> add information to debugging tools. For example the compiler can emit a
> warning about missing switch cases, and a good debugger can print the
> constant name instead of the integer value.

gcc -g3 allows gdb to print macro names, too.

----v----
Level 3 includes extra information, such as all the macro definitions
present in the program. Some debuggers support macro expansion when you
use -g3.
----^----

Cheers,
lacos