Why doesn't ls -al show message queue created by mq_open [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I use mq_open to create message queue /temp.1234,
but command ls -al and ipcs -qin directory / doesn't show any information about the message queue.
I use mq_send to send a message. Also, in another program, mq_open("/temp.1234", O_WRONLY) returns 3(message descriptor) succesfully, but when calling mq_receive, it outputs EBADF. OS is ubuntu.
Is it only effective on solaris rather than ubuntu?
Added:
it's from unix network programing volume 2.
Here is the output under Solaris 2.6:
solaris % mqcreatel /temp.l234
solaris % 1s -1 /tmp/.*l234
-rw-rw-rw- 1 rstevens otherl 132632 Oct 23 17:08 /tmp/.MQDtemp.1234
-rw-rw-rw- 1 rstevens other1
0 Oct 23 17:08 /tmp/.MQLtemp.l234
-rw-r--r--
1 rstevens other1
0 Oct 23 17:08 /tmp/.MQPtemp.l234

The first argument is not a filename, it is an identifier only. It will not exist on the filesystem.
Attempting to receive from a write-only queue is an error.

Related

Permission denied when opening a file written using C [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I was doing some simple exercices with file descriptors with the following code:
int main(int argc, char *argv[]){
int fd1 = open("etc/passwd", O_RDONLY);
int fd2 = open("output.txt", O_CREAT,O_TRUNC,O_WRONLY);
dup2(fd1,0);
close(fd1);
dup2(fd2,1);
close(fd2);
}
Whenever I try to open the "output.txt" i get the following error:
Unable to open 'output.txt': Unable to read file '/home/joao/Desktop/Exercicios/output.txt' (NoPermissions (FileSystemError): Error: EACCES: permission denied, open '/home/joao/Desktop/Exercicios/output.txt').
Even though I believe some of the error refers to VSCode, I'm unable to open the file anywhere. Here is what I get when executing "ls -l" on the folder that has the .c file, the executable and the "output.txt":
---------T 1 joao joao 0 jun 9 21:54 output.txt
-rwxrwxr-x 1 joao joao 16784 jun 9 21:54 test
-rw-rw-r-- 1 700 joao 387 jun 9 21:54 teste.c
How can I fix this?
This:
int fd2 = open("output.txt", O_CREAT,O_TRUNC,O_WRONLY);
is not right. All the flags go in the second argument, combined with bitwise or, and the third is for the "mode", i.e. the access rights. See the manual page for much more details, of course.
So, it should be:
const int fd2 = open("output.txt", O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU);
this will open with the mode S_IRWXU, i.e. permissions are granted to read/write/execute for the owner only.

Implement sudo su in a C program [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 years ago.
Improve this question
I writing a program that is used by a parent process. I cannot control the parent process, its permissions, and how it runs my process.
My program runs a device that needs root permissions, while the parent process does not have the corresponding permissions.
Tried to use setuid(0); setgid(0); in my program. Also, tried to add the user of the process to use sudo. In addition, I run the solutions below. Does not works
The code
if(dry_run == 0)
{
PRINT("reached here\n");
ret = ioctl((int64_t)device, NVME_IOCTL, &usr_io_cmd);
}
if (ret != 0 ) {
PRINT("ERROR : error %x returned\n", ret);
PRINT( "%s\n",strerror(errno) );
Where PRINT prints to a log file.
The log file
[2019-09-05 14:27:25] reached here
[2019-09-05 14:27:25] ERROR : error ffffffff returned
[2019-09-05 14:27:25] Operation not permitted
What can my program do? How can I implement "sudo su" in my program? Is there an alternative solution?
Edit: why this question is locked? I tried the solutions below and it did not worked.
What you need to do is to have your program have the setuid or setgid bit set in the file permissions. This will cause the running process to have the effective user id of that of the program owner (setuid) or effective gid that of the program group (gid). You then can perform actions as those identities or become those with setuid and setgid.
sudo su is a cargo-cult way of doing things - both are programs that more or less do the same thing - elevate permissions of an unprivileged caller.
I.e. to have the program foo owned by root with setuid bit set, you'd do:
gcc foo.c -o foo
sudo chown root:root foo
sudo chmod 4755 foo

File IO unit test in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I need to write unit tests for a simple logger implemented in C (unit tests are in c++).
I'm searching for a way to mock an unsuccessful 'write' to the log file ,in order to see that the logger to responds appropriately and returns an error.
I tried renaming the log-file before writing on to it:
static bool fileWriteMiss() {
const char* testFile = "missLogFile.log";
const char* movedFile = "missedLogFile.log";
ASSERT_TRUE(
spLoggerCreate(testFile, SP_LOGGER_DEBUG_INFO_WARNING_ERROR_LEVEL) ==
SP_LOGGER_SUCCESS);
rename(testFile, movedFile);
ASSERT_TRUE(spLoggerPrintError("MSGA", "sp_logger_unit_test.c", __func__,
__LINE__) == SP_LOGGER_WRITE_FAIL);
spLoggerDestroy();
return true;
}
and I tried deleting the log-file before writing on to it:
static bool fileWriteMiss() {
const char* testFile = "missLogFile.log";
ASSERT_TRUE(
spLoggerCreate(testFile, SP_LOGGER_DEBUG_INFO_WARNING_ERROR_LEVEL) ==
SP_LOGGER_SUCCESS);
remove(testFile);
ASSERT_TRUE(spLoggerPrintError("MSGA", "sp_logger_unit_test.c", __func__,
__LINE__) == SP_LOGGER_WRITE_FAIL);
spLoggerDestroy();
return true;
}
ASSERT_TRUE function is implemented in an assertion library that is assumed to work properly.
spLoggerCreate is the initialization function of the logger structure (I'm being careful not to call it construction and object since the implementation is not oop, but pure C code).
A working hack is to write to file that you cannot write to (please note that you can write to non-existent file in an existing directory - it would be created). There are few ways, some os-dependent:
write to a file in non-existing directory. While it is complicated in a generic case, you can use some tricks like using chars unlikely to meet in a filename, like '\x01'.
const char* testFile = "non-existent\x01dir/missLogFile.log";
write to a file you have no rights to write to. In UNIX you can issue
chmod a-w file.log
command on an existing file to revoke write permission.
write to a system read-only pseudo-file.
const char* testFile = "/proc/uptime"; // linux
const char* testFile = "CLOCK$"; // windows / dos
I believe unit-tests should never access OS, and your test becomes non-unit this way, but this is a terminology question and a holy war subject.
Update:
Your comment actually makes it a poorly asked but pretty interesting question. I think you can edit it and I will try to answer. As things go hacky here, I'll focus on Linux only, answering the question
"How to make file open-for-write succeed, but subsequent write fail?"
Probably the most common error real application face is "No space left on device". This is easy to reproduce in hermetic way: let us create a fat16 filesystem in local file, precisely:
$ dd if=/dev/urandom of=test_disk bs=1048576 count=1
$ mkdosfs test_disk
$ mkdir /tmp/mnt
$ sudo mount -o loop,rw,umask=000 test_disk /tmp/mnt/
Now fill the filesystem. Alternatively we could use smaller size.
$ perl -e 'print "a"x(1024*1002)' > /tmp/mnt/a.txt
$ echo test > /tmp/mnt/test || echo "can't write test file"
And finally hit the error:
$ echo `perl -e 'print "a"x4096'` > /tmp/mnt/test || echo "test succeeded"
bash: echo: write error: No space left on device
test succeeded
To be precise the error is encountered writing byte 1009:
$ ls -l /tmp/mnt/
total 1004
-rwxrwxrwx 1 root root 1026048 Mar 27 17:56 a.txt
-rwxrwxrwx 1 root root 1009 Mar 27 17:57 test
A nice side effect of FAT filesystem is that now you are free to open more files there and write will fail from byte 0, as you asked.

How to fix btrfs root inode errors [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 5 years ago.
Improve this question
Running btrfsck, or more officially, btrfs check --repair gives this output stating that there are root inode errors. The repair command does not fix the issue and reruns will display the same output. The system is fully mountable and operational, but I cannot perform advanced operations on the partition (resizing).
sudo btrfs check --repair /dev/sda9
enabling repair mode
Checking filesystem on /dev/sda9
UUID: 82fca3c2-703b-4fae-aec2-6b7df1be71c1
checking extents
Fixed 0 roots.
checking free space cache
cache and super generation don't match, space cache will be invalidated
checking fs roots
root 257 inode 452001 errors 400, nbytes wrong
root 257 inode 452004 errors 400, nbytes wrong
root 257 inode 452005 errors 400, nbytes wrong
root 257 inode 452006 errors 400, nbytes wrong
root 257 inode 452010 errors 400, nbytes wrong
root 257 inode 452011 errors 400, nbytes wrong
root 257 inode 452012 errors 400, nbytes wrong
root 257 inode 1666032 errors 400, nbytes wrong
checking csums
checking root refs
found 33957216263 bytes used err is 0
total csum bytes: 32206988
total tree bytes: 968933376
total fs tree bytes: 886636544
total extent tree bytes: 35323904
btree space waste bytes: 199109273
file data blocks allocated: 41090113536
referenced 32584159232
btrfs-progs v4.0.1
Provided that the broken inodes are the only problem present, the solution is to simply remove them. There may be a quicker way to do this, but here is what worked for me. From here I gleaned that you can use the find command to search for an inode like so:
find / -inum XXXXXX -print
of course giving it the inode in question from the btrfsck command. It will show you the offending file and you can delete it. When all have been removed, btrfsck will be clear and the system will function normally.

How can I determine what stdout "points" to in C?

I want to be able to tell when my program's stdout is redirected to a file/device, and when it is left to print normally on the screen. How can this be done in C?
Update 1: From the comments, it seems to be system dependent. If so, then how can this be done with posix-compliant systems?
Perhaps isatty(stdout)?
Edit: As Roland and tripleee suggest, a better answer would be isatty(STDOUT_FILENO).
Look up isatty and more generally fileno.
I am afraid that you can't, at least with standard C in a platform independent manner. The idea behind standard input/output is that C will do it's IO from a standard place. That standard place could be a terminal or a file or anything else, that is not the consideration of C. So you can't detect what is standard IO currently used.
EDIT: If a platform specific solution is okay for you then please refer to other answers (and also edit the question accordingly).
If a Linux-specific solution is OK, you can examine the symlinks under the /proc directory for your process. E.g.,
$ exec 3>/dev/null
$ ls -l /proc/$$/fd
total 0
lrwx------ 1 root root 64 Sep 12 03:28 0 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 12 03:29 1 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 12 03:29 2 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 12 03:29 255 -> /dev/pts/1
l-wx------ 1 root root 64 Sep 12 03:29 3 -> /dev/null
You might want to check this out:
http://www.cplusplus.com/reference/clibrary/cstdio/freopen/
I'm quoting from the link:
freopen
Reopen stream with different file or mode
freopen first tries to close any file already associated with the stream given as third parameter and disassociates it.
Then, whether that stream was successfuly closed or not, freopen opens the file whose name is passed in the first parameter, filename, and associates it with the specified stream just as fopen would do using the mode value specified as the second parameter.
This function is specially useful for redirecting predefined streams like stdin, stdout and stderr to specific files.
Though I'm not sure if this'll help you find out what it is pointing to in the first place.

Resources