Skip to content

Commit 6c7ad3e

Browse files
authored
Merge pull request torvalds#294 from copumpkin/cptofs-symlinks
lkl tools: add symlink support to cptofs
2 parents 3472d83 + c22fee9 commit 6c7ad3e

File tree

1 file changed

+89
-6
lines changed

1 file changed

+89
-6
lines changed

tools/lkl/cptofs.c

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,20 +236,28 @@ static int copy_file(const char *src, const char *dst, int mode)
236236
return ret;
237237
}
238238

239-
static int stat_src(const char *path, int *type, int *mode)
239+
static int stat_src(const char *path, int *type, int *mode, int *size)
240240
{
241241
struct stat stat;
242242
struct lkl_stat lkl_stat;
243243
int ret;
244244

245245
if (cptofs) {
246246
ret = lstat(path, &stat);
247-
*type = stat.st_mode & S_IFMT;
248-
*mode = stat.st_mode & ~S_IFMT;
247+
if (type)
248+
*type = stat.st_mode & S_IFMT;
249+
if (mode)
250+
*mode = stat.st_mode & ~S_IFMT;
251+
if (size)
252+
*size = stat.st_size;
249253
} else {
250254
ret = lkl_sys_lstat(path, &lkl_stat);
251-
*type = lkl_stat.st_mode & S_IFMT;
252-
*mode = lkl_stat.st_mode & ~S_IFMT;
255+
if (type)
256+
*type = lkl_stat.st_mode & S_IFMT;
257+
if (mode)
258+
*mode = lkl_stat.st_mode & ~S_IFMT;
259+
if (size)
260+
*size = lkl_stat.st_size;
253261
}
254262

255263
if (ret)
@@ -280,6 +288,79 @@ static int mkdir_dst(const char *path, int mode)
280288
return ret;
281289
}
282290

291+
static int readlink_src(const char *src, char *out, int outsize)
292+
{
293+
int ret;
294+
295+
if (cptofs)
296+
ret = readlink(src, out, outsize);
297+
else
298+
ret = lkl_sys_readlink(src, out, outsize);
299+
300+
if (ret < 0)
301+
fprintf(stderr, "unable to readlink '%s': %s\n", src,
302+
cptofs ? strerror(errno) : lkl_strerror(ret));
303+
304+
return ret;
305+
}
306+
307+
static int symlink_dst(const char *path, const char *target)
308+
{
309+
int ret;
310+
311+
if (cptofs)
312+
ret = lkl_sys_symlink(target, path);
313+
else
314+
ret = symlink(target, path);
315+
316+
if (ret)
317+
fprintf(stderr, "unable to symlink '%s' with target '%s': %s\n",
318+
path, target, cptofs ? lkl_strerror(ret) :
319+
strerror(errno));
320+
321+
return ret;
322+
}
323+
324+
static int copy_symlink(const char *src, const char *dst)
325+
{
326+
int ret;
327+
int size;
328+
char *target = NULL;
329+
330+
ret = stat_src(src, NULL, NULL, &size);
331+
if (ret) {
332+
ret = -1;
333+
goto out;
334+
}
335+
336+
target = malloc(size + 1);
337+
if (!target) {
338+
fprintf(stderr, "Unable to allocate memory (%d bytes)\n",
339+
size + 1);
340+
ret = -1;
341+
goto out;
342+
}
343+
344+
ret = readlink_src(src, target, size);
345+
if (ret != size) {
346+
fprintf(stderr, "readlink(%s) bad size: got %d, expected %d\n",
347+
src, ret, size);
348+
ret = -1;
349+
goto out;
350+
}
351+
target[size] = 0; // readlink doesn't append the trailing null byte
352+
353+
ret = symlink_dst(dst, target);
354+
if (ret)
355+
ret = -1;
356+
357+
out:
358+
if (target)
359+
free(target);
360+
361+
return ret;
362+
}
363+
283364
static int do_entry(const char *_src, const char *_dst, const char *name)
284365
{
285366
char src[PATH_MAX], dst[PATH_MAX];
@@ -289,7 +370,7 @@ static int do_entry(const char *_src, const char *_dst, const char *name)
289370
snprintf(src, sizeof(src), "%s/%s", _src, name);
290371
snprintf(dst, sizeof(dst), "%s/%s", _dst, name);
291372

292-
ret = stat_src(src, &type, &mode);
373+
ret = stat_src(src, &type, &mode, NULL);
293374

294375
switch (type) {
295376
case S_IFREG:
@@ -304,6 +385,8 @@ static int do_entry(const char *_src, const char *_dst, const char *name)
304385
ret = searchdir(src, dst, NULL);
305386
break;
306387
case S_IFLNK:
388+
ret = copy_symlink(src, dst);
389+
break;
307390
case S_IFSOCK:
308391
case S_IFBLK:
309392
case S_IFCHR:

0 commit comments

Comments
 (0)