LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   trying to write code for UNIX command "which" (https://www.linuxquestions.org/questions/programming-9/trying-to-write-code-for-unix-command-which-301104/)

live_dont_exist 03-13-2005 10:21 AM

trying to write code for UNIX command "which"
 
Hi Guys,

Theres little trouble I've run into while writing a C program . I was writing a C program for the Unix command "which" . I got to th epoint where I parsed my $PATH and got /usr/local/sbin stored into a variable called path1 (char *path1)
.Now I want to execute a system command from this path . I copied a file xclock into this directory and I now want to do system("path1/xclock") but obviously this is incorrect . Can anyone tell me how to represent the variable path1 inside system . I'll be more than happy to provide the entire source if anyone needs it .Do try an dhelp me out.
Thanks
Arvind

jonaskoelker 03-13-2005 10:30 AM

Code:

int run(const char* path, const char* prog)
{
  int exitcode;
  char* const temp = malloc (strlen(path) + strlen(path) + 1)
  strcpy (temp, path);
  strcat (temp, prog);
  exitcode = system (temp);
  free (temp);
  return exitcode
}

see also http://www.cplusplus.com/ref/cstring/strcat.html

live_dont_exist 03-13-2005 10:40 AM

hi ,
Thanks a million buddy...completely 4got abt strcat..thnx 4 the refresher course . I'm gonna try that out right away.Thanks a million again.
Arvind

TheLinuxDuck 03-14-2005 09:10 AM

Just an FYI: Don't use strcpy and strcat (nor sprintf), use strncpy strncat and snprintf. These force you to make sure that you're not letting too much data be copied, cat'd or printed into a variable. This is also known as a buffer overrun.

jonaskoelker 03-14-2005 09:15 AM

TheLinuxDuck: your point about watching out for buffer overruns is perfectly valid. You suggest using the n-functions, which are fine. However, I believe that malloc'ing enough space would be just as fine. Correct?

zeropash 03-14-2005 09:33 AM

use n functions where the data is coming from a untrusted source.
you can still use strcpy etc when you are the producer of the data
(provided you do the checks properly when you produce it)

Hivemind 03-14-2005 09:36 AM

Just a small bug I noticed:
Code:

char* const temp = malloc (strlen(path) + strlen(path) + 1);
should be
Code:

char* const temp = malloc (strlen(path) + strlen(prog) + 1);
:)

jonaskoelker 03-14-2005 09:42 AM

yeah. Well, I was tired at the time of writing, so buggy code is OK. :D

Hko 03-14-2005 11:16 AM

Quote:

Originally posted by jonaskoelker
You suggest using the n-functions, which are fine. However, I believe that malloc'ing enough space would be just as fine. Correct?
No, not: "just as fine". Malloc'ing enough rather "improves chances to get away with not using the n-functions".

Also, how must is "enough"?

As zeropash said: For a trivial programs (like this one?) where there's no strings involved coming from user input, files, database or a network-socket, it may be just as fine to malloc enough memory because you, the programmer, knows exactly how much data you will be copying, hence you know how much will be enough.

In all other cases, all memory in the machine wouldn't even be really enough.

jonaskoelker 03-14-2005 11:30 AM

forgive me for being thick, but is there any way that I would have malloc'ed too little space or in otherwise endanger the stability of the program?

I think we kinda' agree on this: when you know how much enough is, it's safe to malloc that much. If you don't, work around it--use the n-functions, perhaps repeatedly.

this reminds me of why I love C++:
{
string str;
cin >> str; // no worries :)
dostuff (str);
}

Hko 03-15-2005 12:01 PM

Quote:

Originally posted by jonaskoelker
is there any way that I would have malloc'ed too little space or in otherwise endanger the stability of the program?
Let's say you allocate 500 GigaBytes for a string which is read from stdin. And you expect the user of to feed your program something like his/her name to your program's stdin. Then say the user does some "experiment":
Code:

yes 'Z' | yourpogram
..then it will take a while to fill you 500 Gb string (putting some load on the CPU and using a lot of memory). And after that while you program will crash.

OK. When using 500 Gb, chances are not too big this will ever happen as your users me be not have bad intent and are not that stupid. Also it will take a while to pump 500 Gb into your program, and the user is likely to give up after 10 Gb, or the system administrator notices what is happening and kills the program.

But then think again, you don't want to allocate 500 Gb for just a name. You shouldn't even want to allocate 10k for it. Right.

Still this not the worst case yet. If your program reads strings from a file, line-by-line. And you expect the longest line to be something like 100 chars. So you allocate 10000 bytes to be on the safe side, for the string that will contain one line from the file. If you want to keep quite a few lines in memory you'll already be spilling memory. And chances of an accident with lines > 10000 chars are quite real (like accidentally feeding it some binary file, or messed up with perl/sed/awk).

Worse yet, imagine the data is read from the internet (TCP-socket on a server program). Then anybody on the internet is able to crash your program, or engineer some special data to overflow your string buffer gaining shell access to you computer. When the server also runs as root, those people able of gaining shell-acces will have root-access...

Quote:

I think we kinda' agree on this: when you know how much enough is, it's safe to malloc that much.
Yes, we do agree on that.
But this would mean the program only uses strings (and other buffers) that are fixed in the code. Only then you know for sure how much is enough. This is hardly ever the case in a real world program.

Quote:

this reminds me of why I love C++:
{
string str;
cin >> str; // no worries :)
dostuff (str);
}
Sure. But you could probably still fill the computer memory until the point the kernel kill the program. But much less worries, true.

BTW GNU libc also provides getline() which can do something similar in plain C. or you could make your own.

jonaskoelker 03-15-2005 12:16 PM

Quote:

Yes, we agree on that. But it is never the case in a real world program.
.. once you have read the data into memory, it is :p (of course, when reading it into memory, you don't). And yes, I fear buffer overruns more than the devil himself. Okay, maybe not excactly, but at least I fear them more than I fear Orwell's 1984 turning into reality. Or... come to think of it, most people fear a good buffer overrun more than I do, but that's besides the point ;)

Quote:

But you could probably still fill the computer memory until the point the kernel kill the program.
sure.

Quote:

BTW GNU libc also provides getline() which can do something similar in plain C.
oh? Didn't know that. I gotta check it out.
btw, it also provides a special scanf conversion: %a (for `allocate').
problem is: they aren't --ansi.

/me is --pedantic

Jonas Kölker


All times are GMT -5. The time now is 02:10 AM.