bcf2303@dcrbg1.UUCP (Wing Chow) (01/16/88)
can someone give me an example of how to use 'system' in a c program?
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/18/88)
In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes: >can someone give me an example of how to use 'system' in a c program? ... fflush( stdout ); if ( system( "date" ) != 0 ) /* print a time stamp on stdout */ error( "cannot execute \"date\" command" ); ...
lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (01/19/88)
In article <7118@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes: >>can someone give me an example of how to use 'system' in a c program? > > ... > fflush( stdout ); > if ( system( "date" ) != 0 ) /* print a time stamp on stdout */ > error( "cannot execute \"date\" command" ); > ... System is probably one of the most abused functions in the C library. This is an example of poor use, sorry Mr. Gwyn. There are security problems with system() on UNIX. If the program user sets their PATH so that it searches other than "non-standard" directories before searching "standard" there is the potentional for running the wrong program. This is deadly if the program using system() is setuid/setgid. What to do about it? When the program starts up, reset the PATH and IFS environment variables to something sensible, use full path names (unfortunately you will lose portability here) to the programs you are executing. Pathnames can be isolated in a header file so this isn't a big issue. -- Larry Cipriani, AT&T Networks Systems (by day) Ohio State University (by night) Domain: lvc@tut.cis.ohio-state.edu Path: ...!cbosgd!osu-cis!tut.cis.ohio-state.edu!lvc (yes its right)
pmd@cbdkc1.ATT.COM (Paul Dubuc) (01/20/88)
In article <4790@tut.cis.ohio-state.edu> (Lawrence V. Cipriani) writes: }>>can someone give me an example of how to use 'system' in a c program? }> }> ... }> fflush( stdout ); }> if ( system( "date" ) != 0 ) /* print a time stamp on stdout */ }> error( "cannot execute \"date\" command" ); }> ... } }System is probably one of the most abused functions in the C }library. This is an example of poor use, sorry Mr. Gwyn. There }are security problems with system() on UNIX. If the program user }sets their PATH so that it searches other than "non-standard" }directories before searching "standard" there is the potential }for running the wrong program. This is deadly if the program using }system() is setuid/setgid. } }What to do about it? When the program starts up, reset the PATH }and IFS environment variables to something sensible, use full }path names (unfortunately you will lose portability here) to the }programs you are executing. Pathnames can be isolated in a }header file so this isn't a big issue. Larry's cautions about the use of system() are well put, but these "abuses" are not inherent in that function. The same problems exist with the alternative of using the exec() family of system calls (speaking UNIX Sys V, here). Full path names must be specified with most of them (there's the loss of portability) except the "execvp()" and "execlp()" forms which use PATH, and are subject to the same security problems as system(). Unfortunately, you have to use these latter forms if what you want to exec might be a shell procedure (you get ENOEXEC) with the others in this case). The abuse that is inherent in system() is the fact that system() spawns another copy of the shell and runs your command under that shell. Needless to say this can be a tremendous waste in overhead if you don't need the facilities of the subshell to run the command (as in the above example). System() is also tempting to use because you don't have to go through the fork()/exec()/wait() sequence and handle all the possible outcomes correctly. (System() gives you less control of your child process, so there is less you have to look after, but the same results may be achieved more efficiently by isolating the fork()/exec()/wait() procedure in a subroutine.) -- Paul Dubuc {ihnp4,cbosgd}!cbdkc1!pmd
gp@picuxa.UUCP (Greg Pasquariello X1190) (01/20/88)
In article <127@dcrbg1.UUCP>, bcf2303@dcrbg1.UUCP (Wing Chow) writes: > > can someone give me an example of how to use 'system' in a c program? 'System()' is a way to call an external process from within your C code. The way you use it, is to pass it the process name e.g. system("ls -l"), or system("sh -c") or if your forced to be running DOS (:-)) system("command"); This will have the effect of stopping your program, executing the command, and returning control to your program. On a UNIX system this is (almost) equi- vilent to a: if(!fork()) execlp("/bin/sh","sh","-c",command,0); wait() Hope this helps. Greg Pasquariello
miket@ccicpg.UUCP (Mike Tracy) (01/20/88)
In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes: > >can someone give me an example of how to use 'system' in a c program? The best example I have is the mkdir command. Since a normal user can not create a directory. The mkdir (under Unix) is a SUID root program. That is, when the program is envoked its effective user id is that of the super user (stupid user :-)) root. To make a directory from you C program (unless your program is SUID root) you must use the system call (with the appropriate checks for success). system( "mkdir mydir" ); Michael D. Tracy Computer Consoles Incorporated (714)458-7282 9801 Muirlands Boulevard Irvine, CA 92718 {allegra!hplabs!felix,seismo!rlgvax}!ccicpg!miket
ok@quintus.UUCP (Richard A. O'Keefe) (01/20/88)
In article <4790@tut.cis.ohio-state.edu>, lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) writes: > In article <7118@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: > > fflush( stdout ); > > if ( system( "date" ) != 0 ) /* print a time stamp on stdout */ > > error( "cannot execute \"date\" command" ); > > ... > > > System is probably one of the most abused functions in the C > library. This is an example of poor use, sorry Mr. Gwyn. There > are security problems with system() on UNIX. If the program user > sets their PATH so that it searches other than "non-standard" > directories before searching "standard" there is the potentional > for running the wrong program. This is deadly if the program using > system() is setuid/setgid. > > What to do about it? When the program starts up, reset the PATH > and IFS environment variables to something sensible, use full > path names (unfortunately you will lose portability here) to the > programs you are executing. Pathnames can be isolated in a > header file so this isn't a big issue. > There is a better way. Instead of calling system("date") you call system("PATH=/bin:/usr/bin date") in System V, or system("PATH=/usr/ucb:/bin:/usr/bin date") in 4.xBSD. To keep system-dependency to one place, do cat >safesys.c <<'EOF' #include <assert.h> #ifdef SUN #define CMDSIZ 10240 #define STDENV "IFS= PATH=/usr/ucb:/bin:/usr/bin:/usr/5bin " #else #ifdef BSD #define CMDSIZ 10240 #define STDENV "IFS= PATH=/usr/ucb:/bin:/usr/bin " #else /* assume USG */ #define CMDSIZ 10240 /* check your manual! */ #define STDENV "IFS= PATH=/bin:/usr/bin " #endif #endif int safe_system(command) char *command; { char buffer[CMDSIZ]; static char stdenv[] = STDENV; assert(sizeof stdenv + strlen(command) <= sizeof buffer); sprintf(buffer, "%s%.*s", stdenv, sizeof buffer - sizeof stdenv, command); return system(buffer); } EOF A still better approach is to have safe_system() do a fork(), and have the child process reset its environment, do seteuid(getuid()) setegid(getgid()) and finally call system(). That takes more code than I care to include here. There isn't any special security problem with system(). The security problem is with setuid/setgid programs. If your program offers the user the opportunity to enter a UNIX command, the user will be *extremely* unhappy to find that he can't run any of his programs because you have smashed the $PATH variable! If your program wants to run a utility for its OWN benefit, where it cares that a specific program documented in the UNIX commands manual should be run, use safe_system(). If your program wants to run another program on behalf of the user, it should use system() and should NOT alter the $PATH variable.
kers@otter.HP.COM (Christopher Dollin) (01/21/88)
[someone has said that "mkdir" must be system-ed]. Duh ... well, in HP-UX, -mkdir- is a system call. But the manual says that some implementations "may run mkdir" from a library routine. If -mkdir- (in a program) isn't a system call, how does -mkdir- (the program) work? How come it wasn't a system call anyway? Regards, | "Those who understand Unix are compelled to prefect it". Kers | (to prefect - to perfect, as in Ford Prefects use of "safe".
pmd@cbdkc1.ATT.COM (Paul Dubuc) (01/21/88)
In article <9472@ccicpg.UUCP> miket@ccicpg.UUCP (Mike Tracy) writes: }In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes: }> }>can someone give me an example of how to use 'system' in a c program? } }The best example I have is the mkdir command. Since a normal }user can not create a directory. The mkdir (under Unix) is a SUID root }program. That is, when the program is envoked its effective user id is }that of the super user (stupid user :-)) root. } }To make a directory from you C program (unless your program is }SUID root) you must use the system call (with the appropriate checks }for success). } } system( "mkdir mydir" ); No, you don't have to you system() for this. You can use fork()/exec(). See my previous article on this subject. For the reasons I gave in that article, system() is best reserved for running command strings that need the facilities of the shell (pipelines, redirection, metacharacter translation, etc.). However, running mkdir from a C program either way brings up an interesting example of another problem. Suppose I (pmd) have a program that runs set-uid to user 'joe'. This program exec's mkdir to create a directory. If it then tries to change the mode, owner or group on the directory it just created, it can't. Why? Because mkdir runs set-uid to root, creates the directory and then sets the owner to the real user ID of the process (pmd in my case). My program is running as 'joe' and can't change the mode, owner or group on any directory it creates because it is not the owner (and not 'root' either). This is a problem because it's good practice for programs that create directories to be selective about the permissions of those directories and the lack of a solution means your program may be "broken" by merely setting the set-uid bit*. It's also a needless security risk to make the program set-uid to root just to avoid this problem. I know how much readers of this group like puzzles, so I won't detail the solution (it's fairly simple, anyway). For my solution, I implemented a mkdir() subroutine that runs the mkdir command (with fork() and exec(), not system()) and takes mode, owner and group specifications as arguments, so the whole proceedure is isolated to one routine. This allows a safe, easy way to create directories independent of the real or effective user ID of the calling process. -- * The set-uid bit is patented by Dennis Ritchie. -- Paul Dubuc {ihnp4,cbosgd}!cbdkc1!pmd
swarbric@tramp.Colorado.EDU (SWARBRICK FRANCIS JOHN) (01/21/88)
In article <452@picuxa.UUCP> gp@picuxa.UUCP (Greg Pasquariello X1190) writes: > if(!fork()) > execlp("/bin/sh","sh","-c",command,0); > wait() Just curious, but what do fork() and wait() do? I have Turbo C, and it has execlp(), but neither of the other two. Does it have something to do with the fact that UNIX is multiuser, while MS-DOS is not? ------------------------------------------------------------------ Frank Swarbrick | "Ignorance and prejudice -- swarbric@tramp.UUCP | And fear walk and in hand." swarbric@tramp.Colorado.EDU | --RUSH ...!{hao|nbires}!boulder!tramp!swarbric
usenet@lll-winken.llnl.gov (Usenet News Administrator) (01/21/88)
>> fflush( stdout ); >> if ( system( "date" ) != 0 ) /* print a time stamp on stdout */ >> error( "cannot execute \"date\" command" ); >> ... > >System is probably one of the most abused functions in the C >library. > From: washer@lll-crg.llnl.gov (Jim Washer) Path: lll-crg.llnl.gov!washer system is nice for things like system("mkdir xyz" ) since non-superusers cannot make a directory from a program thru standard system call. ( At least I think thats true ) jim washer lll-crg!isaac!washer
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/22/88)
In article <3920@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU (SWARBRICK FRANCIS JOHN) writes: >Just curious, but what do fork() and wait() do? I have Turbo C, and it has >execlp(), but neither of the other two. Does it have something to do with >the fact that UNIX is multiuser, while MS-DOS is not? Yes, exactly. fork() creates a duplicate process image that shares the same open files; it returns 0 in the "child" process and the child's ID number in the "parent" process, both of which are then concurrently executing. exec() simply overlays a process image from a file on top of the currently executing one, then starts execution at its new entry point; the process ID remains unchanged. The combination of the two effectively "spawns" a new subprocess.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/22/88)
In article <7152@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >>...the fact that UNIX is multiuser... >Yes, exactly. Before someone picks on this, it's not EXACTLY correct -- it's the multitasking nature of UNIX that's involved with fork and exec. Of course, the multiuser environment relies on this..
pmd@cbdkc1.ATT.COM (Paul Dubuc) (01/22/88)
In article <3920@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU (SWARBRICK FRANCIS JOHN) writes: }In article <452@picuxa.UUCP> gp@picuxa.UUCP (Greg Pasquariello X1190) writes: }> if(!fork()) }> execlp("/bin/sh","sh","-c",command,0); }> wait() } }Just curious, but what do fork() and wait() do? I have Turbo C, and it has }execlp(), but neither of the other two. Does it have something to do with }the fact that UNIX is multiuser, while MS-DOS is not? Close. It has to do with UNIX being multiprocessing. On UNIX, fork() clones the process into two virtually identical processes. execlp() overlays the currently running process with the one specified by the arguments. Wait() waits for a "child" process to terminate. Although it's not very clear in this example, only the child process does the execlp(), the parent executes the wait() which returns when the child terminates. (Fork() returns 0 to the child; the process ID of the child (a positive integer) to the parent). The execlp() in Turbo C probably acts similarly to system() on UNIX. It stops the calling program, runs the subprogram, and resumes the calling program when that's done. In UNIX a parent process does not have to wait for the subprocess (child) to finish before continuing. -- Paul Dubuc {ihnp4,cbosgd}!cbdkc1!pmd
shannon@intelisc.UUCP (Shannon Nelson) (01/23/88)
In article <2771@cbdkc1.ATT.COM> pmd@cbdkc1.UUCP (Paul Dubuc) writes: >In article <9472@ccicpg.UUCP> miket@ccicpg.UUCP (Mike Tracy) writes: >} >}The best example I have [of system()] is the mkdir command. Since a normal >}user can not create a directory. The mkdir (under Unix) is a SUID root >}program... >} >}To make a directory from you C program [...] you must use the system call >} >} system( "mkdir mydir" ); > >No, you don't have to you system() for this. You can use fork()/exec(). I may be showing my ignorance, but what ever happened to the mkdir() call? In my manuals (Xenix, sysVr3, Pyramid OSx) neither the call nor the command say anything about set-uid to root. A quick ls -l of /bin/mkdir confirms this. As long as the effective user id has write permission in the target directory, both "mkdir(path, mod)" and "mkdir path" should be successful. Given this, and the overhead inherent in system(), why are you not using mkdir()? -- ============================================================================ Shannon Nelson ...!tektronix!ogcvax!intelisc!shannon (503) 629-7607 "Live, from iSC Evaluation ..." Intel disclaims all knowledge of my existence.
) Seaman) (01/23/88)
In article <2771@cbdkc1.ATT.COM>, pmd@cbdkc1.ATT.COM (Paul Dubuc) writes: < < In article <9472@ccicpg.UUCP> miket@ccicpg.UUCP (Mike Tracy) writes: < }In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes: < }> < }>can someone give me an example of how to use 'system' in a c program? < } < }The best example I have is the mkdir command... < } < } system( "mkdir mydir" ); < No, you don't have to you system() for this. You can use fork()/exec(). < < Paul Dubuc {ihnp4,cbosgd}!cbdkc1!pmd You are correct about using fork()/exec() to call mkdir, at least in System V. As for what system is good for, try this one: You have a program, which accepts input from a user (or a user created file), then wants to 'fork and exec' their input as a command. If their command is a binary executable, no problem. You can parse their input to determine command and arguments, initialize appropriate arrays, and call fork()/exec(). But, if their command is a shell script, exec() will fail. A script must be exec'ed as an argument to the appropriate shell (/bin/sh, /bin/csh, /bin/ksh, etc.). You can make a few tests in your program, to see what kind of file it is (assuming you can find it), and then appropriately call their program directly, or as an argument to the shell. However, it is sometimes easier (when you aren't sure), and involves less coding (if you are in a hurry), to use system(). Some benchmarks I have tried showed little performance improvement of a program that used fork()/exec(), versus one that used system(). Don't get me wrong. I *do* use fork()/exec()/wait() whenever possible, but sometimes... -- Chris Seaman | o\ /o crs@cpsc6a.att.com <or> | || See "Attack of the Killer Smiley"! ..!ihnp4!cpsc6a!crs | \vvvvvv/ Coming Soon to a newsgroup near you! | \____/
tim@amdcad.AMD.COM (Tim Olson) (01/23/88)
In article <2788@cbdkc1.ATT.COM> pmd@cbdkc1.UUCP (Paul Dubuc) writes: | Close. It has to do with UNIX being multiprocessing. On UNIX, fork() Minor nit here. 'multiprocessing' is usually the term reserved for hardware with multiple physical processors. I think you meant 'multitasking' or 'multiprogramming', which are interchangably used to refer to systems that run multiple processes (independant of the number of processors). -- Tim Olson Advanced Micro Devices (tim@amdcad.amd.com)
daveb@laidbak.UUCP (Dave Burton) (01/24/88)
In article <3920@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU writes: >Just curious, but what do fork() and wait() do? I have Turbo C, and it has >execlp(), but neither of the other two. Does it have something to do with >the fact that UNIX is multiuser, while MS-DOS is not? Close. Multitasking. Very basicly, fork() creates a new process and wait() waits for its completion. MSDOS does not have the capability of a fork(), so no wait() is needed. exec() overlays one process with another, which MSDOS can do. -- --------------------"Well, it looked good when I wrote it"--------------------- Verbal: Dave Burton Net: ...!ihnp4!laidbak!daveb V-MAIL: (312) 505-9100 x325 USSnail: 1901 N. Naper Blvd. #include <disclaimer.h> Naperville, IL 60540
ok@quintus.UUCP (Richard A. O'Keefe) (01/24/88)
In article <447@cpsc6b.cpsc6a.att.com>, crs@cpsc6b.cpsc6a.att.com (Chris (I'm Outta Here!) Seaman) writes that: > But, if their command is a shell > script, exec() will fail. A script must be exec'ed as an argument > to the appropriate shell (/bin/sh, /bin/csh, /bin/ksh, etc.). BSD UNIX doesn't have this restriction; that is a System V "feature". Which is, of course, the point of system(): the fork/exec approach isn't exactly the same in all versions of UNIX. system() fits nicely with popen() too. {Why isn't there a popen() which gives me *two* stdio streams, one to each end of the command?} This is more appropriate for comp.unix.questions.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/25/88)
In article <569@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >>But, if their command is a shell script, exec() will fail. >BSD UNIX doesn't have this restriction; that is a System V "feature". This Berkeley feature requires that the script start with an appropriate #! line; not all scripts do. The #! line contains system-specific (non-portable) instructions, in general. For example, someone just reported a problem when he used a copy of one of my #!/usr/5bin/sh scripts on a Sun workstation (which didn't have /usr/5bin/sh). >{Why isn't there a popen() which gives me *two* >stdio streams, one to each end of the command?} Because this isn't generally helpful; if you don't carefully design an IPC protocol, deadlock can easily result. If you keep your "packets" below the pipe buffer size, and use a strict alternation of (write, then read), then such a connection should work. But a naive programmer will just get in trouble with such a facility.
nather@ut-sally.UUCP (Ed Nather) (01/25/88)
In article <1317@laidbak.UUCP>, daveb@laidbak.UUCP (Dave Burton) writes: > In article <3920@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU writes: > > Very basicly, fork() creates a new process and wait() waits for > its completion. MSDOS does not have the capability of a fork(), > so no wait() is needed. exec() overlays one process with another, > which MSDOS can do. > -- MS-DOS can do the same thing (create a new process and wait for it to finish) -- it's called "spawn()". Look for it in your favorite manual. -- Ed Nather Astronomy Dept, U of Texas @ Austin {allegra,ihnp4}!{noao,ut-sally}!utastro!nather nather@astro.AS.UTEXAS.EDU
mlandau@bbn.com (Matt Landau) (01/25/88)
In comp.lang.c (<10202@ut-sally.UUCP>), nather@ut-sally.UUCP (Ed Nather) writes: >MS-DOS can do the same thing (create a new process and wait for it to >finish) -- it's called "spawn()". Look for it in your favorite manual. The fundamental difference between Unix fork() and creation of child processes in MS-DOS is twofold: (1) When a child is created by fork(), both child and parent continue to run, unless the parent explicitly calls wait() to wait for the child to terminate. MS-DOS is single-tasking, so creation of a child process normally involves suspending the parent (but there are ways you can get around this and fake multitasking). (2) More importantly, fork() creates a child process by *copying the parent's address space* -- the child is an exact copy of the parent until they take divergent execution paths. The child process is typically overlaid almost immediately by a call to exec(), but this is by no means required. MS-DOS has no way to copy a process's address space. -- Matt Landau Waiting for a flash of enlightenment mlandau@bbn.com in all this blood and thunder
henry@utzoo.uucp (Henry Spencer) (01/26/88)
> I may be showing my ignorance, but what ever happened to the mkdir() call?
Alas, you are showing your ignorance: only some versions of Unix have
mkdir() as a system call. Mind you, there is no excuse for not having
it as a library function if you don't have the system call, but many
older Unixes have neither.
--
Those who do not understand Unix are | Henry Spencer @ U of Toronto Zoology
condemned to reinvent it, poorly. | {allegra,ihnp4,decvax,utai}!utzoo!henry
maart@cs.vu.nl (Maarten Litmaath) (01/28/88)
In article <1017@uokmax.UUCP> rmtodd@uokmax.UUCP () writes:
\My understanding is that mkdir() was made into a system call in BSD (probably
\because they had just changed the directory format).
The 'old' mkdir program has a serious security bug (to become su).
--
Floating eye exception -- |Maarten Litmaath @ Free U Amsterdam:
Core dumped |maart@cs.vu.nl, mcvax!botter!ark!maart
dsill@NSWC-OAS.arpa (Dave Sill) (01/29/88)
In article <1670009@otter.HP.COM> Christopher Dollin <kers@otter.HP.COM> writes: >If -mkdir- (in a program) isn't a system call, how does -mkdir- (the program) >work? It uses mknod to make the directory, its dot ".", and its dot-dot "..". >How come it wasn't a system call anyway? Because mknod must be run by the super-user. It's purpose is creating special files.
?) Seaman) (01/30/88)
In article henry@utzoo.uucp (Henry Spencer) writes: < > I may be showing my ignorance, but what ever happened to the mkdir() call? < < Alas, you are showing your ignorance: only some versions of Unix have < mkdir() as a system call. Mind you, there is no excuse for not having < it as a library function if you don't have the system call, but many < older Unixes have neither. < -- < Henry Spencer @ U of Toronto Zoology Actually, there is not much reason for worrying about whether or not there is a library function for mkdir on most (all?) System V boxes, since the mkdir system call is reserved for the super user alone. In the standard System V world, you will find that even the 'mkdir' command is setuid to root. -- Chris Seaman | o\ /o crs@cpsc6a.att.com <or> | || See "Attack of the Killer Smiley"! ..!ihnp4!cpsc6a!crs | \vvvvvv/ Coming Soon to a newsgroup near you! | \____/
guy@gorodish.Sun.COM (Guy Harris) (01/30/88)
(This long ago ceased to be a C-related discussion; it is now a UNIX-related discussion. It is now being redirected to comp.unix.questions.) > Actually, there is not much reason for worrying about whether or not > there is a library function for mkdir on most (all?) System V boxes, > since the mkdir system call is reserved for the super user alone. WRONG. It is not a privileged system call in S5R3. > In the standard System V world, you will find that even the 'mkdir' command > is setuid to root. Not in S5R3.1, at least, and probably not in S5R3. On the 3B2/400s we have here, running S5R3.1, "/bin/mkdir" is not set-UID, and it works just fine. In S5 systems *prior* to S5R3, it is set-UID "root" because it has to use the privileged "mknod" system call. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
wong@llama.rtech.UUCP (J. Wong) (01/30/88)
In article <224@intelisc.UUCP> shannon@intelisc.UUCP (Shannon Nelson) writes: >In article <2771@cbdkc1.ATT.COM> pmd@cbdkc1.UUCP (Paul Dubuc) writes: >>In article <9472@ccicpg.UUCP> miket@ccicpg.UUCP (Mike Tracy) writes: >>} >I may be showing my ignorance, but what ever happened to the mkdir() >call? In my manuals (Xenix, sysVr3, Pyramid OSx) neither the call nor >the command say anything about set-uid to root. I believe that in System V and other non-BSD systems (especially version 7) only super-users could create links to directories. Since the . and .. entries were really just links to the directory and its parent both "mkdir" and "rmdir" had to be set-UID to be able to create a `Unix' directory (i.e., the system call didn't create these links, but "mkdir" did!) J. Wong ucbvax!mtxinu!rtech!wong **************************************************************** You start a conversation, you can't even finish it. You're talking alot, but you're not saying anything. When I have nothing to say, my lips are sealed. Say something once, why say it again. - David Byrne
wes@obie.UUCP (Barnacle Wes) (01/30/88)
On System V, directories are made with the system call mknod(2). To make the directory '/usr/fool' with rwxrwxr-x permissions, you would use: mknod("/usr/fool", 040775, 0); The mode bits are: 040000: make directory, 0775: permission bits.
daveb@geac.UUCP (David Collier-Brown) (01/30/88)
In article <1185@ark.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes: |In article <1017@uokmax.UUCP> rmtodd@uokmax.UUCP () writes: ||My understanding is that mkdir() was made into a system call in BSD (probably ||because they had just changed the directory format). | |The 'old' mkdir program has a serious security bug (to become su). The "new, secure" rename system call, on the other hand, has a serious functionality bug: it panics, dumps core and cross-links two directories in Utrix 2.x if one tries to move a directory to a mis-specified location. Setuid was **invented** to deal with the security/functionality tradeoff in a workable way. To claim that it is more than a security **risk** is to mistakenly trivialize the problems T & R faced. --dave (do you want software written by grad students, or salesmen?) c-b -- David Collier-Brown. {mnetor yunexus utgpu}!geac!daveb Geac Computers International Inc., | Computer Science loses its 350 Steelcase Road,Markham, Ontario, | memory (if not its mind) CANADA, L3R 1B3 (416) 475-0525 x3279 | every 6 months.
jay@splut.UUCP (Jay Maynard) (02/01/88)
In article <224@intelisc.UUCP>, shannon@intelisc.UUCP (Shannon Nelson) writes: > I may be showing my ignorance, but what ever happened to the mkdir() > call? In my manuals (Xenix, sysVr3, Pyramid OSx) [...] ^^ > [...] Given this, and the overhead inherent in system(), why are you > not using mkdir()? My SVr2 doesn't have it, and I suspect that lots of other Unixes (Unix? Unices? What _is_ the plural of Unix, anyway?) don't either. -- Jay Maynard, K5ZC (@WB5BBW)...>splut!< | GEnie: JAYMAYNARD CI$: 71036,1603 uucp: {uunet!nuchat,academ!uhnix1,{ihnp4,bellcore,killer}!tness1}!splut!jay Never ascribe to malice that which can adequately be explained by stupidity. The opinions herein are shared by none of my cats, much less anyone else.
rikki)) (02/02/88)
From article <2794@cbdkc1.ATT.COM>, by pmd@cbdkc1.ATT.COM (Paul Dubuc): > In article <447@cpsc6b.cpsc6a.att.com> (Chris (I'm Outta Here!) Seaman) writes: > }As for what system is good for, try this one: How about if an application which is really a command interpreter but allows the user to escape to the shell to do things like "!write joe"? Back in the middle ages before the "system" call existed, we invariably included a routine in our applications to do that -- it simply forked /bin/sh (passing the parsed arguments), exec'd, and waited. It was invariable named "execute" or "system". Seemed like a useful thing. -- Rikki Welsh Centel Information Systems 5515 Security Lane, Rockville, Maryland, 20852, (301) 984-3636 UUCP: decuac!macom1!rikki
pmd@cbdkc1.ATT.COM (Paul Dubuc) (02/02/88)
In article <7@obie.UUCP> wes@obie.UUCP (Barnacle Wes) writes: }On System V, directories are made with the system call mknod(2). }To make the directory '/usr/fool' with rwxrwxr-x permissions, }you would use: } } mknod("/usr/fool", 040775, 0); } }The mode bits are: 040000: make directory, 0775: permission bits. It's already been mentioned that System Vr3 has a mkdir() call, but in the older systems, this still won't do the whole job of making a directory. After the mknod(), you need two calls to link() to make it properly: link("/usr/fool", "/usr/fool/."); link("/usr", "/usr/fool/.."); This *still* requires the calling program to have super-user permission, so I think the solution of using a routine that exec's the mkdir comand is better. I never understood why making directories was a super user priviledge. Can someone enlighten me? Since they changed it in r3 of sys V, there must not have been a good reason. -- Paul Dubuc {ihnp4,cbosgd}!cbdkc1!pmd
gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/08/88)
In article <2824@cbdkc1.ATT.COM> pmd@cbdkc1.UUCP (Paul Dubuc) writes: >After the mknod(), you need two calls to link() to make it properly: [...] >I never understood why making directories was a super user priviledge. Because, if the links weren't done right, the directory hierarchy could be turned into a royal mess. Therefore only a limited amount of (presumably carefully-checked) code was permitted to make directories, and everything else had to ask the privileged process to help get it right. Indeed, this is the main point of the "superuser" on UNIX; far from being a security problem, as you read in various places, it is the minimum mechanism that is absolutely necessary to ensure that important system operations are carried out securely. Unfortunately a lot of people who don't grok simplicity are working to pile a mess of more conventional layered security features on UNIX. Too bad.
ftw@datacube.UUCP (02/11/88)
pmd@cbdkc1.UUCP writes: > Because many of us are still fooling around with older versions of UNIX > (e.g., sysVr2) that don't have a standard mkdir() routine. There is a mknod() > system call but it needs su permission and is clumsy for making directories > (needing to be called 3 times to do it right). > -- > Paul Dubuc {ihnp4,cbosgd}!cbdkc1!pmd I was able to do that with one mknod() and two calls to link(). (Okay, Name That Tune! 8-) Farrell T. Woods Datacube Inc. Systems / Software Group 4 Dearborn Rd. Peabody, Ma 01960 VOICE: 617-535-6644; FAX: (617) 535-5643; TWX: (710) 347-0125 INTERNET: ftw@datacube.COM UUCP: {rutgers, ihnp4, mirror}!datacube!ftw "OS/2 -- Half an operating system"
ftw@datacube.UUCP (02/11/88)
gwyn@brl-smoke.UUCP writes: > Because, if the links weren't done right, the directory hierarchy could > be turned into a royal mess. Ah, yes. It's amazing how quickly our Pyramid came to its knees when I was in the Sys V universe, ran a program with a defective "mkdir()", and then tried to use the newly created directory... Farrell T. Woods Datacube Inc. Systems / Software Group 4 Dearborn Rd. Peabody, Ma 01960 VOICE: 617-535-6644; FAX: (617) 535-5643; TWX: (710) 347-0125 INTERNET: ftw@datacube.COM UUCP: {rutgers, ihnp4, mirror}!datacube!ftw "OS/2 -- Half an operating system"
det@hawkmoon.MN.ORG (Derek E. Terveer) (01/21/89)
Has anyone encountered a problem with the Microsoft C 5.0 compiler always returning a 0 from the system() call, no matter what the actual command executed by system() returns? Is there a fix for this or am i misunderstanding something fundamental about the way the system() call works in msc5.0? (Like the command.com always returning the 0, which system(), in turn, returns to my program?) I'm trying to determine whether or not the executed command succeeded or not by looking at the completion code from system, ala: char buf[BUFSIZ]; sprintf(buf,"rnews < D_elricf.3aa"); if (!system(buf)) perror(buf); and i'm having a hard time of it since system() always (seems) to return 0! derek -- Derek Terveer det@hawkmoon.MN.ORG || ..!uunet!rosevax!elric!hawkmoon!det w(612)681-6986 h(612)688-0667 "A proper king is crowned" -- Thomas B. Costain
jeenglis@nunki.usc.edu (Joe English) (01/24/89)
In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes: >Has anyone encountered a problem with the Microsoft C 5.0 compiler always >returning a 0 from the system() call, no matter what the actual command >executed by system() returns? That, unfortunately, is right. system() returns the exit status of command.com (in Turbo C, anyway, and I suspect that MSC works the same way), and command.com doesn't return an error code if the called program fails. (!) (system() also returns non-zero if command.com could not be loaded for lack of memory.) The way to get the return status of the program you're interested in is to use one of the exec or spawn functions, which call the DOS load/exec syscall and bypass command.com. It's possible, though a bit more work, to do redirection with these as well (check out dup() and dup2()); the only thing you can't do is call command.com-resident functions like copy and type. Joe English jeenglis@nunki.usc.edu
alexande@drivax.DRI (Mark Alexander) (01/25/89)
One possible solution to the problem of COMMAND.COM always returning zero is that used by NDMAKE. The basic idea is to construct on the fly a little batch file that gets passed to COMMAND.COM. Before you call system(), though, you create a little zero-length temporary file. The batch file runs the subprogram, then checks the errorlevel. If the errorlevel is 0, it deletes the temporary file. Then the main program gets control again and checks the existence of the temporary file: if it still exists, an error occurred. The batch file would look something like this: prog [parms...] [<infile] [>outfile] if errorlevel 1 goto done del tempfile :done -- Mark Alexander (amdahl!drivax!alexande)
bkbarret@sactoh0.UUCP (Brent K. Barrett) (01/25/89)
In article <2439@nunki.usc.edu>, jeenglis@nunki.usc.edu (Joe English) writes: > > In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes: > >Has anyone encountered a problem with the Microsoft C 5.0 compiler always > >returning a 0 from the system() call, no matter what the actual command > >executed by system() returns? > > That, unfortunately, is right. system() returns the exit status of > command.com (in Turbo C, anyway, and I suspect that MSC works the same > way), and command.com doesn't return an error code if the called > program fails. (!) (system() also returns non-zero if command.com could > not be loaded for lack of memory.) > That may not be entirely correct, at least as far as TC goes. In Turbo C 2.0 (and, I believe, 1.5, even though it was not documented), system() will return 0 if command.com was successfully loaded, and -1 if command.com was not found. I do not know the ANSI standard on this beast (if indeed there is one), but since MSC and TC both have it functioning this way, I'm going to assume it's ANSI. You are correct that spawn()/exec() should be used to return the proper errorlevels. I ran into this exact same problem a few days ago when I wanted to run a small utility program externally from a larger program without removing the larger program from memory. An errorlevel had to be returned and system() didn't seem to want to do it. I was confused by the TC 1.0 manual and the 2.0 THELP. The manual stated that the errorlevel was returned, while the THELP indicated the true condition. Since I only ordered the upgrade to 2.0, I did not receive a full 2.0 manual, and only have the 1.0 description of system(). Fortunately for me, a Borland beta tester is easily accessable. -- "Somebody help me! I'm trapped in this computer!" Brent Barrett ..pacbell!sactoh0!bkbarret GEMAIL: B.K.BARRETT
wietse@wzv.UUCP (Wietse Z. Venema) (01/25/89)
In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes: >Has anyone encountered a problem with the Microsoft C 5.0 compiler always >returning a 0 from the system() call, no matter what the actual command >executed by system() returns? Command.com always returns a zero status. There are two alternatives: (a) Do not use a shell, but use the spawnlp() functions. These are similar to the unix execlp() functions, but instead of over- laying the calling process they just suspend it. (b) Use a different shell. This may not be practical if your program is to be used on other machines. In case of alternative (a) you will have to do your own i/o redirection handling. Caveat: in some cases I had to save the positions of all stdio streams open for reading from files, and restore them after the system() routine terminated. -- work: wswietse@eutrc3.uucp | Eindhoven University of Technology work: wswietse@heitue5.bitnet | Mathematics and Computing Science home: wietse@wzv.uucp | 5600 MB Eindhoven, The Netherlands
bobmon@iuvax.cs.indiana.edu (RAMontante) (01/25/89)
[ The "system()" returns 0 after invoking COMMAND.COM, in MSC and TC on MSDOS machines ] <646@sactoh0.UUCP> bkbarret@sactoh0.UUCP (Brent K. Barrett): > > That may not be entirely correct, at least as far as TC goes. In >Turbo C 2.0 (and, I believe, 1.5, even though it was not >documented), system() will return 0 if command.com was successfully >loaded, and -1 if command.com was not found. I do not know the ANSI >standard on this beast (if indeed there is one), but since MSC and >TC both have it functioning this way, I'm going to assume it's >ANSI. "System()" in Turbo C is specifically defined to "...invoke COMMAND.COM to execute a command...". In TCv1.5 the return value is described as the exit status of COMMAND.COM. Unfortunately (but not surprisingly) COMMAND.COM exits with a 0 if it successfully loads and runs, whether the executable file that it was supposed to execute was successful or not. So the only information that you can get back from COMMAND.COM is whether it (loaded and) ran, or crashed the whole dam' machine; nothing about what it did while it was running. This has nothing to do with ANSI, which doesn't specify the behavior of MSDOS. The C "system()" call is doing what it should, but what it receives from the operating system isn't any use to anyone (except in the case of a missing COMMAND.COM file). > You are correct that spawn()/exec() should be used to return the >proper errorlevels. No problem here, as COMMAND.COM isn't involved. The executed file is responsible for returning a meaningful value to spawn() / exec().
ray@ole.UUCP (Ray Berry) (01/26/89)
value from the last program it executed. There are times when it would be handy to be able to interrogate that number from the command line. Does anyone know a way to do this? The location of the variable? Obviously a short shell could be written in c to execute it and print the value, but it seems as though it the ERRORLEVEL variable must be present somewhere in memory. -- Ray Berry KB7HT uucp: ...{uw-beaver|uiucuxc}tikal!ole!ray CS: 73407,3152 Seattle Silicon Corp. 3075 112th Ave NE. Bellevue WA 98004 (206) 828 4422
bright@Data-IO.COM (Walter Bright) (01/26/89)
In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes: >Has anyone encountered a problem with the Microsoft C 5.0 compiler always >returning a 0 from the system() call, no matter what the actual command >executed by system() returns? system("command") on MS-DOS is usually implemented by running COMMAND.COM with the argument "/c command". The system() call returns the value that COMMAND.COM returns. COMMAND.COM does not return the exit status of the command that it executed, so it's a DOS bug, not a compiler library bug. The correct solution is to use the spawn() function. spawn() also uses less memory and executes faster than system(). The only caveats are that spawn() cannot execute COMMAND.COM's built-in commands like TYPE and DIR, and spawn() does not do the < | > redirection.
ked@garnet.berkeley.edu (Earl H. Kinmonth) (01/26/89)
In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes: >Has anyone encountered a problem with the Microsoft C 5.0 compiler always >returning a 0 from the system() call, no matter what the actual command >executed by system() returns? The same brain dead result occurs with the Turbo C system call. Presumably the problem is in command.com. I wrote my own system() using spawn to get around this. Remember, you don't get to be a multi-billion dollar company by doing this for the conveience of users.
scm@datlog.co.uk ( Steve Mawer ) (01/26/89)
In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes: >Has anyone encountered a problem with the Microsoft C 5.0 compiler always >returning a 0 from the system() call, no matter what the actual command >executed by system() returns? > >and i'm having a hard time of it since system() always (seems) to return 0! > According to my Microsoft manual "The system function returns the value 0 if string is successfully executed. A return value of -1 indicates an error ..." and cites the error reasons as being E2BIG - arg list > 128 bytes or env info >32K ENOENT - can't find COMMAND.COM ENOEXEC - COMMAND.COM file can't be executed ENOMEM - insufficient memory to execute the command, etc. What it returns is whether its exec succeeded, not the exec'd command's status. I have been burned by this problem, too, and haven't got a solution. (Anyone?) -- Steve C. Mawer <scm@datlog.co.uk> or < {backbone}!ukc!datlog!scm > Voice: +44 1 863 0383 (x2153)
sme@computing-maths.cardiff.ac.uk (Simon Elliott) (02/01/89)
In article <782@hawkmoon.MN.ORG>, det@hawkmoon.MN.ORG (Derek E. Terveer) writes: > Has anyone encountered a problem with the Microsoft C 5.0 compiler always > returning a 0 from the system() call, no matter what the actual command > executed by system() returns? > -- > Derek Terveer det@hawkmoon.MN.ORG || ..!uunet!rosevax!elric!hawkmoon!det The problem is that system works by constructing a "command /c yourcommand", thus letting commnad.com do the work of looking down the path, etc. command.com _always_ succeeds, so system returns 0, always. You have to do the work yourself, and use one of the spawn/exec functions if you want meaningful status information. I have used this behaviour of command.com in makefiles when i want to clean up files which may not be there. Some versions of make will croak if the file is not there, since the 'del' is a builtin, but command /c del will always succeed, and the make continues. -- -------------------------------------------------------------------------- Simon Elliott Internet: sme%v1.cm.cf.ac.uk@cunyvm.cuny.edu UWCC Computer Centre JANET: sme@uk.ac.cf.cm.v1 40/41 Park Place UUCP: {backbones}!mcvax!ukc!reading!cf-cm!sme Cardiff, Wales PHONE: +44 222 874300
tp1l+@andrew.cmu.edu (Thomas W. Pope) (02/03/91)
I am writing a short program to put into my autoexec file, allowing me to select a shorter autoexec by hitting a key. For this I tried to use the system() command to run either of two batch files. The command works fine, but the program stays resident after that call, adding 64k to my memory usage. The Turbo C manuals say that the system command will run batch files fine, but it seems to terminate withour clearing memory every time I try it... Does anyone know how I could make these calls from my program??? I have tried the following calls: system(default) system(call default) execvp("default.bat") execvp("dobat.exe",default.bat") the system calls all ran the batch files correctly, but the program still didn't exit gracefully. The execvp() calls wouldn't recognise either the batch files or the dobat.exe with the batch files as parameters. Any help would be greatly appreciated... Thanks in advance -Thomas Pope P.S. Dobat.exe is a shareware program that allows you to call a batch file from within another batch file, and return to the calling file when finished.
jdb@reef.cis.ufl.edu (Brian K. W. Hook) (02/04/91)
In article <obetOdy00UzxA2Ya89@andrew.cmu.edu> tp1l+@andrew.cmu.edu (Thomas W. Pope) writes: |> |> I am writing a short program to put into my autoexec file, allowing me |>to select a shorter autoexec by hitting a key. For this I tried to use the |>system() command to run either of two batch files. The command works fine, but |>the program stays resident after that call, adding 64k to my memory usage. |> The Turbo C manuals say that the system command will run batch files fine, |>but it seems to terminate withour clearing memory every time I try it... Does |>anyone know how I could make these calls from my program??? I have tried the |>following calls: |> |> |> system(default) system(call default) |> execvp("default.bat") execvp("dobat.exe",default.bat") I know that in DOS if you call a batch file from another batch file that it will not return unless you state specifically that what you are doing is calling a BAT file....e.g. CALL DEFAULT.BAT Does your program get past the system() command? If not, then it is likely that it is getting stuck after that .BAT file....the system() command executes a command and then returns to the calling process, so I would presume that you would want to return....if you don't want to return to the calling process don't use system()....in other words, if you are chaining your main program to your batch program, without returning to the main program, don't use system(). Execxx (xx are the various incarnations you can use) should work, but I am not familiar enough with them....have you considered using errorlevels? The DOS manual states how errorlevels are used, and errorlevels are very easy to set with a program...it's simply the return value of main(). E.g. (not sure if syntax is exact) getbat if errorlevel==1 call bat1.bat if errorlevel==2 call bat2.bat However, I believe that errorlevel evaluates to true if the current errorlevel is equal to or higher than what you are comparing it to....so that example isn't exactly correct.... Hope this muddle sort of helped, comp.os.msdos.programmer might be able to help out a bit more.
hp@vmars.tuwien.ac.at (Peter Holzer) (02/10/91)
tp1l+@andrew.cmu.edu (Thomas W. Pope) writes: > I am writing a short program to put into my autoexec file, allowing me >to select a shorter autoexec by hitting a key. For this I tried to use the >system() command to run either of two batch files. The command works fine, but >the program stays resident after that call, adding 64k to my memory usage. > The Turbo C manuals say that the system command will run batch files fine, >but it seems to terminate withour clearing memory every time I try it... Does >anyone know how I could make these calls from my program??? I have tried the >following calls: > system(default) system(call default) Shouldn't this be: system ("default"); and system ("call default"); ? Apart from that, does your batchfile invoke any TSRs? If it does, it will fragment your memory, and DOS will report only the largest chunk as free memory, although it can use the rest as well. Your memory looks something like that (low addresses at the bottom: Command.com DOS Start your program: yourprog.exe Command.com DOS system ("default"): command.com -c default yourprog.exe Command.com DOS default now executes some TSR, e.g. sidekick: sidekick command.com -c default yourprog.exe Command.com DOS default terminates, thus command.com and system terminate, too: sidekick <empty space> yourprog.exe Command.com DOS Then your program terminates: sidekick <empty space> <empty space> Command.com DOS So you have sidekick floating around somewhere in mid-memory, with a whole of ~64kB below it and a larger hole above it. DOS will always use the largest available whole and it cannot split a program to use multiple wholes so you have wasted those 64kB :-(. -- | _ | Peter J. Holzer | Think of it | | |_|_) | Technical University Vienna | as evolution | | | | | Dept. for Real-Time Systems | in action! | | __/ | hp@vmars.tuwien.ac.at | Tony Rand |
francis@atmos.cse.ogi.edu (Francis Moraes) (06/10/91)
I compiled the following program using Turbo C under all of its memory
models:
main()
{
system("vtsr");
}
Vtsr is a program that lists the programs in memory and the amount of memory
allocated to it. The amount of memory in kilobytes used by this program are
given below for each of the memory models:
model memory usage
====================
tiny 64.2
small 66.7
compact 9.0
medium 66.8
large 10.0
huge 10.0
I think it is interesting that the memory models that use far pointers for
data have smaller memory usage than those with near data pointers. Does anyone
know why this is so? The same problem exists with the exec() function. I
hope this isn't a stupid question. Send me mail or post as you see fit. If
I get enough mail I will post a summary.
francis@atmos.ogi.edu