int main(int argc, char **argv) { t_list *list; char *term; char *bp; int tty; struct termios t; struct termios save; init_main(&bp, &list); tty = get_tty_fd(); if (argc < 2) { my_printf("[*] Usage : %s [arg:]\n", argv[0]); return (0); } if (my_params_to_list(&list, argc, argv)) return (1); if (catch_error(&term, bp, &t, &save)) return (1); raw_mode(&t); clean_screen(tty); my_select(&list, tty); default_mode(&save); return (0); }
static void fetch_accounts (struct cld_client *client) { printf("fetching accounts\n"); struct cld_object *req = cld_object_create("request"); if (req == NULL) return; cld_object_set(req, "object", cld_object_create_string("accounts")); if (cld_connection_write_blocking(client->connection, req) < 0) return; struct cld_object *response = cld_connection_read_blocking(client->connection); if (response == NULL) return; if (catch_error(__FUNCTION__, response) < 0) return; client->accounts = cld_list_create(); if (client->accounts == NULL) return; int i; int num_accounts = cld_object_array_count(response); printf("received %i accounts\n", num_accounts); for (i = 0; i < num_accounts; i++) { struct cld_account *account = cld_account_create(cld_object_copy(cld_object_array_get(response, i)), account_commit, client); cld_list_add(client->accounts, account); } cld_object_destroy(response); }
struct cld_account *cld_client_add_account (struct cld_client *client, const char *type) { struct cld_object *object; object = cld_object_create("make.account"); if (object == NULL) return NULL; cld_object_set(object, "type", cld_object_create_string(type)); if (cld_connection_write_blocking(client->connection, object) < 0) { cld_object_destroy(object); return NULL; } cld_object_destroy(object); struct cld_object *response = cld_connection_read_blocking(client->connection); if (response == NULL || catch_error(__FUNCTION__, response) < 0) return NULL; struct cld_account *account; account = cld_account_create(response, account_commit, client); if (account == NULL) { cld_object_destroy(response); return NULL; } return account; }
int my_recursive(t_opt t, char *root) { DIR *d; struct dirent *e; struct stat s; char *file; if ((d = catch_error(root)) == NULL) return (1); my_printf("\033[32m%s:\033[0m\n", root); (t.l || t.g) ? list_column_dir(root, &t) : list_simple_dir(root); while ((e = readdir(d))) { file = format_dir(root, e->d_name); if ((stat(file, &s)) == -1) { closedir(d); perror("stat"); return (1); } (IS_DIR_OK) ? file = my_strcat(file, "/") : 0; (IS_DIR_OK) ? my_recursive(t, file) : 0; free(file); } closedir(d); return (0); }
/* Asynchronous Signal-driven I/O */ #include<stdio.h> #include<sys/signal.h> #include<unistd.h> void catch_error(char *errorMessage); /* for error handling */ void InterruptSignalHandler(int signalType); /* Handles interrupts, signals */ int main(int argc, char *argv[]) { struct sigaction handler; /*Signal handler specification*/ /*--Set InterruptSignalHandler() as handler function--*/ handler.sa_handler = InterruptSignalHandler; /*--Creating mask for all signals--*/ if(sigfillset(&handler.sa_mask) < 0) catch_error("sigfillset() failed"); /*No flags*/ handler.sa_flags = 0; /*setting signal handler for interrupt signals*/ if(sigaction(SIGINT, &handler, 0) < 0) catch_error("sigaction() failed"); for(; ;) pause(); /*suspend program until signals received*/ exit(0); }
static void send_error_packet(int to_peer, int err, const char* msg) { size_t msg_size = strlen(msg); if (msg_size > UINT16_MAX) msg_size = UINT16_MAX; struct xfer_msg m = { .type = XFER_MSG_ERROR, .u.error.err = err, .u.error.msg_size = msg_size, }; send_xfer_msg(to_peer, &m); write_all(to_peer, msg, msg_size); } int xfer_stub_main(const struct cmd_xfer_stub_info* info) { struct xfer_ctx ctx = { .from_peer = STDIN_FILENO, .to_peer = STDOUT_FILENO, .info = info, }; struct errinfo ei = { .want_msg = true }; if (catch_error(do_xfer, &ctx, &ei)) { send_error_packet(ctx.to_peer, ei.err, ei.msg); return 1; } return 0; } #if FBADB_MAIN int xfer_handle_command( const struct start_peer_info* spi, const struct cmd_xfer_stub_info* local, const struct cmd_xfer_stub_info* remote) { struct child* peer = start_peer( spi, make_args_cmd_xfer_stub( CMD_ARG_NAME | CMD_ARG_FORWARDED, remote)); struct xfer_ctx ctx = { .from_peer = peer->fd[1]->fd, .to_peer = peer->fd[0]->fd, .info = local, }; do_xfer(&ctx); return child_status_to_exit_code(child_wait(peer)); }
struct cld_object * cld_client_account_list (struct cld_client *client) { struct cld_object *req = cld_object_create("request"); if (req == NULL) return NULL; cld_object_set(req, "object", cld_object_create_string("accounts")); if (cld_connection_write_blocking(client->connection, req) < 0) return NULL; struct cld_object *response = cld_connection_read_blocking(client->connection); if (response == NULL) return NULL; if (catch_error(__FUNCTION__, response) < 0) return NULL; return response; }
struct pollfd channel_request_poll(struct channel* c) { if (channel_wanted_readsz(c)) return (struct pollfd){c->fdh->fd, POLLIN, 0}; if (channel_wanted_writesz(c)) return (struct pollfd){c->fdh->fd, POLLOUT, 0}; return (struct pollfd){-1, 0, 0}; } void channel_write(struct channel* c, const struct iovec* iov, unsigned nio) { assert(c->dir == CHANNEL_TO_FD); if (c->fdh == NULL) return; // If the stream is closed, just discard bool try_direct = !c->always_buffer && ringbuf_size(c->rb) == 0; size_t directwrsz = 0; size_t totalsz; if (c->adb_encoding_hack) try_direct = false; // If writing directly, would make us overflow the write counter, // fall back to buffered IO. if (try_direct) { totalsz = iovec_sum(iov, nio); if (c->track_bytes_written && UINT32_MAX - c->bytes_written < totalsz) { try_direct = false; } } if (try_direct) { // If writev fails, just fall back to buffering path directwrsz = XMAX(writev(c->fdh->fd, iov, nio), 0); if (c->track_bytes_written) c->bytes_written += directwrsz; } for (unsigned i = 0; i < nio; ++i) { size_t skip = XMIN(iov[i].iov_len, directwrsz); directwrsz -= skip; char* b = (char*)iov[i].iov_base + skip; size_t blen = iov[i].iov_len - skip; ringbuf_copy_in(c->rb, b, blen); ringbuf_note_added(c->rb, blen); } } // Begin channel shutdown process. Closure is not complete until // channel_dead_p(c) returns true. void channel_close(struct channel* c) { c->pending_close = true; if (c->fdh != NULL && ((c->dir == CHANNEL_TO_FD && ringbuf_size(c->rb) == 0) || c->dir == CHANNEL_FROM_FD)) { fdh_destroy(c->fdh); c->fdh = NULL; } } static void poll_channel_1(void* arg) { struct channel* c = arg; size_t sz; if ((sz = channel_wanted_readsz(c)) > 0) { size_t nr_read; if (c->adb_encoding_hack) nr_read = channel_read_adb_hack(c, sz); else nr_read = channel_read_1(c, sz); assert(nr_read <= c->window); if (c->track_window) c->window -= nr_read; if (nr_read == 0) channel_close(c); } if ((sz = channel_wanted_writesz(c)) > 0) { size_t nr_written; if (c->adb_encoding_hack) nr_written = channel_write_adb_hack(c, sz); else nr_written = channel_write_1(c, sz); assert(nr_written <= UINT32_MAX - c->bytes_written); if (c->track_bytes_written) c->bytes_written += nr_written; if (c->pending_close && ringbuf_size(c->rb) == 0) channel_close(c); } } bool channel_dead_p(struct channel* c) { return (c->fdh == NULL && ringbuf_size(c->rb) == 0 && c->sent_eof == true); } void channel_poll(struct channel* c) { struct errinfo ei = { .want_msg = false }; if (catch_error(poll_channel_1, c, &ei) && ei.err != EINTR) { if (c->dir == CHANNEL_TO_FD) { // Error writing to fd, so purge buffered bytes we'll // never write. By purging, we also make the stream // appear writable (because now there's space available), // but any writes will actually go into a black hole. // This way, if somebody's blocked on being able to write // to this stream, he'll get unblocked. This behavior is // important when c is TO_PEER and lets us complete an // orderly shutdown, flushing any data we've buffered, // without adding special logic all over the place to // account for this situation. ringbuf_note_removed(c->rb, ringbuf_size(c->rb)); } channel_close(c); c->err = ei.err; } }
void parser(_map *mem, const char *statement) { /* * there're three occasions: * (1) variable declaration * (2) variable printing * (3) variable assignment */ _vector *vec_statement = vector_new(8); int count = string_split(vec_statement, statement, ';'); char *current_statement = (char *)malloc(sizeof(char)); for (int i = 0; i < count; ++i) { size_t len = strlen((char *)*vector_get(vec_statement, i)); current_statement = (char *)realloc(current_statement, sizeof(char) * (len + 1)); strcpy(current_statement, (char *)*vector_get(vec_statement, i)); if (!strcmp(current_statement, "")) { break; } bool is_assignment = true; // variable declaration char temp_str[1005]; // TODO(twd2): enough? const char double_declare[] = "double "; const char int_declare[] = "int "; const size_t double_declare_len = strlen(double_declare); const size_t int_declare_len = strlen(int_declare); int str_int_start_pos = string_startswith(current_statement, int_declare); int str_double_start_pos = string_startswith(current_statement, double_declare); if (str_double_start_pos != -1) { // variable declared as a double is_assignment = false; size_t j; for (j = str_double_start_pos + double_declare_len; j < len; ++j) { if (current_statement[j] != ' ') { break; } } string_sub(temp_str, current_statement, j, len); _vector *vec_declare = vector_new(8); int count = string_split(vec_declare, temp_str, ','); for (j = 0; j < count; ++j) { char *name_purified = string_purify((char *)(*vector_get(vec_declare, j))); add_double_variable(mem, name_purified, 0); free(name_purified); } vector_deepfree(vec_declare); } if (str_int_start_pos != -1) { // variable declared as a int is_assignment = false; size_t j; for (j = str_int_start_pos + int_declare_len; j < len; ++j) { if (current_statement[j] != ' ') { break; } } string_sub(temp_str, current_statement, j, len); _vector *vec_declare = vector_new(8); int count = string_split(vec_declare, temp_str, ','); for (j = 0; j < count; ++j) { char *name_purified = string_purify((char *)(*vector_get(vec_declare, j))); add_int_variable(mem, name_purified, 0); free(name_purified); } vector_deepfree(vec_declare); } // variable printing const char print_declare1[] = "print "; const char print_declare2[] = "print("; const size_t print_declare_len = strlen(print_declare1); if (string_startswith(current_statement, print_declare1) != -1 || string_startswith(current_statement, print_declare2) != -1) { // print statement is_assignment = false; int j; for (j = print_declare_len - 1; j < len; ++j) { if (current_statement[j] == ')') { break; } } string_sub(temp_str, current_statement, print_declare_len, j - print_declare_len); string_clearspace(temp_str); parse(temp_str); convert(temp_str); _variable var = calculate(mem, temp_str); if (var.type == ERRORVALUE) { catch_error(var.int_value); break; } print_variable(&var); } // variable assignment if (is_assignment) { strcpy(temp_str, current_statement); string_clearspace(temp_str); parse(temp_str); convert(temp_str); _variable var = calculate(mem, temp_str); if (var.type == ERRORVALUE) { catch_error(var.int_value); break; } } } free(current_statement); vector_deepfree(vec_statement); return; }
static void xfd_op(struct xfd_op_ctx* ctx) { bool old_die_on_quit = hack_die_on_quit; hack_die_on_quit = true; struct errinfo ei = { .want_msg = true, }; if (catch_error(xfd_op_1, ctx, &ei)) { deferred_die(ei.err, "%s", ei.msg); errno = ei.err < 0 ? EIO : ei.err; ctx->result = -1; } hack_die_on_quit = old_die_on_quit; } // xfdopen_read and xfdopen_write are called from inside stdio // machinery and must always return locally --- never longjmp! If we // die inside one of these functions, we "defer" the die and actually // longjmp at the next safe opportunity. static custom_stream_ssize_t xfdopen_read(void* cookie, char* buf, custom_stream_size_t size) { struct xfd_op_ctx ctx = { .op = XFD_OP_READ, .fd = xfdopen_fd(cookie), .buf = buf, .size = size }; xfd_op(&ctx); return ctx.result; } static custom_stream_ssize_t xfdopen_write(void* cookie, const char* buf, custom_stream_size_t size) { struct xfd_op_ctx ctx = { .op = XFD_OP_WRITE, .fd = xfdopen_fd(cookie), .buf = (void*) buf, .size = size }; xfd_op(&ctx); return ctx.result; } FILE* xfdopen(int fd, const char* mode) { struct cleanup* cl = cleanup_allocate(); FILE* f = NULL; #if defined(HAVE_FOPENCOOKIE) cookie_io_functions_t funcs = { .read = xfdopen_read, .write = xfdopen_write, .seek = NULL, .close = NULL, }; f = fopencookie((void*) (intptr_t) fd, mode, funcs); #elif defined(HAVE_FUNOPEN) f = funopen((void*) (intptr_t) fd, xfdopen_read, xfdopen_write, NULL, NULL); #else # error This platform has no custom stdio stream support #endif if (f == NULL) die_errno("fdopen"); cleanup_commit(cl, xfopen_cleanup, f); return f; } // Like xdup, but return a structure that allows the fd to be // individually closed. struct fdh* fdh_dup(int fd) { struct reslist* rl = reslist_create(); WITH_CURRENT_RESLIST(rl); struct fdh* fdh = xalloc(sizeof (*fdh)); fdh->rl = rl; fdh->fd = xdup(fd); return fdh; } void fdh_destroy(struct fdh* fdh) { reslist_destroy(fdh->rl); } int xF_GETFL(int fd) { int flags = fcntl(fd, F_GETFL); if (flags == -1) die_errno("fcntl(%d, F_GETFL)", fd); return flags; }