Reputation: 23
I am transferring a file from Linux to windows using library libssh in SFTP mode using C++ on Windows.
I am able to create a file on Windows side and write in it for once using this program:
int sftp_read_sync(ssh_session session, sftp_session sftp)
{
int access_type;
sftp_file file;
char* buffer[MAX_XFER_BUF_SIZE];
int nbytes, nwritten, rc;
int fd;
access_type = O_RDONLY;
file = sftp_open(sftp, "/root/bel1.txt",
access_type, 0);
if (file == NULL) {
fprintf(stderr, "Can't open file for reading: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
fd = open("C:\\Users\\Wipro\\Desktop\\bel6.txt", O_WRONLY | O_CREAT | O_TRUNC);
if (fd < 0) {
fprintf(stderr, "Can't open file for writing: %s\n",
strerror(errno));
return SSH_ERROR;
}
for (;;) {
nbytes = sftp_read(file, buffer, sizeof(buffer));
if (nbytes == 0) {
break; // EOF
} else if (nbytes < 0) {
fprintf(stderr, "Error while reading file: %s\n",
ssh_get_error(session));
sftp_close(file);
return SSH_ERROR;
}
nwritten = write(fd, buffer, nbytes);
if (nwritten != nbytes) {
fprintf(stderr, "Error writing: %s\n",
strerror(errno));
sftp_close(file);
return SSH_ERROR;
}
}
rc = sftp_close(file);
if (rc != SSH_OK) {
fprintf(stderr, "Can't close the read file: %s\n",
ssh_get_error(session));
return rc;
}
return SSH_OK;
}
On running this same program again, I'm getting an error:
Can't open file for writing: Permission denied
The file created is not having a permission to rewrite in it.
How can I correct this?
Upvotes: 2
Views: 3073
Reputation: 2482
On Windows, open() is deprecated and you should use _open() or, even preferred, _sopen_s() instead.
_open() has an optional parameter "int pmode" which allows you to set file permissions:
int _open(
const char *filename,
int oflag [,
int pmode]
);
For pmode, you can specify
_S_IREAD
Only reading permitted.
_S_IWRITE
Writing permitted. (In effect, permits reading and writing.)
_S_IREAD | _S_IWRITE
Reading and writing permitted.
So just replace your statement
fd = open("C:\\Users\\Wipro\\Desktop\\bel6.txt", O_WRONLY | O_CREAT | O_TRUNC);
with
fd = _open("C:\\Users\\Wipro\\Desktop\\bel6.txt", O_WRONLY | O_CREAT | O_TRUNC, _S_IREAD | _S_IWRITE);
and you should be fine. See https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx for further details.
Since you are on Windows, you can also use _sopen_s() instead of open(). _sopen_s() also allows to specify file permissions. Its API is different and looks like
errno_t _sopen_s(
int* pfh,
const char *filename,
int oflag,
int shflag,
int pmode
);
According to https://msdn.microsoft.com/en-us/library/w64k0ytk.aspx, the parameters are
[out] pfh
The file handle, or -1 in the case of an error.
[in] filename
File name.
[in] oflag
The kind of operations allowed.
[in] shflag
The kind of sharing allowed.
[in] pmode
Permission setting.
So you can replace your statement
fd = open("C:\\Users\\Wipro\\Desktop\\bel6.txt", O_WRONLY | O_CREAT | O_TRUNC);
with
int fd;
int err = _sopen_s( &fd, "C:\\Users\\Wipro\\Desktop\\bel6.txt", O_WRONLY | O_CREAT | O_TRUNC, _SH_DENYNO, _S_IREAD | _S_IWRITE );
if (err) {
fprintf( stderr, "Can't open file for writing: %s\n",
strerror( errno ) );
return errno;
}
Other possible values for the paramerers are documented meticulously at https://msdn.microsoft.com/en-us/library/w64k0ytk.aspx .
At the end, no matter whether you use _open() or _sopen_s(), you should still close your file (it is then, when the file permissions are set):
_close( fh );
Finally, you will need the following headers:
#include <io.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream>
#include <sys/stat.h>
#include <errno.h>
Upvotes: 1
Reputation: 202232
You have to close the file handle, once you finish writing:
close(fd);
When you do not close the handle, the file is kept locked by the process, until the process exits and no other process can write the file meanwhile.
Upvotes: 5