0

i'm trying to get the filesize of the cmdline file in proc/[pid]. For example porc/1/cmdline. The file is not empty, it contains "/sbin/init". But i get file_size = 0.

int main(int argc, char **argv) {
    int file_size;
    FILE *file_cmd;
    file_cmd = fopen("/proc/1/cmdline", "r");
    if(file_cmd == NULL) {
        perror("proc/1/cmdline");
        exit(1);
    }else {
        if(fseek(file_cmd, 0L, SEEK_END)!=0) {
            perror("proc/1/cmdline");
            exit(1);
        }
        file_size = ftell(file_cmd);
    }
    printf("fs: %d\n",file_size);
    fclose(file_cmd);
    }

Regards

user1324258
  • 561
  • 2
  • 8
  • 25
  • Does this answer your question? [how can i show the size of files in /proc? it should not be size zero](https://stackoverflow.com/questions/12237712/how-can-i-show-the-size-of-files-in-proc-it-should-not-be-size-zero) – 273K May 16 '23 at 06:40

1 Answers1

2

That's normal. /proc files (most of them, there are a few exceptions) are generated by the kernel at the moment you read from them. That means it's impossible to know the size before reading from the file. Think of it as Quantum Mechanics on files. You won't get a state unless you read the information, but there's no guarantee that reading again will give you the same information twice ;-)

In other words, the EOF is only generated when you try to read it. It's not there before that, so there's no way a file size can be determined.

This is really just communication with the kernel disguised as file I/O.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
  • Ah okey. But why should this file be generated at the moment when i read from it. I thought it would be generated when the process starts, because then the cmdline arguments are stored there. Do you hae any suggestion how to read the file content? – user1324258 Nov 11 '12 at 17:34
  • Having the data stored in a real file would only waste memory. You can read from the file just fine, btw. You just can't seek of get a size from it (even with `stat()`.) Simply read until you get an EOF. – Nikos C. Nov 11 '12 at 17:38
  • @user1324258 Yeah, that's what I wrote. You can't get the size even with `stat()`. – Nikos C. Nov 11 '12 at 18:14
  • oh sorry read to much today ;) so there is no way to get file size of cmdline, but with read() ? – user1324258 Nov 11 '12 at 18:26
  • @user1324258 Yep. The only way to know where this pseudo-file ends is to read to the end and get an EOF. With this file, you can simply assume that it won't be too big, so can try reading something like 1kb out of it. This should get you the whole contents at once. – Nikos C. Nov 11 '12 at 18:28
  • I read something about the ARG_MAX constant. So this should be the max file size. Do you know which header file defines this constant? I read it is 4096 bytes. – user1324258 Nov 11 '12 at 18:39
  • @user1324258 ARG_MAX is the maximum length of command-line arguments for a process. I don't see a connection here. The kernel is not a process, so that limitation doesn't apply to it. – Nikos C. Nov 11 '12 at 18:55
  • the file proc/[pid]/cmdline containts cmdline arguments for a process, so the file should not be bigger then ARG_MAX?! – user1324258 Nov 11 '12 at 19:06
  • @user1324258 Oops, sorry. I though we were talking about `/proc/cmdline`. Yes, for process command lines, ARG_MAX makes sense. The portable POSIX way to this value, is by using `sysconf()` from ``. For example `sysconf(ARG_MAX)` will give you the value. See `man sysconf` for more details. You should still sanity check the value though, in case some strange platform has no limit on ARG_MAX; you wouldn't want to allocate 2^32 bytes buffer or similar :P – Nikos C. Nov 11 '12 at 19:12
  • @user1324258 _SC_ARG_MAX, not ARG_MAX. Sorry. – Nikos C. Nov 11 '12 at 19:17
  • `printf("scarg: %ld\n",sysconf(_SC_ARG_MAX))` shows 2097152. That is pretty many bytes, isnt it? And _POSIX_ARG_MAX is the minimum value, _SC_ARG_MAX could be?! – user1324258 Nov 11 '12 at 19:35
  • @user1324258 Yes, nowadays Linux supports 2MB big command lines. _POSIX_ARG_MAX is the minimum; ARG_MAX can be larger, but not smaller than that. – Nikos C. Nov 11 '12 at 19:38