how to use mount function from c? - c++

I want to use mount function to implement NFS.
int mount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags,
const void *data);
I can implement it by using mount command e.g mount 172.16.0.144:/tmp/test /tmp/test. But when I use the mount() function , it doesn't work. This is my code here .
#include<sys/mount.h>
#include<iostream>
#include<errno.h>
#include<fstream>
#include<string.h>
using namespace std;
int main(int argc, char**argv) {
const char* srcPath = "/tmp/watchman";
const char* targetPath = "172.16.0.144:/tmp/watchman";
if (argc == 3) {
srcPath = argv[1];
targetPath = argv[2];
cerr << "reset the src && target path\n";
} else {
if (argc != 1) {
cerr << "wrong input argument!\n";
return 0;
}
}
cerr << "srcPath = " << srcPath << endl;
cerr << "target = " << targetPath << endl;
int ret_val = mount(srcPath, targetPath, "", MS_SHARED, "");
if (ret_val == 0) {
cerr << "mount succeed\n";
string filename = string(srcPath) + "/" + "tmp.txt";
fstream fin(filename.c_str(), ios::out);
fin << "there is a write test from client\n";
fin.close();
ret_val = umount(srcPath);
if (ret_val == 0) {
cerr << "umount succeed \n";
} else {
cerr << "umount failed \n";
printf("%s/n", strerror(errno));
}
} else {
cout<<"ret_val = "<<ret_val<<endl;
cerr << "mount failed \n";
cerr << strerror(errno) << endl;
}
return 0;
}
It printf mount failed,No such file or directory. anyone can help me? please !!!

If you read the mount manual page you will see that
mount() attaches the filesystem specified by source (which is often a pathname referring to a device, but can also be the pathname of a directory or file, or a dummy string) to the location (a directory or file) specified by the pathname in target.
You have switched the source and target in your application.

Related

c++ How to put path from command line argument to fprintf

I am having trouble figuring out how to take a path from the command line argument and having my program write to that folder using fprinf. For example: /here would write the file to the "here" folder with /here being the path from where the program is to where it needs to be written. Same for if the path were /there/here. This is just this section of my code:
void write_file(int sockfd, char* path)
{
int n;
FILE *fp;
char filename[] = "file1.txt";
char buffer[SIZE];
fp = fopen(filename, "w");
if (fp == NULL)
{
std::cerr << "ERROR: Could not write file.\n";
exit(EXIT_FAILURE);
}
while (1)
{
n = recv(sockfd, buffer, SIZE, 0);
if (n <= 0)
{
break;
return;
}
fprintf(fp, "%s", buffer);
bzero(buffer, SIZE);
}
fclose(fp);
return;
}
This code works but saves the file in my current folder. The variable "path" is the command line argument.
Edit: This is code that does not print lines to a file. Instead it copies lines from an existing file and puts those lines into the "file1.txt" file.
Here's an example using std::filesystem (C++17):
void write_file(int sockfd, const char* path)
{
auto filename = std::filesystem::path(path) / "file1.txt";
std::ofstream out{ filename, ios::trunc | ios::out };
if (!out) {
std::cerr << "ERROR: " << std::strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
char buffer[SIZE];
while (1)
{
int n = recv(sockfd, buffer, sizeof(buffer), 0);
if (n == 0)
{
break;
}
if (n < 0) {
std::cerr << "ERROR: " << std::strerror(errno) << "\n";
break;
}
if (!out.write(buffer, n)) {
std::cerr << "ERROR: " << std::strerror(errno) << "\n";
break;
}
}
}
If you don't have std::filesystem support, you can replace the first 2 statements with some manual path concatenation like:
std::string filename = path;
if (filename != "" && filename.back() != '/')
filename += '/';
filename += "file1.txt";

Segmentation fault: unable to fix the problem

I'm new to C++, and I'm trying to write a project that interacts through command line. Right now, whenever I run my main (which is the executable), I always receive a segmentation fault error when the main program finished.
Edit comment:
I'm told by tutor to use as little as C++ features such as vectors or strings ... I'm also very new to C++, so i'm trying to utilize as many basic C functions as I can.
I'm
My main function looks like this:
int main(int argc, char** argv) {
cout << "starting mvote..." << endl;
int run_flag = 1;
char* actionBuffer = (char*)malloc(100 * sizeof(char));
char* action = (char*)malloc(16 * sizeof(char));
char* readPtr;
char exit[4] = { 'e','x','i','t' };
//parse command line argumentand get the filename
char* filename = argv[2];
cout << filename;
FILE* fp;
char line[64];
//from here, I'm opening the file and read it by lines
fp = fopen(filename, "r");
if (fp == NULL) {
cout << "file not exists";
return -1;
}
while (fgets(line, 64, fp) != NULL) {
cout << line << "\n";
}
fclose(fp);
while (run_flag == 1) {
cout << "what do you want?\n " << endl;
cin.getline(actionBuffer, 1024);
if (strcmp(actionBuffer, exit) == 0) {
cout << "bye!";
run_flag = 0;
break;
}
//if not exit, Look for the space in the input
readPtr = strchr(actionBuffer, ' ');
int size = readPtr - actionBuffer;
//extract the operation
strncpy(action, actionBuffer, size);
for (int i = 0; i < size; i++) {
cout << "operation:" << action[i];
}
// depend on the operation specified before the first empty space
run_flag = 0;
}
free(actionBuffer);
free(action);
return 0;
}
Description:
I first try to open up a csv file which lies in the same folder as main, and I read the file line by line. Then, I just implement a simple command where you can type exit and quit the program.
I allocate two memory, actionBuffer and action, which are used to hold command
Problem: a segmentation fault [core dumped] always exists when I type exit and hit enter, and then the process finished.
Research: So I learned that segmentation fault is due to accessing a memory that does not belongs to me. But where in my program am I trying to access such a memory?
Any advice is appreciated! Thank you.
Just to give you an idea, this would be an example of C++ code
#include<iostream>
#include<fstream>
#include<string_view>
#include<string>
#include<sstream>
#include<exception>
int main(int argc, char** argv) {
std::cout << "starting mvote...\n";
//parse command line argumentand get the filename
std::string filename = argv[2]; // NO CHECKS!
std::cout << filename <<'\n';
//from here, I'm opening the file and read it by lines
{
std::ifstream ifs(filename);
if (!ifs) {
throw std::invalid_argument("file not exists");
}
std::string line;
while (std::getline(ifs, line)) {
std::cout << line << '\n';
}
}
bool run_flag = true;
while (run_flag) {
std::cout << "what do you want?\n";
std::string userInput;
std::getline(std::cin, userInput);
if (userInput == "exit") {
std::cout << "bye!\n";
return 0;
}
std::stringstream userInputSs(userInput);
std::string operation;
while(userInputSs >> operation){
std::cout << "operation: " << operation << '\n';
}
}
}

ifstream: /dev/stdin is not working the same as std::cin

For my formation, an exercise ask us to create a program similar to the linux 'cat' command.
So to read the file, i use an ifstream, and everything work fine for regular file.
But not when i try to open /dev/ files like /dev/stdin: the 'enter' is not detected and so, getline really exit only when the fd is being closed (with a CTRL-D).
The problem seems to be around how ifstream or getline handle reading, because with the regular 'read' function from libc, this problem is not to be seen.
Here is my code:
#include <iostream>
#include <string>
#include <fstream>
#include <errno.h>
#ifndef PROGRAM_NAME
# define PROGRAM_NAME "cato9tails"
#endif
int g_exitCode = 0;
void
displayErrno(std::string &file)
{
if (errno)
{
g_exitCode = 1;
std::cerr << PROGRAM_NAME << ": " << file << ": " << strerror(errno) << std::endl;
}
}
void
handleStream(std::string file, std::istream &stream)
{
std::string read;
stream.peek(); /* try to read: will set fail bit if it is a folder. */
if (!stream.good())
displayErrno(file);
while (stream.good())
{
std::getline(stream, read);
std::cout << read;
if (stream.eof())
break;
std::cout << std::endl;
}
}
int
main(int argc, char **argv)
{
if (argc == 1)
handleStream("", std::cin);
else
{
for (int index = 1; index < argc; index++)
{
errno = 0;
std::string file = std::string(argv[index]);
std::ifstream stream(file, std::ifstream::in);
if (stream.is_open())
{
handleStream(file, stream);
stream.close();
}
else
displayErrno(file);
}
}
return (g_exitCode);
}
We can only use method from libcpp.
I have search this problem for a long time, and i only find this post where they seems to have a very similar problem to me:
https://github.com/bigartm/bigartm/pull/258#issuecomment-128131871
But found no really usable solution from them.
I tried to do a very ugly solution but... well...:
bool
isUnixStdFile(std::string file)
{
return (file == "/dev/stdin" || file == "/dev/stdout" || file == "/dev/stderr"
|| file == "/dev/fd/0" || file == "/dev/fd/1" || file == "/dev/fd/2");
}
...
if (isUnixStdFile(file))
handleStream(file, std::cin);
else
{
std::ifstream stream(file, std::ifstream::in);
...
As you can see, a lot of files are missing, this can only be called a temporary solution.
Any help would be appreciated!
The following code worked for me to deal with /dev/fd files or when using shell substitute syntax:
std::ifstream stream(file_name);
std::cout << "Opening file '" << file_name << "'" << std::endl;
if (stream.fail() || !stream.good())
{
std::cout << "Error: Failed to open file '" << file_name << "'" << std::endl;
return false;
}
while (!stream.eof() && stream.good() && stream.peek() != EOF)
{
std::getline(stream, buffer);
std::cout << buffer << std::endl;
}
stream.close();
Basically std::getline() fails when content from the special file is not ready yet.

How To Fix C++ File Or Directory Program

In an effort to learn plain ansi C++, I am creating a console program that will hopefully
check to see if a file/folder exists.
Then differentiate between a file or a folder.
Count the number of lines in a file.
Recurse through all the files in a folder.
I don't want to include any libraries, just trying to get my head around basic c++ for the moment.
The problem I am having is with stage 2 of the application. I was struggling to find a way to tell if I had a file or directory, and after doing some reading I came across the library.
When the program calls the
checkIsDir()
function I get thrown an error
thread1 : EXEC_BAD_ACCESS(code = 1, address = 0x8)
I am presuming it is a memory problem, but I don't really have a hang of the basics with c++ never mind memory management. Here is my code
#include <iostream>
#include <fstream>
#include <dirent.h>
#include <sys/stat.h>
using namespace std;
bool checkIsDir(const char *fileData);
bool checkFileExists(const char *fileName, const char *directory);
int countTheNumberOfLines(const char *fileName);
int main(int argc, const char * argv[])
{
string directory, fileName;
while(fileName != "-1"){
cout << "Please enter your filename or enter -1 to quit:" << endl;
getline(cin, fileName);
cout << "Please enter your directory :" << endl;
getline(cin, directory);
if(checkFileExists(fileName.c_str(), directory.c_str())){
cout << fileName << " : exists" << endl;
if(checkIsDir(fileName.c_str())){ //code breaks when calling this function
cout << "==================| ";
cout << fileName << " is a Directory";
cout << " |==================";
}
if(checkIsDir(fileName.c_str())){
cout << fileName << " is a directory" << endl;
}
} else {
cout << fileName << " : not found";
cout << endl;
}
}
cout << "\nGoodbye";
return 0;
}
bool checkFileExists(const char *fileName, const char *directory){
const char* dirContent;
dirent* dirStruct;
DIR* dir;
dir = opendir(directory);
if(dir == NULL) return false;
while((dirStruct = readdir(dir))){
dirContent = dirStruct->d_name;
if(strcmp(fileName, dirContent) == 0){
closedir(dir);
return true;
}
}
closedir(dir);
return false;
}
bool checkIsDir(const char * fileData){
struct stat data;
struct dirent *file;
DIR *dir;
dir = opendir(fileData);
while((file = readdir(dir))){
stat(file->d_name, &data);
if(S_ISDIR(data.st_mode)){
closedir(dir);
return true;
} else {
closedir(dir);
return false;
}
}
closedir(dir);
return false;
}
int countTheLines(const char *fileName){
int lineNums = 0;
//implement
return lineNums;
}
StackExchange is the best place for hemp on the internet and I appreciate all the help that everyone gives.
Thanks in advance

debug assertion error

I've been scratching my head for quite some time now, this code worked fine when I first used cmd to go inside the project\debug folder then run the program there. Then I added the if(in) and else part then it started giving me "debug assertion failed" errors mbstowcs.c
Expression s != NULL
It just doesn't make any sense to me..
I used this command in cmd: prog.exe test.txt nuther.txt
Both files exists inside the debug folder and the main project folder..
Any ideas?
int main(int argc, char **argv)
{
parse_opts(argc, argv); //parse the arguments
return 0;
}
void parse_opts(int argc, char **argv)
{
string compl_out;
if( argc > 1 )
{
for( int i = 1; i < argc; i++ )
{
if( argv[i][0] = '>' )
{
ofstream out_file(argv[i+1]);
out_file << compl_out;
out_file.close();
break;
}
ifstream in(argv[i]);
string buff;
if(in)
{
while(getline( in, buff ))
cout << buff << endl;
compl_out.append(buff);
}
else
{
cout << "Can't open file: " << argv[i]
<< ", file doesn't exist or is locked in use. " << endl;
}
}
}
else
{
usage();
}
}
First impressions:
if( argv[i][0] = '>' )
should be:
if( argv[i][0] == '>' )
You are assigning instead of comparing.
I think you also might have intended the compl_out.append to be inside the while loop? As it is it won't append anying to that buffer:
while(getline( in, buff ))
{
cout << "buf" << buff << endl;
compl_out.append(buff);
}