diff options
author | Steve Bennett <steveb@workware.net.au> | 2014-11-28 09:57:01 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2014-11-28 15:37:58 +1000 |
commit | 4a1c716c9db7f4348513168febc1ea1266bf4b3a (patch) | |
tree | 32ec0660eed270b7d8c9e2a887a08b852a57141f | |
parent | 4a7c05835e2cf52526a6d8de5b3fc446fb3dbbf9 (diff) | |
download | jimtcl-4a1c716c9db7f4348513168febc1ea1266bf4b3a.zip jimtcl-4a1c716c9db7f4348513168febc1ea1266bf4b3a.tar.gz jimtcl-4a1c716c9db7f4348513168febc1ea1266bf4b3a.tar.bz2 |
file: add support for file link
Currently only on systems that support both hard and symbolic links.
Update docs for 'file link' and some other [file] commands
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | auto.def | 2 | ||||
-rw-r--r-- | jim-file.c | 47 | ||||
-rw-r--r-- | jim_tcl.txt | 15 |
3 files changed, 60 insertions, 4 deletions
@@ -101,7 +101,7 @@ cc-check-functions ualarm lstat fork vfork system select execvpe cc-check-functions backtrace geteuid mkstemp realpath strptime isatty cc-check-functions regcomp waitpid sigaction sys_signame sys_siglist isascii cc-check-functions syslog opendir readlink sleep usleep pipe getaddrinfo utimes -cc-check-functions shutdown socketpair isinf isnan +cc-check-functions shutdown socketpair isinf isnan link symlink if {[cc-check-functions sysinfo]} { cc-with {-includes sys/sysinfo.h} { @@ -528,6 +528,44 @@ static int file_cmd_rename(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } +#if defined(HAVE_LINK) && defined(HAVE_SYMLINK) +static int file_cmd_link(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int ret; + const char *source; + const char *dest; + static const char * const options[] = { "-hard", "-symbolic", NULL }; + enum { OPT_HARD, OPT_SYMBOLIC, }; + int option = OPT_HARD; + + if (argc == 3) { + if (Jim_GetEnum(interp, argv[0], options, &option, NULL, JIM_ENUM_ABBREV | JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + argv++; + argc--; + } + + dest = Jim_String(argv[0]); + source = Jim_String(argv[1]); + + if (option == OPT_HARD) { + ret = link(source, dest); + } + else { + ret = symlink(source, dest); + } + + if (ret != 0) { + Jim_SetResultFormatted(interp, "error linking \"%#s\" to \"%#s\": %s", argv[0], argv[1], + strerror(errno)); + return JIM_ERR; + } + + return JIM_OK; +} +#endif + static int file_stat(Jim_Interp *interp, Jim_Obj *filename, struct stat *sb) { const char *path = Jim_String(filename); @@ -825,6 +863,15 @@ static const jim_subcmd_type file_command_table[] = { 3, /* Description: Renames a file */ }, +#if defined(HAVE_LINK) && defined(HAVE_SYMLINK) + { "link", + "?-symbolic|-hard? newname target", + file_cmd_link, + 2, + 3, + /* Description: Creates a hard or soft link */ + }, +#endif #if defined(HAVE_READLINK) { "readlink", "name", diff --git a/jim_tcl.txt b/jim_tcl.txt index d1eb687..2305b88 100644 --- a/jim_tcl.txt +++ b/jim_tcl.txt @@ -2243,11 +2243,12 @@ abbreviation for +'option'+ is acceptable. The valid options are: Copies file +'source'+ to file +'target'+. The source file must exist. The target file must not exist, unless +-force+ is specified. -+*file delete ?-force?* 'name\...'+:: ++*file delete ?-force? ?--?* 'name\...'+:: Deletes file or directory +'name'+. If the file or directory doesn't exist, nothing happens. If it can't be deleted, an error is generated. Non-empty directories will not be deleted unless the +-force+ options is given. In this case no errors will be generated, even - if the file/directory can't be deleted. + if the file/directory can't be deleted. Use +'--'+ if there is any possibility of + the first name being +'-force'+. +*file dirname* 'name'+:: Return all of the characters in +'name'+ up to but not including @@ -2281,6 +2282,12 @@ abbreviation for +'option'+ is acceptable. The valid options are: an absolute path, the preceding components are ignored. Thus +"`file` join /tmp /root"+ returns +"/root"+. ++*file link* ?*-hard|-symbolic*? 'newname target'+:: + Creates a hard link (default) or symbolic link from +'newname'+ to +'target'+. + Note that the sense of this command is the opposite of `file rename` and `file copy` + and also of `ln`, but this is compatible with Tcl. + An error is returned if +'target'+ doesn't exist or +'newname'+ already exists. + +*file lstat* 'name varName'+:: Same as 'stat' option (see below) except uses the +'lstat'+ kernel call instead of +'stat'+. This means that if +'name'+ @@ -2324,8 +2331,10 @@ abbreviation for +'option'+ is acceptable. The valid options are: an error is returned. On systems that don't support symbolic links this option is undefined. -+*file rename* 'oldname' 'newname'+:: ++*file rename* ?*-force*? 'oldname' 'newname'+:: Renames the file from the old name to the new name. + If +'newname'+ already exists, an error is returned unless +'-force'+ is + specified. +*file rootname* 'name'+:: Return all of the characters in +'name'+ up to but not including |