Skip to content

Commit 11cb89d

Browse files
committed
copy: re-create device nodes for fifo, character and block devices instead of copying them (thats typically bad idea) (fix #1907)
1 parent 339aa21 commit 11cb89d

File tree

5 files changed

+116
-4
lines changed

5 files changed

+116
-4
lines changed

WinPort/src/sudo/sudo_client_api.cpp

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -802,10 +802,10 @@ extern "C" __attribute__ ((visibility("default"))) int sdc_fsetxattr(int fd, con
802802
}
803803
return r;
804804
#endif
805-
}
805+
}
806806

807-
extern "C" __attribute__ ((visibility("default"))) int sdc_fs_flags_set(const char *path, unsigned long flags)
808-
{
807+
extern "C" __attribute__ ((visibility("default"))) int sdc_fs_flags_set(const char *path, unsigned long flags)
808+
{
809809
#if defined(__CYGWIN__) || defined(__HAIKU__)
810810
//TODO
811811
return 0;
@@ -842,7 +842,59 @@ extern "C" __attribute__ ((visibility("default"))) int sdc_fsetxattr(int fd, con
842842

843843
return r;
844844
#endif
845-
}
845+
}
846+
847+
extern "C" __attribute__ ((visibility("default"))) int sdc_mkfifo(const char *path, mode_t mode)
848+
{
849+
ClientReconstructCurDir crcd(path);
850+
int r = mkfifo(path, mode);
851+
if (r == 0 || !IsAccessDeniedErrno() || !TouchClientConnection(true)) {
852+
return r;
853+
}
854+
855+
try {
856+
ClientTransaction ct(SUDO_CMD_MKFIFO);
857+
ct.SendStr(path);
858+
ct.SendPOD(mode);
859+
860+
r = ct.RecvInt();
861+
if (r != 0)
862+
ct.RecvErrno();
863+
864+
} catch(std::exception &e) {
865+
fprintf(stderr, "sudo_client: sdc_mkfifo('%s', 0x%lx) - error %s\n",
866+
path, (unsigned long)mode, e.what());
867+
r = -1;
868+
}
869+
870+
return r;
871+
}
872+
873+
extern "C" __attribute__ ((visibility("default"))) int sdc_mknod(const char *path, mode_t mode, dev_t dev)
874+
{
875+
ClientReconstructCurDir crcd(path);
876+
int r = mknod(path, mode, dev);
877+
if (r == 0 || !IsAccessDeniedErrno() || !TouchClientConnection(true)) {
878+
return r;
879+
}
880+
881+
try {
882+
ClientTransaction ct(SUDO_CMD_MKNOD);
883+
ct.SendStr(path);
884+
ct.SendPOD(mode);
885+
ct.SendPOD(dev);
886+
887+
r = ct.RecvInt();
888+
if (r != 0)
889+
ct.RecvErrno();
890+
} catch(std::exception &e) {
891+
fprintf(stderr, "sudo_client: sdc_mknod('%s', 0x%lx, 0x%lx) - error %s\n",
892+
path, (unsigned long)mode, (unsigned long)dev, e.what());
893+
r = -1;
894+
}
895+
896+
return r;
897+
}
846898

847899

848900
} //namespace Sudo

WinPort/src/sudo/sudo_dispatcher.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,34 @@ namespace Sudo
342342
}
343343
bt.SendInt(r);
344344
}
345+
346+
static void OnSudoDispatch_MkFifo(BaseTransaction &bt)
347+
{
348+
std::string path;
349+
mode_t mode;
350+
bt.RecvStr(path);
351+
bt.RecvPOD(mode);
352+
int r = mkfifo(path.c_str(), mode);
353+
bt.SendInt(r);
354+
if (r != 0) {
355+
bt.SendErrno();
356+
}
357+
}
358+
359+
static void OnSudoDispatch_MkNod(BaseTransaction &bt)
360+
{
361+
std::string path;
362+
mode_t mode;
363+
dev_t dev;
364+
bt.RecvStr(path);
365+
bt.RecvPOD(mode);
366+
bt.RecvPOD(dev);
367+
int r = mknod(path.c_str(), mode, dev);
368+
bt.SendInt(r);
369+
if (r != 0) {
370+
bt.SendErrno();
371+
}
372+
}
345373

346374
void OnSudoDispatch(SudoCommand cmd, BaseTransaction &bt)
347375
{
@@ -449,6 +477,14 @@ namespace Sudo
449477
case SUDO_CMD_FCHMOD:
450478
OnSudoDispatch_FChMod(bt);
451479
break;
480+
481+
case SUDO_CMD_MKFIFO:
482+
OnSudoDispatch_MkFifo(bt);
483+
break;
484+
485+
case SUDO_CMD_MKNOD:
486+
OnSudoDispatch_MkNod(bt);
487+
break;
452488

453489
default:
454490
throw std::runtime_error("OnSudoDispatch - bad command");

WinPort/src/sudo/sudo_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ namespace Sudo
3838
SUDO_CMD_FSFLAGSGET,
3939
SUDO_CMD_FSFLAGSSET,
4040
SUDO_CMD_FCHMOD,
41+
SUDO_CMD_MKFIFO,
42+
SUDO_CMD_MKNOD
4143
};
4244

4345
class BaseTransaction

WinPort/sudo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ extern "C" {
7272
__attribute__ ((visibility("default"))) int sdc_fsetxattr(int fd, const char *name, const void *value, size_t size, int flags);
7373
__attribute__ ((visibility("default"))) int sdc_fs_flags_get(const char *path, unsigned long *flags);
7474
__attribute__ ((visibility("default"))) int sdc_fs_flags_set(const char *path, unsigned long flags);
75+
__attribute__ ((visibility("default"))) int sdc_mkfifo(const char *path, mode_t mode);
76+
__attribute__ ((visibility("default"))) int sdc_mknod(const char *path, mode_t mode, dev_t dev);
77+
7578
#ifdef __cplusplus
7679
}
7780

far2l/src/copy.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2764,6 +2764,15 @@ DWORD ShellFileTransfer::PieceWrite(const void *Data, DWORD Size)
27642764

27652765
/////////////////////////////////////////////////////////// END OF ShellFileTransfer
27662766

2767+
static dev_t GetRDev(FARString SrcName)
2768+
{
2769+
struct stat st{};
2770+
if (sdc_stat(SrcName.GetMB().c_str(), &st) == 0) {
2771+
return st.st_rdev;
2772+
}
2773+
return 0;
2774+
}
2775+
27672776
int ShellCopy::ShellCopyFile(const wchar_t *SrcName, const FAR_FIND_DATA_EX &SrcData, FARString &strDestName,
27682777
int Append)
27692778
{
@@ -2778,6 +2787,16 @@ int ShellCopy::ShellCopyFile(const wchar_t *SrcName, const FAR_FIND_DATA_EX &Src
27782787
return (MkSymLink(SrcName, strDestName, RPT, true) ? COPY_SUCCESS : COPY_FAILURE);
27792788
}
27802789
}
2790+
if (SrcData.dwFileAttributes & (FILE_ATTRIBUTE_DEVICE_FIFO | FILE_ATTRIBUTE_DEVICE_BLOCK | FILE_ATTRIBUTE_DEVICE_CHAR)) {
2791+
int r = (SrcData.dwFileAttributes & FILE_ATTRIBUTE_DEVICE_FIFO)
2792+
? sdc_mkfifo(strDestName.GetMB().c_str(), SrcData.dwUnixMode)
2793+
: sdc_mknod(strDestName.GetMB().c_str(), SrcData.dwUnixMode, GetRDev(SrcName));
2794+
if (r == -1) {
2795+
_localLastError = errno;
2796+
return COPY_FAILURE;
2797+
}
2798+
return COPY_SUCCESS;
2799+
}
27812800

27822801
try {
27832802
#if defined(COW_SUPPORTED) && defined(__APPLE__)

0 commit comments

Comments
 (0)