3 /* See Makefile for compilation details. */
9 #if defined (HAVE_UNISTD_H)
13 #include "posixstat.h"
20 #include "bashgetopt.h"
26 typedef int unix_link_syscall_t
__P((const char *, const char *));
28 #define LN_SYMLINK 0x01
29 #define LN_UNLINK 0x02
31 static unix_link_syscall_t
*linkfn
;
43 reset_internal_getopt ();
44 while ((opt
= internal_getopt (list
, "fs")) != -1)
67 linkfn
= (flags
& LN_SYMLINK
) ? symlink
: link
;
69 if (list
->next
== 0) /* ln target, equivalent to ln target . */
70 return (dolink (list
->word
->word
, ".", flags
));
72 if (list
->next
->next
== 0) /* ln target source */
73 return (dolink (list
->word
->word
, list
->next
->word
->word
, flags
));
75 /* ln target1 target2 ... directory */
77 /* find last argument: target directory, and make sure it's an existing
79 for (l
= list
; l
->next
; l
= l
->next
)
83 if (stat(sdir
, &sb
) < 0)
85 builtin_error ("%s", sdir
);
86 return (EXECUTION_FAILURE
);
89 if (S_ISDIR (sb
.st_mode
) == 0)
95 for (rval
= EXECUTION_SUCCESS
; list
!= l
; list
= list
->next
)
96 rval
+= dolink (list
->word
->word
, sdir
, flags
);
102 mkdirpath (dir
, file
)
109 flen
= strlen (file
);
111 ret
= xmalloc (2 + dlen
+ flen
);
114 if (ret
[dlen
- 1] != '/')
116 strcpy (ret
+ dlen
, file
);
120 #if defined (HAVE_LSTAT)
127 dolink (src
, dst
, flags
)
131 struct stat ssb
, dsb
;
135 /* If we're not doing symlinks, the source must exist and not be a
137 if ((flags
& LN_SYMLINK
) == 0)
139 if (stat (src
, &ssb
) != 0)
141 builtin_error ("%s: %s", src
, strerror (errno
));
142 return (EXECUTION_FAILURE
);
144 if (S_ISDIR (ssb
.st_mode
))
147 builtin_error ("%s: %s", src
, strerror (errno
));
148 return (EXECUTION_FAILURE
);
152 /* If the destination is a directory, create the final filename by appending
153 the basename of the source to the destination. */
155 if ((stat (dst
, &dsb
) == 0) && S_ISDIR (dsb
.st_mode
))
157 if ((p
= strrchr (src
, '/')) == 0)
162 dst_path
= mkdirpath (dst
, p
);
166 exists
= LSTAT (dst
, &dsb
) == 0;
168 /* If -f was specified, and the destination exists, unlink it. */
169 if ((flags
& LN_UNLINK
) && exists
&& unlink (dst
) != 0)
171 builtin_error ("%s: cannot unlink: %s", dst
, strerror (errno
));
173 return (EXECUTION_FAILURE
);
176 /* Perform the link. */
177 if ((*linkfn
) (src
, dst
) != 0)
179 builtin_error ("cannot link %s to %s: %s", dst
, src
, strerror (errno
));
181 return (EXECUTION_FAILURE
);
185 return (EXECUTION_SUCCESS
);
189 "Create a new directory entry with the same modes as the original",
190 "file. The -f option means to unlink any existing file, permitting",
191 "the link to occur. The -s option means to create a symbolic link.",
192 "By default, ln makes hard links.",
196 /* The standard structure describing a builtin command. bash keeps an array
197 of these structures. */
198 struct builtin ln_struct
= {
199 "ln", /* builtin name */
200 ln_builtin
, /* function implementing the builtin */
201 BUILTIN_ENABLED
, /* initial flags for builtin */
202 ln_doc
, /* array of long documentation strings. */
203 "ln [-fs] file1 [file2] OR ln [-fs] file ... directory", /* usage synopsis; becomes short_doc */
204 0 /* reserved for internal use */