Message-ID: <39A1181F.C25823B3@softhome.net> Date: Mon, 21 Aug 2000 13:53:03 +0200 From: Laurynas Biveinis X-Mailer: Mozilla 4.74 [en] (Win98; U) X-Accept-Language: lt,en MIME-Version: 1.0 To: DJGPP Workers Subject: Patch: symlinks to programs Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Here are changes for dosexec.c to DTRT with symlinks. This code was probably the hardest piece of symlink support to implement, so there might be few stupid stupidities laying around in this patch, although my testsuite suggests that it even works. This is (If I haven't skipped anything else) the last non-trivial patch for symlinks. All upcoming patches will be mostly if (!__solve_symlinks(path, real_path)) return -1; ... /* Change 'path' to 'real_path' everywhere... */ Feedback is very welcome for this patch. Laurynas Index: djgpp/src/libc/dos/process/dosexec.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/dos/process/dosexec.c,v retrieving revision 1.9 diff -u -r1.9 dosexec.c --- dosexec.c 2000/08/03 12:21:17 1.9 +++ dosexec.c 2000/08/21 11:41:51 @@ -22,6 +22,7 @@ #include #include #include +#include /* FIXME: this is not LFN-clean. Win95 has a way to pass long command lines, but we don't support it here. */ @@ -519,6 +520,7 @@ int i; char *go32, *sip=0; char rpath[FILENAME_MAX]; + char real_program[FILENAME_MAX]; int argc=0; int si_la=0, si_off=0, rm_off, argv_off; @@ -527,8 +529,11 @@ int retval; int lfn = 2; /* means don't know yet */ - type = _check_v2_prog (program, -1); + if (!__solve_symlinks(program, real_program)) + return -1; + type = _check_v2_prog (real_program, -1); + /* Because this function is called only, when program exists, I can skip the check for type->valid */ @@ -539,16 +544,16 @@ if (type->exec_format == _V2_EXEC_FORMAT_UNIXSCRIPT) { - return script_exec(program, argv, envp); + return script_exec(real_program, argv, envp); } /* Non-DJGPP programs cannot be run by !proxy. */ if (!is_coff) { if (type->exec_format == _V2_EXEC_FORMAT_EXE) - return direct_exec(program, argv, envp); + return direct_exec(real_program, argv, envp); else - return __dosexec_command_exec (program, argv, envp); + return __dosexec_command_exec (real_program, argv, envp); } if (found_si) @@ -560,7 +565,7 @@ if (v2_0 && is_stubbed) { - strcpy(rpath, program); + strcpy(rpath, real_program); } else { @@ -568,7 +573,7 @@ if (!__dosexec_find_on_path(go32, envp, rpath)) { errno = e; - return direct_exec(program, argv, envp); /* give up and just run it */ + return direct_exec(real_program, argv, envp); /* give up and just run it */ } if (found_si) @@ -586,7 +591,7 @@ usual DOS command line and the !proxy one (which will be put into the environment). Sigh... */ save_argv0 = argv[0]; - argv[0] = unconst(program, char *); /* since that's where we really found it */ + argv[0] = unconst(program, char *); /* Construct the DOS command tail */ for (argc=0; argv[argc]; argc++); @@ -704,9 +709,13 @@ int cmdlen; int i; int was_quoted = 0; /* was the program name quoted? */ + char real_program[FILENAME_MAX]; + + if (!__solve_symlinks(program, real_program)) + return -1; /* Add spare space for possible quote characters. */ - cmdlen = strlen(program) + 4 + 2; + cmdlen = strlen(real_program) + 4 + 2; for (i=0; argv[i]; i++) cmdlen += 2*strlen(argv[i]) + 1; cmdline = (char *)alloca(cmdlen); @@ -714,21 +723,21 @@ /* FIXME: is this LFN-clean? What special characters can the program name have and how should they be quoted? */ strcpy(cmdline, "/c "); - if (strchr(program, ' ') || strchr(program, '\t')) + if (strchr(real_program, ' ') || strchr(real_program, '\t')) { was_quoted = 1; cmdline[3] = '"'; } - for (i = 0; program[i] > ' '; i++) + for (i = 0; real_program[i] > ' '; i++) { /* COMMAND.COM cannot grok program names with forward slashes. */ if (program[i] == '/') cmdline[i+3+was_quoted] = '\\'; else - cmdline[i+3+was_quoted] = program[i]; + cmdline[i+3+was_quoted] = real_program[i]; } - for (; program[i]; i++) - cmdline[i+3+was_quoted] = program[i]; + for (; real_program[i]; i++) + cmdline[i+3+was_quoted] = real_program[i]; if (was_quoted) { cmdline[i+3+was_quoted] = '"'; Index: djgpp/tests/libc/dos/process/args.c =================================================================== RCS file: args.c diff -N args.c --- /dev/null Tue May 5 16:32:27 1998 +++ args.c Mon Aug 21 07:42:04 2000 @@ -0,0 +1,9 @@ +#include + +int main(int argc, char *argv[]) +{ + int i; + for (i = 0; i < argc; i++) + printf("argv[%d] = %s\n", i, argv[i]); + return 0; +} Index: djgpp/tests/libc/dos/process/makefile =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/dos/process/makefile,v retrieving revision 1.1 diff -u -r1.1 makefile --- makefile 1995/11/13 03:14:50 1.1 +++ makefile 2000/08/21 11:42:04 @@ -1,5 +1,7 @@ TOP=../.. +SRC += args.c SRC += spawnvp.c +SRC += symlinks.c include $(TOP)/../makefile.inc Index: djgpp/tests/libc/dos/process/symlinks.c =================================================================== RCS file: symlinks.c diff -N symlinks.c --- /dev/null Tue May 5 16:32:27 1998 +++ symlinks.c Mon Aug 21 07:42:04 2000 @@ -0,0 +1,28 @@ +/* Testsuite for symlink handling aspect in launching program. + * This is by no means a regression testsuite, you have to decide + * if bad stuff happens from output. + * + * Shell script handling will be checked only if you have bash installed. + */ +#include +#include +#include +#include + +int main(void) +{ + symlink("args.exe", "linkargs.exe"); + system("args.exe 1 2 3"); + system("linkargs.exe 4 5 6"); + spawnl(P_WAIT, "args.exe", "args.exe", "what", NULL); + spawnl(P_WAIT, "linkargs.exe", "linkargs.exe", "where", "why", NULL); + remove("linkargs.exe"); + symlink("C:/command.com", "linkcom.com"); + system("linkcom.com"); + remove("linkcom.com"); + symlink("test.sh", "linksh.sh"); + system("test.sh"); + system("linksh.sh"); + remove("linksh.sh"); + return 0; +} Index: djgpp/tests/libc/dos/process/test.sh =================================================================== RCS file: test.sh diff -N test.sh --- /dev/null Tue May 5 16:32:27 1998 +++ test.sh Mon Aug 21 07:42:04 2000 @@ -0,0 +1,3 @@ +#!/bin/sh +echo Just checking... +