How to get out of input in Linux console - linux

I have written a program that asks for user input in a loop and only terminates when exit was entered. However, there seems to be a bug in my program so that I can never exit. Is there a Linux shortcut that lets me exit the program even when I am in the user input? I am running Linux in Oracle Virtualbox on a Windows 10 Laptop.
I think the reason might be fgets. Now, using fflush() "test" is printed, but after this the command line expects input again. The function "parse" is specified in the function parser.c but this should not be of relevance for this question.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "parser.c"
int main()
{
//Ausgabe des "$"
write(1, "$", 1);
//Auf Eingabe des Nutzers warten:
char *input=malloc(1024*sizeof(char));
fgets(input, 1023, stdin);
fflush(stdout);
printf("%s", "test", 5);
parse(input);
return 0;
}
Thank you very much for your answer.

Related

Cygwin FIFO vs native Linux FIFO - discrepancy in blocking behaviour?

The code shown is based on an example using named pipes from some tutorial site
server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define FIFO_FILE "MYFIFO"
int main()
{
int fd;
char readbuf[80];
int read_bytes;
// mknod(FIFO_FILE, S_IFIFO|0640, 0);
mkfifo(FIFO_FILE, 0777);
while(1) {
fd = open(FIFO_FILE, O_RDONLY);
read_bytes = read(fd, readbuf, sizeof(readbuf));
readbuf[read_bytes] = '\0';
printf("Received string: \"%s\". Length is %d\n", readbuf, (int)strlen(readbuf));
}
return 0;
}
When executing the server in Windows, using Cygwin, then the server enters an undesired loop, repeating the same message. For example, if you write in a shell:
$ ./server
|
then the "server" waits for the client, but when the FIFO is not empty, e.g. writing in a new shell
$ echo "Hello" > MYFIFO
then the server enters an infinite loop, repeating the "Hello"-string
Received string: "Hello". Length is 4
Received string: "Hello". Length is 4
...
Furthermore, new strings written to the fifo doesn't seem to be read by the server. However, in Linux the behaviour is quite different. In Linux, the server prints the string and waits for new data to appear on the fifo. What is the reason for this discrepancy ?
You need to fix your code to remove at least 3 bugs:
You're not doing a close(fd) so you will get a file descriptor leak and eventually be unable to open() new files.
You're not checking the value of fd (if it returns -1 then there was an error).
You're not checking the value of read (if it returns -1 then there was an error)... and your readbuf[read_bytes] = '\0'; will not be doing what you expect as a result.
When you get an error then errno will tell you what went wrong.
These bugs probably explain why you keep getting Hello output (especially the readbuf[read_bytes] problem).

bus error with mmap

I get bus error (core dumped) when trying to write to memory. I want to write to a binary file using mmap() and open() functions in Linux. I want to write integers from 1 to 100 in the binary file by mapping it to memory instead of writing to the file directly.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#define FILE_SIZE 0x100
int main(int argc,char *argv[])
{
int fd;
void *pmap;
printf("im here");
//fd=open(argv[1],O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);
fd=open("numbers.raw",O_RDWR);
if(fd == -1)
{
perror("open");
exit(1);
}
lseek(fd,FILE_SIZE+1,SEEK_SET); //checking the file length
lseek(fd,0,SEEK_SET);//points to start of the file
//create the memory mapping
pmap = mmap(0,FILE_SIZE,PROT_WRITE,MAP_SHARED,fd,0);
if(pmap == MAP_FAILED)
{
perror("mmap") ;
close(fd);
exit(1);
}
close(fd);
for(int i=1;i<=100;i++)
sprintf(pmap,"%d",i);
return 0;
}
Your comment says you are "checking the file length" but you never check the return value of that call. I'd bet it is failing since your file is not large enough, hence the bus error later.
There are multiple other unrelated mistakes in your file as well, by
the way:
Your file size assumes 0x100 bytes are enough to store 100 integers in binary. This is not the case for 64 bit systems.
You aren't actually storing binary numbers - you are storing strings of the numbers.
You aren't advancing where you write, so you write all the numbers at the start of the file, one on top of the other.

Ptrace reset a breakpoint

I am having trouble resetting a process after I have hit a breakpoint with Ptrace. I am essentially wrapping this code in python.
I am running this on 64 bit Ubuntu.
I understand the concept of resetting the data at the location and decrementing the instruction pointer, but after I get the trap signal and do that, my process is not finishing.
Code snippet:
# Continue to bp
res = libc.ptrace(PTRACE_CONT,pid,0,0)
libc.wait(byref(wait_status))
if _wifstopped(wait_status):
print('Breakpoint hit. Signal: %s' % (strsignal(_wstopsig(wait_status))))
else:
print('Error process failed to stop')
exit(1)
# Reset Instruction pointer
data = get_registers(pid)
print_rip(data)
data.rip -= 1
res = set_registers(pid,data)
# Verify rip
print_rip(get_registers(pid))
# Reset Instruction
out = set_text(pid,c_ulonglong(addr),c_ulonglong(initial_data))
if out != 0:
print_errno()
print_text(c_ulonglong(addr),c_ulonglong(get_text(c_void_p(addr))))
And I run a PTRACE_DETACH right after returning from this code.
When I run this, it hits the breakpoint the parent process returns successfully, but the child does not resume and finish its code.
If I comment out the call to the breakpoint function it just attaches ptrace to the process and then detaches it, and the program runs fine.
The program itself is just a small c program that prints 10 times to a file.
Full code is in this paste
Is there an error anyone sees with my breakpoint code?
I ended up writing a C program that was as exact a duplicate of the python code as possible:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/reg.h>
#include <sys/user.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
void set_unset_bp(pid){
int wait_status;
struct user_regs_struct regs;
unsigned long long addr = 0x0000000000400710;
unsigned long long data = ptrace(PTRACE_PEEKTEXT,pid,(void *)addr,0);
printf("Orig data: 0x%016x\n",data);
unsigned long long trap = (data & 0xFFFFFFFFFFFFFF00) | 0xCC;
ptrace(PTRACE_POKETEXT,pid,(void *)addr,(void *)trap);
ptrace(PTRACE_CONT,pid,0,0);
wait(&wait_status);
if(WIFSTOPPED(wait_status)){
printf("Signal recieved: %s\n",strsignal(WSTOPSIG(wait_status)));
}else{
perror("wait");
}
ptrace(PTRACE_POKETEXT,pid,(void *)addr,(void *)data);
ptrace(PTRACE_GETREGS,pid,0,&regs);
regs.rip -=1;
ptrace(PTRACE_SETREGS,pid,0,&regs);
data = ptrace(PTRACE_PEEKTEXT,pid,(void *)addr,0);
printf("Data after resetting bp data: 0x%016x\n",data);
ptrace(PTRACE_CONT,pid,0,0);
}
int main(void){
//Fork child process
extern int errno;
int pid = fork();
if(pid ==0){//Child
ptrace(PTRACE_TRACEME,0,0,0);
int out = execl("/home/chris/workspace/eliben-debugger/print","/home/chris/workspace/eliben-debugger/print",0);
if(out != 0){
printf("Error Value is: %s\n", strerror(errno));
}
}else{ //Parent
wait(0);
printf("Got stop signal, we just execv'd\n");
set_unset_bp(pid);
printf("Finished setting and unsetting\n");
wait(0);
printf("Got signal, detaching\n");
ptrace(PTRACE_DETACH,pid,0,0);
wait(0);
printf("Parent exiting after waiting for child to finish\n");
}
exit(0);
}
After comparing the output to my Python output I noticed that according to python my original data was 0xfffffffffffe4be8 and 0x00000000fffe4be8.
This lead me to believe that my return data was getting truncated to a 32 bit value.
I changed my get and set methods to something like this, setting the return type to a void pointer:
def get_text(addr):
restype = libc.ptrace.restype
libc.ptrace.restype = c_void_p
out = libc.ptrace(PTRACE_PEEKTEXT,pid,addr, 0)
libc.ptrace.restype = restype
return out
def set_text(pid,addr,data):
return libc.ptrace(PTRACE_POKETEXT,pid,addr,data)
Can't tell you how it works yet, but I was able to get the child process executing successfully after the trap.

Ordering file location on linux partition

I have a process which processes a lot of files (~96,000 files, ~12 TB data). Several runs of the process has left the files scattered about the drive. Each iteration in the process, uses several files. This leads to a lot of whipsawing around the disk collecting the files.
Ideally, I would like the process to write the files it uses in order, so that the next run will read them in order (file sizes change). Is there a way to hint at a physical ordering/grouping, short of writing to the raw partition?
Any other suggestions would be helpful.
Thanks
There are two system calls you might lookup: fadvise64, fallocate tell the kernel how you intend to read or write a given file.
Another tip is the "Orlov block allocator" (Wikipedia, LWN) affects the way the kernel will allocate new directories and file-entries.
In the end I decided not to worry about writing the files in any particular ordering. Instead, before I started a run, I would figure out where the first block of each file was located, and then sort the file processing order by first block location. Not perfect, but it did make a big difference in processing times.
Here's the C code I used to get the first block of supplied file list I adapted it from example code I found online (can't seem to find the original source).
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <linux/fs.h>
//
// Get the first block for each file passed to stdin,
// write filename & first block for each file to stdout
//
int main(int argc, char **argv) {
int fd;
int block;
char fname[512];
while(fgets(fname, 511, stdin) != NULL) {
fname[strlen(fname) - 1] = '\0';
assert(fd=open(fname, O_RDONLY));
block = 0;
if (ioctl(fd, FIBMAP, &block)) {
printf("FIBMAP ioctl failed - errno: %s\n", strerror(errno));
}
printf("%010d, %s\n", block, fname);
close(fd);
}
return 0;
}

What is a good Linux exit error code strategy?

I have several independent executable Perl, PHP CLI scripts and C++ programs for which I need to develop an exit error code strategy. These programs are called by other programs using a wrapper class I created to use exec() in PHP. So, I will be able to get an error code back. Based on that error code, the calling script will need to do something.
I have done a little bit of research and it seems like anything in the 1-254 (or maybe just 1-127) range could be fair game to user-defined error codes.
I was just wondering how other people have approached error handling in this situation.
The only convention is that you return 0 for success, and something other than zero for an error. Most well-known unix programs document the various return codes that they can return, and so should you. It doesn't make a lot of sense to try to make a common list for all possible error codes that any arbitrary program could return, or else you end up with tens of thousands of them like some other OS's, and even then, it doesn't always cover the specific type of error you want to return.
So just be consistent, and be sure to document whatever scheme you decide to use.
1-127 is the available range. Anything over 127 is supposed to be "abnormal" exit - terminated by a signal.
While you're at it, consider using stdout rather than exit code. Exit code is by tradition used to indicate success, failure, and may be one other state. Rather than using exit code, try using stdout the way expr and wc use it. You can then use backtick or something similar in the caller to extract the result.
the unix manifesto states -
Exit as soon and as loud as possible on error
or something like that
Don't try to encode too much meaning into the exit value: detailed statuses and error reports should go to stdout / stderr as Arkadiy suggests.
However, I have found it very useful to represent just a handful of states in the exit values, using binary digits to encode them. For example, suppose you have the following contrived meanings:
0000 : 0 (no error)
0001 : 1 (error)
0010 : 2 (I/O error)
0100 : 4 (user input error)
1000 : 8 (permission error)
Then, a user input error would have a return value of 5 (4 + 1), while a log file not having write permission might have a return value of 11 (8 + 2 + 1). As the different meanings are independently encoded in the return value, you can easily see what's happened by checking which bits are set.
As a special case, to see if there was an error you can AND the return code with 1.
By doing this, you can encode a couple of different things in the return code, in a clear and simple way. I use this only to make simple decisions such as "should the process be restarted", "do the return value and relevant logs need to be sent to an admin", that sort of thing. Any detailed diagnostic information should go to logs or to stdout / stderr.
The normal exit statuses run from 0 to 255 (see Exit codes bigger than 255 posssible for a discussion of why). Normally, status 0 indicates success; anything else is an implementation-defined error. I do know of a program that reports the state of a DBMS server via the exit status; that is a special case of implementation-defined exit statuses. Note that you get to define the implementation of the statuses of your programs.
I couldn't fit this into 300 characters; otherwise it would have been a comment to #Arkadiy's answer.
Arkadiy is right that in one part of the exit status word, values other than zero indicate the signal that terminated the process and the 8th bit normally indicates a core dump, but that section of the exit status is different from the main 0..255 status. However, the shell (whichever shell it is) is presented with a problem when a process dies as a result of a signal. There is 16 bits of data to be presented in an 8-bit value, which is always tricky. What the shells seem to do is to take the signal number and add 128 to it. So, if a process dies as a result of an interrupt (signal number 2, SIGINT), the shell reports the exit status as 130. However, the kernel reported the status as 0x0002; the shell has modified what the kernel reports.
The following C code demonstrates this. There are two programs
suicide which kills itself using a signal of your choosing (interrupt by default).
exitstatus which runs a command (such as suicide) and reports the kernel exit status.
Here's suicide.c:
/*
#(#)File: $RCSfile: suicide.c,v $
#(#)Version: $Revision: 1.2 $
#(#)Last changed: $Date: 2008/12/28 03:45:18 $
#(#)Purpose: Commit suicide using kill()
#(#)Author: J Leffler
#(#)Copyright: (C) JLSS 2008
#(#)Product: :PRODUCT:
*/
/*TABSTOP=4*/
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 500
#endif /* __STDC_VERSION__ */
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "stderr.h"
static const char usestr[] = "[-V][-s signal]";
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
extern const char jlss_id_suicide_c[];
const char jlss_id_suicide_c[] = "#(#)$Id: suicide.c,v 1.2 2008/12/28 03:45:18 jleffler Exp $";
#endif /* lint */
int main(int argc, char **argv)
{
int signum = SIGINT;
int opt;
char *end;
err_setarg0(argv[0]);
while ((opt = getopt(argc, argv, "Vs:")) != -1)
{
switch (opt)
{
case 's':
signum = strtol(optarg, &end, 0);
if (*end != '\0' || signum <= 0)
err_error("invalid signal number %s\n", optarg);
break;
case 'V':
err_version("SUICIDE", &"#(#)$Revision: 1.2 $ ($Date: 2008/12/28 03:45:18 $)"[4]);
break;
default:
err_usage(usestr);
break;
}
}
if (optind != argc)
err_usage(usestr);
kill(getpid(), signum);
return(0);
}
And here's exitstatus.c:
/*
#(#)File: $RCSfile: exitstatus.c,v $
#(#)Version: $Revision: 1.2 $
#(#)Last changed: $Date: 2008/12/28 03:45:18 $
#(#)Purpose: Run command and report 16-bit exit status
#(#)Author: J Leffler
#(#)Copyright: (C) JLSS 2008
#(#)Product: :PRODUCT:
*/
/*TABSTOP=4*/
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 500
#endif /* __STDC_VERSION__ */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "stderr.h"
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
extern const char jlss_id_exitstatus_c[];
const char jlss_id_exitstatus_c[] = "#(#)$Id: exitstatus.c,v 1.2 2008/12/28 03:45:18 jleffler Exp $";
#endif /* lint */
int main(int argc, char **argv)
{
pid_t pid;
err_setarg0(argv[0]);
if (argc < 2)
err_usage("cmd [args...]");
if ((pid = fork()) < 0)
err_syserr("fork() failed: ");
else if (pid == 0)
{
/* Child */
execvp(argv[1], &argv[1]);
return(1);
}
else
{
pid_t corpse;
int status;
corpse = waitpid(pid, &status, 0);
if (corpse != pid)
err_syserr("waitpid() failed: ");
printf("0x%04X\n", status);
}
return(0);
}
The missing code, stderr.c and stderr.h, can easily be found in essentially any of my published programs. If you need it urgently, get it from the program SQLCMD at the IIUG Software Archive; alternatively, contact me by email (see my profile).

Resources