handle errs properly in fs code without logic holes

This commit is contained in:
Carsten Haitzler 2024-04-30 14:46:11 +01:00
parent 9413ca2e62
commit f4b20c1fd8
1 changed files with 52 additions and 31 deletions

View File

@ -125,6 +125,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
mode_t old_umask; mode_t old_umask;
struct timeval times[2]; struct timeval times[2];
const char *op = ""; const char *op = "";
Eina_Strbuf *sbuf = NULL;
if (strlen(src) < 1) return EINA_FALSE; if (strlen(src) < 1) return EINA_FALSE;
@ -135,19 +136,25 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
else if (!rm && cp) op = "Copy"; else if (!rm && cp) op = "Copy";
else if (rm && !cp) op = "Delete"; else if (rm && !cp) op = "Delete";
old_umask = umask(0);
if (lstat(src, &st) != 0) if (lstat(src, &st) != 0)
{ {
switch (errno) switch (errno)
{ {
case ENOENT: // ignore this error - file removed during scan ? case ENOENT: // ignore this error - file removed during scan ?
status_pos(1, "Move - File vanished"); eina_strbuf_reset(sbuf);
break; eina_strbuf_append(sbuf, op);
eina_strbuf_append(sbuf, ": ");
eina_strbuf_append(sbuf, "File vanished");
status_pos(1, eina_strbuf_string_get(sbuf));
goto err;
default: default:
_error_handle(src, dst, op, errno); _error_handle(src, dst, op, errno);
return EINA_FALSE; res = EINA_FALSE;
goto err;
} }
} }
old_umask = umask(0); sbuf = eina_strbuf_new();
if (S_ISDIR(st.st_mode)) if (S_ISDIR(st.st_mode))
{ // it's a dir - scan this recursively { // it's a dir - scan this recursively
if (cp) if (cp)
@ -180,8 +187,8 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
eina_strbuf_append(buf, dst); eina_strbuf_append(buf, dst);
eina_strbuf_append(buf, "/"); eina_strbuf_append(buf, "/");
eina_strbuf_append(buf, fs); eina_strbuf_append(buf, fs);
if (!fs_cp_rm(s, eina_strbuf_string_get(buf), report_err, if (!fs_cp_rm(s, eina_strbuf_string_get(buf),
cp, rm)) report_err, cp, rm))
res = EINA_FALSE; res = EINA_FALSE;
} }
eina_strbuf_free(buf); eina_strbuf_free(buf);
@ -190,21 +197,6 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
} }
eina_iterator_free(it); eina_iterator_free(it);
} }
if ((rm) && (res))
{
if (rmdir(src) != 0)
{
switch (errno)
{
case ENOENT: // ignore missing
break;
default:
_error_handle(src, NULL, op, errno);
res = EINA_FALSE;
goto err;
}
}
}
} }
else if (S_ISLNK(st.st_mode)) else if (S_ISLNK(st.st_mode))
{ {
@ -217,16 +209,24 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
if ((lnsz > 0) && (lnsz < (ssize_t)sizeof(link))) if ((lnsz > 0) && (lnsz < (ssize_t)sizeof(link)))
{ {
if (symlink(link, dst) < 0) if (symlink(link, dst) < 0)
{ // XXX: soft error? e.g. mv on FAT fs? { // soft error? e.g. mv on FAT fs? report but move on
status_pos(1, "Move - Error creating symlink"); eina_strbuf_reset(sbuf);
eina_strbuf_append(sbuf, op);
eina_strbuf_append(sbuf, ": ");
eina_strbuf_append(sbuf, "Error creating symlink");
status_pos(1, eina_strbuf_string_get(sbuf));
} }
} }
else if (lnsz < 0) else if (lnsz < 0)
{ // XXX: handle read link err {
switch (errno) switch (errno)
{ {
case ENOENT: // ignore this error - file removed during scan ? case ENOENT: // ignore this error - file removed during scan ?
status_pos(1, "Move - File vanished"); eina_strbuf_reset(sbuf);
eina_strbuf_append(sbuf, op);
eina_strbuf_append(sbuf, ": ");
eina_strbuf_append(sbuf, "File vanished");
status_pos(1, eina_strbuf_string_get(sbuf));
break; break;
default: default:
_error_handle(src, dst, op, errno); _error_handle(src, dst, op, errno);
@ -234,7 +234,12 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
} }
} }
else // 0 sized symlink ... WAT? else // 0 sized symlink ... WAT?
{ // XXX: handle this {
eina_strbuf_reset(sbuf);
eina_strbuf_append(sbuf, op);
eina_strbuf_append(sbuf, ": ");
eina_strbuf_append(sbuf, "Zero sized symlink");
status_error(src, NULL, eina_strbuf_string_get(sbuf));
} }
} }
} }
@ -243,7 +248,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
if (cp) if (cp)
{ {
if (mkfifo(dst, st.st_mode) < 0) if (mkfifo(dst, st.st_mode) < 0)
{ // XXX: soft error? ignore? { // soft error? ignore?
} }
} }
} }
@ -259,7 +264,7 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
if (cp) if (cp)
{ {
if (mknod(dst, st.st_mode, st.st_dev) < 0) if (mknod(dst, st.st_mode, st.st_dev) < 0)
{ // XXX: soft error? ignore? { // soft error? ignore?
} }
} }
} }
@ -361,8 +366,23 @@ err_copy:
if (fd_in >= 0) close(fd_in); if (fd_in >= 0) close(fd_in);
if (fd_ou >= 0) close(fd_ou); if (fd_ou >= 0) close(fd_ou);
} }
if ((rm) && (res)) }
if ((rm) && (res))
{
if (S_ISDIR(st.st_mode))
{ {
if (rmdir(src) != 0)
{
switch (errno)
{
case ENOENT: // ignore missing
break;
default:
_error_handle(src, NULL, op, errno);
res = EINA_FALSE;
goto err;
}
}
if (unlink(src) != 0) if (unlink(src) != 0)
{ {
switch (errno) switch (errno)
@ -378,7 +398,7 @@ err_copy:
} }
} }
err_unlink: err_unlink:
chown(dst, st.st_uid, st.st_gid); chown(dst, st.st_uid, st.st_gid); // ignore err
#ifdef STAT_NSEC #ifdef STAT_NSEC
#ifdef st_mtime #ifdef st_mtime
#define STAT_NSEC_ATIME(st) (unsigned long long)((st)->st_atim.tv_nsec) #define STAT_NSEC_ATIME(st) (unsigned long long)((st)->st_atim.tv_nsec)
@ -398,9 +418,10 @@ err_unlink:
times[0].tv_usec = STAT_NSEC_ATIME(st) * 1000; times[0].tv_usec = STAT_NSEC_ATIME(st) * 1000;
times[1].tv_sec = st.st_mtime; times[1].tv_sec = st.st_mtime;
times[1].tv_usec = STAT_NSEC_MTIME(st) * 1000; times[1].tv_usec = STAT_NSEC_MTIME(st) * 1000;
utimes(dst, times); utimes(dst, times); // ingore err
err: err:
umask(old_umask); umask(old_umask);
if (sbuf) eina_strbuf_free(sbuf);
return res; return res;
} }