/* add/remove iptable drop rule to VIP */ static void handle_iptable_rule_to_vip(ip_address_t *ipaddress, int cmd, char *ifname, void *unused) { char *argv[10]; unsigned int i = 0; int if_specifier = -1; char *addr_str; if (global_data->vrrp_iptables_inchain[0] == '\0') return; if (IP_IS6(ipaddress)) { handle_iptable_rule_to_NA(ipaddress, cmd, ifname); argv[i++] = "ip6tables"; } else { argv[i++] = "iptables"; } addr_str = ipaddresstos(NULL, ipaddress); argv[i++] = cmd ? "-A" : "-D"; argv[i++] = global_data->vrrp_iptables_inchain; argv[i++] = "-d"; argv[i++] = addr_str; if (IP_IS6(ipaddress) && IN6_IS_ADDR_LINKLOCAL(&ipaddress->u.sin6_addr)) { if_specifier = i; argv[i++] = "-i"; argv[i++] = ifname; } argv[i++] = "-j"; argv[i++] = "DROP"; argv[i] = NULL; if (fork_exec(argv) < 0) log_message(LOG_ERR, "Failed to %s iptable drop rule" " to vip %s", (cmd) ? "set" : "remove", addr_str); else ipaddress->iptable_rule_set = (cmd != IPADDRESS_DEL); if (global_data->vrrp_iptables_outchain[0] == '\0') return; argv[2] = global_data->vrrp_iptables_outchain ; argv[3] = "-s"; if (if_specifier >= 0) argv[if_specifier] = "-o"; if (fork_exec(argv) < 0) log_message(LOG_ERR, "Failed to %s iptable drop rule" " from vip %s", (cmd) ? "set" : "remove", addr_str); }
void ring(char *d) { static char buf[BUF_SIZE]; snprintf(buf, BUF_SIZE, "%s %s", cmd.ring_prog, d); dbg_print("Ringing %s", buf); fork_exec(buf); }
int sv_exec(callspace *cs, int argv[]) { int *array = array_get(g_cs, argv[0]); int array_c = array_length(g_cs, argv[0]); char **fork_argv = malloc(sizeof(char*) * (array_c + 1)); int i; char *arg; for (i = 0; i < array_c; i++) { arg = string_get(g_cs, array[i]); if (strcmp(arg, "%%") == 0) { fork_argv[i] = g_last_pid_str; } else { fork_argv[i] = arg; } } fork_argv[i+1] = NULL; return fork_exec(array_c, fork_argv); }
/* Unregister with netreport, relay a status byte to the parent, clean up * the pid file, and bail. */ static void failureExit(int exitCode) { fork_exec(TRUE, "/sbin/netreport", "-r", NULL, NULL); relay_exitcode(exitCode); doPidFile(NULL); exit(exitCode); }
/** * Run a serie of piped commands * @param n number of commands in the pipe * @param cmds arrays of commands */ void fork_runline(int n, char **cmds){ int in = STDIN_FILENO; // file descriptor for in -- initially set as stdin int out; int status; pid_t pid; int fd[2]; // file descriptor for piping //for each command, create a fork to execute except the last one. for(int i=0 ; i<n-1 ; i++){ pipe(fd); out = fd[1]; // fd[1] is write end of the pipe pid = fork_exec(in, out, cmds[i]); //only parent process of the fork_exec will reach here waitpid(pid, &status, 0); // wait for its child to finish first! // close(fd[0]); //TODO where to put this close(out); // no noweed for writing since the child will write in = fd[0]; // now the in side of the pipe became in for the next command } //Last stage of the pipeline -- redirect in to be stdin if(in!=STDIN_FILENO) dup2(in,STDIN_FILENO); char *cmd = cmds[n-1]; char * const cmdArgv[INPUT_SIZE] = {cmd, NULL}; // fflush(stdout); execvp(cmdArgv[0], cmdArgv); perror("last"); exit(-1); }
int main(int argc, char argv[]) { pid_t pid[10]; fork_exec("ping 127.0.0.1", FALSE, &pid[0]); fork_exec("ping 127.0.0.1", FALSE, &pid[1]); /* lacy */ if(argc == 1) sleep(2); else sleep(60*60); // 1h kill(pid[0],SIGTERM); kill(pid[1],SIGKILL); blocking_wait_on_child(pid[0]); blocking_wait_on_child(pid[1]); return 0; }
/* * While inside interactive mode, launch the external command cmd on the given * file. */ void wins_launch_external (char *file, char *cmd) { char *arg[] = { cmd, file, NULL }; int pid; wins_prepare_external (); if ((pid = fork_exec (NULL, NULL, cmd, arg))) child_wait (NULL, NULL, pid); wins_unprepare_external (); }
void rclick_taskbar(int x) { XEvent ev; int mousex, mousey; Rect bounddims; unsigned int current_item = UINT_MAX; Window constraint_win; XSetWindowAttributes pattr; get_mouse_position(&mousex, &mousey); bounddims.x = 0; bounddims.y = 0; bounddims.width = DisplayWidth(dsply, screen); bounddims.height = BARHEIGHT(); constraint_win = XCreateWindow(dsply, root, bounddims.x, bounddims.y, bounddims.width, bounddims.height, 0, CopyFromParent, InputOnly, CopyFromParent, 0, &pattr); XMapWindow(dsply, constraint_win); if (!(XGrabPointer(dsply, root, False, MouseMask, GrabModeAsync, GrabModeAsync, constraint_win, None, CurrentTime) == GrabSuccess)) { XDestroyWindow(dsply, constraint_win); return; } draw_menubar(); update_menuitem(INT_MAX); // force initial highlight current_item = update_menuitem(x); do { XMaskEvent(dsply, MouseMask|KeyMask, &ev); switch (ev.type) { case MotionNotify: current_item = update_menuitem(ev.xmotion.x); break; case ButtonRelease: if (current_item != UINT_MAX) { fork_exec(menuitems[current_item].command); } break; case KeyPress: XPutBackEvent(dsply, &ev); break; } } while (ev.type != ButtonPress && ev.type != ButtonRelease && ev.type != KeyPress); redraw_taskbar(); XUnmapWindow(dsply, constraint_win); XDestroyWindow(dsply, constraint_win); ungrab(); }
void context_callback ( MBTrayApp *app ) { #ifdef USE_LIBSN if (CONTEXT_APP_WANT_SN) { sn_activate(CONTEXT_APP, CONTEXT_APP " " CONTEXT_APP_ARGS); return; } #endif fork_exec(CONTEXT_APP " " CONTEXT_APP_ARGS); }
/** * @brief Make sure the country code is effective imediately * * @param path Path of command * @param argv[] Arguments * @param idx Index * * @return 0 Success !0 Failed */ static int set_ccode_cmd(int idx) { const char *argv[4]; int ret; argv[0] = "wl"; argv[1] = "country"; argv[2] = g_ccode[idx].code; argv[3] = NULL; ret = fork_exec("/bin/wl", (char *const *) argv); if (0 != ret) { DEBUG("%s, set ccode failed\n", __FUNCTION__); } return ret; }
static int do_exec (ssh_event event, ssh_channel chan, const gchar *cmd) { socket_t fd; short events; fd = fork_exec (cmd); if (fd < 0) return -1; cb.userdata = GINT_TO_POINTER (fd); ssh_callbacks_init(&cb); ssh_set_channel_callbacks (chan, &cb); events = POLLIN | POLLOUT | POLLPRI | POLLERR | POLLHUP | POLLNVAL; if (ssh_event_add_fd (event, fd, events, fd_data, chan) != SSH_OK) g_return_val_if_reached(-1); return 0; }
int ewmh_handle_root_message(Wm *w, XClientMessageEvent *e) { /* Handle client messages _sent_ to root window */ Client *c = NULL; dbg("%s() called\n", __func__); if (e->message_type == w->atoms[_NET_ACTIVE_WINDOW]) { dbg("%s() got active window message for win %li", __func__, e->window); if ((c = wm_find_client(w, e->window, WINDOW)) != NULL) { if (c->type == MBCLIENT_TYPE_DIALOG && c->trans != NULL) { /* * If an attempt has been made to activate a hidden * dialog, activate its parent app first. * * Note this is mainly to work with some task selectors * ( eg the gnome one, which activates top dialog ). * * XXX wm_activate_client() should probably do this. */ Client *parent = c->trans; while (parent->trans != NULL) parent = parent->trans; if (parent != wm_get_visible_main_client(w)) wm_activate_client(parent); } /* Likely activated by a TN so start pinging if aggresive setup */ if (w->config->ping_aggressive && c->type == MBCLIENT_TYPE_APP && c != wm_get_visible_main_client(w)) ewmh_ping_client_start (c); wm_activate_client(c); } return 1; } else if (e->message_type == w->atoms[_NET_CLOSE_WINDOW]) { if ((c = wm_find_client(w, e->window, WINDOW)) != NULL) client_deliver_delete(c); return 1; } else if (e->message_type == w->atoms[WM_PROTOCOLS] && e->data.l[0] == w->atoms[_NET_WM_PING]) { if ((c = wm_find_client(w, e->data.l[1], WINDOW)) != NULL) { dbg("%s() pong from %s\n", __func__, c->name); /* We got a response to a ping. stop pinging it now * until close button is pressed again. */ if (c->ping_handler_called) { int len; char *buf; /* aha! this was thought be be dead but has come * alive again.. */ len = strlen(w->config->ping_handler) + 32; buf = malloc(len); if (buf) { snprintf(buf, len-1, "%s %i %li 1", w->config->ping_handler, c->pid, c->window); fork_exec(buf); free(buf); } } if (w->config->ping_aggressive) { if (c->pings_pending >= 0) c->pings_pending--; } else { /* Regular pinging, assume 1 reply and the * app is alive. */ if (c->pings_pending > 0) { ewmh_ping_client_stop(c); } } } } else if (e->message_type == w->atoms[WINDOW_STATE]) { if (e->data.l[1] == w->atoms[WINDOW_STATE_FULLSCREEN] && ((c = wm_find_client(w, e->window, WINDOW)) != NULL) && c->type == MBCLIENT_TYPE_APP) { dbg("got EWMH fullscreen state change\n"); switch (e->data.l[0]) { case _NET_WM_STATE_REMOVE: if (c->flags & CLIENT_FULLSCREEN_FLAG) main_client_toggle_fullscreen(c); break; case _NET_WM_STATE_ADD: if (!(c->flags & CLIENT_FULLSCREEN_FLAG)) main_client_toggle_fullscreen(c); break; case _NET_WM_STATE_TOGGLE: main_client_toggle_fullscreen(c); break; } } else if (e->data.l[1] == w->atoms[WINDOW_STATE_ABOVE] && ((c = wm_find_client(w, e->window, WINDOW)) != NULL) && c->type == MBCLIENT_TYPE_DIALOG) { dbg("got EWMH above state change\n"); switch (e->data.l[0]) { case _NET_WM_STATE_REMOVE: c->flags &= ~CLIENT_HAS_ABOVE_STATE; break; case _NET_WM_STATE_ADD: c->flags |= CLIENT_HAS_ABOVE_STATE; break; case _NET_WM_STATE_TOGGLE: c->flags ^= CLIENT_HAS_ABOVE_STATE; break; } wm_activate_client(c); } return 1; } else if (e->message_type == w->atoms[_NET_SHOW_DESKTOP] && wm_get_desktop(w) ) { dbg("%s() got desktop message\n", __func__); if (e->data.l[0] == 1) { /* Show the desktop, if not shown */ if (!(w->flags & DESKTOP_RAISED_FLAG)) wm_toggle_desktop(w); } else { /* Hide the desktop, if shown */ if (w->flags & DESKTOP_RAISED_FLAG) wm_toggle_desktop(w); } } return 0; }
int main(int argc, char **argv) { int i, x, y; /* Config Parameters */ int switch_count = 1; char *img_file = NULL; char *dotdesktop_file = NULL; MBDotDesktop *dd = NULL; Bool start_app = False; char png_path[256] = { 0 }; TrayApp = mb_tray_app_new ( "mb-applet-launcher", resize_callback, paint_callback, &argc, &argv ); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { if (!strcmp ("--title", argv[i]) || !strcmp ("-n", argv[i])) { if (++i>=argc) usage (argv[0]); win_panel_title = argv[i]; switch_count += 2; continue; } if (!strcmp ("--kill", argv[i]) || !strcmp ("-k", argv[i])) { action = ACTION_KILL; switch_count++; continue; } if (!strcmp ("--start", argv[i]) || !strcmp ("-s", argv[i])) { start_app = True; switch_count++; continue; } if (!strcmp ("--kill", argv[i]) || !strcmp ("-k", argv[i])) { action = ACTION_KILL; switch_count++; continue; } if (!strcmp ("--relaunch", argv[i]) || !strcmp ("-l", argv[i])) { action = ACTION_NONE; switch_count++; continue; } if (!strcmp ("--message", argv[i]) || !strcmp ("-m", argv[i])) { action = ACTION_MESSAGE_DOCK; switch_count++; continue; } if (!strcmp ("--no-animation", argv[i]) || !strcmp ("-na", argv[i])) { DoAnimation = False; switch_count++; continue; } if (!strcmp ("--desktop", argv[i])) { if (++i>=argc) usage (argv[0]); dotdesktop_file = argv[i]; switch_count += 2; continue; } usage(argv[0]); } else break; } if (argc-switch_count < 2 && dotdesktop_file == NULL) usage(argv[0]); dpy = mb_tray_app_xdisplay(TrayApp); screen = mb_tray_app_xscreen(TrayApp); atom_wm_state = XInternAtom(dpy, "WM_STATE", False); atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); atom_wm_protos = XInternAtom(dpy, "WM_PROTOCOLS", False); pb = mb_pixbuf_new(dpy, mb_tray_app_xscreen(TrayApp)); if (dotdesktop_file != NULL) { if ((dd = mb_dotdesktop_new_from_file(dotdesktop_file)) != NULL && mb_dotdesktop_get(dd, "Name") && mb_dotdesktop_get(dd, "Icon") && mb_dotdesktop_get(dd, "Exec") ) { img_file = mb_dotdesktop_get(dd, "Icon"); if (img_file[0] != '/') { snprintf(png_path, 256, "%s/pixmaps/%s", DATADIR, mb_dotdesktop_get(dd, "Icon") ); img_file = strdup(png_path); } cmd_str = mb_dotdesktop_get_exec(dd); if (!win_panel_title) win_panel_title = mb_dotdesktop_get(dd, "Name"); #ifdef USE_LIBSN if (mb_dotdesktop_get(dd, "SingleInstance") && !strcasecmp(mb_dotdesktop_get(dd, "SingleInstance"), "true")) { action = ACTION_SI; } else if (mb_dotdesktop_get(dd, "StartupNotify") && !strcasecmp(mb_dotdesktop_get(dd, "StartupNotify"), "true")) { action = ACTION_SN; } else #endif if (mb_dotdesktop_get(dd, "X-MB-NoWindow") && !strcasecmp(mb_dotdesktop_get(dd, "X-MB-NoWindow"), "true")) { DoAnimation = False; action = ACTION_NONE; } } else { fprintf(stderr,"%s: failed to parse %s\n", argv[0], dotdesktop_file); exit(1); } } else { img_file = argv[switch_count]; if (img_file[0] != '/') { /* FIXME: should really get from theme */ snprintf(png_path, 256, "%s/pixmaps/%s", DATADIR, img_file); img_file = strdup(png_path); } cmd_str = arr_to_str(&argv[switch_count+1], argc - switch_count - 1); } if (!(img_icon = mb_pixbuf_img_new_from_file(pb, img_file))) { fprintf(stderr, "%s: failed to load image %s \n", argv[0], img_file ); exit(1); } /* make active button image */ img_icon_active = mb_pixbuf_img_clone(pb, img_icon); for (x=0; x<mb_pixbuf_img_get_width(img_icon); x++) for (y=0; y<mb_pixbuf_img_get_height(img_icon); y++) { int aa; unsigned char r,g,b,a; mb_pixbuf_img_get_pixel (pb, img_icon_active, x, y, &r, &g, &b, &a); aa = (int)a; aa -= 0x80; if (aa < 0) aa = 0; mb_pixbuf_img_set_pixel_alpha(img_icon_active, x, y, aa); } #ifdef USE_LIBSN if (action == ACTION_SN || action == ACTION_SI) sn_dpy = sn_display_new (dpy, NULL, NULL); #endif mb_tray_app_set_xevent_callback (TrayApp, xevent_callback ); mb_tray_app_set_button_callback (TrayApp, button_callback ); if (win_panel_title == NULL) /* XXX UTF8 naming */ { win_panel_title = malloc( strlen(argv[1+switch_count]) + strlen(" Launcher") + 1 ); strcpy(win_panel_title, argv[1+switch_count]); strcat(win_panel_title, " Launcher"); } mb_tray_app_set_name (TrayApp, win_panel_title); XSelectInput(dpy, mb_tray_app_xrootwin(TrayApp), SubstructureNotifyMask); signal(SIGCHLD, SIG_IGN); mb_tray_app_set_icon(TrayApp, pb, img_icon); /* make sure we always end up on the left of the panel */ mb_tray_app_request_offset (TrayApp, -1); if (start_app) { switch(action) { #ifdef USE_LIBSN case ACTION_SN: sn_activate(win_panel_title, cmd_str); break; case ACTION_SI: si_activate(win_panel_title, cmd_str); break; #endif case ACTION_NONE: fork_exec(cmd_str); break; case ACTION_KILL: case ACTION_TOGGLE_WIN_STATE: fork_exec(cmd_str); win_launched = get_launch_window(); break; } } mb_tray_app_main (TrayApp); XCloseDisplay(dpy); exit(0); }
void button_callback (MBTrayApp *app, int x, int y, Bool is_released ) { int abs_x, abs_y; Bool do_anim = False; ButtonIsDown = True; if (is_released) { ButtonIsDown = False; mb_tray_app_repaint (app); switch (action) { case ACTION_NONE: fork_exec(cmd_str); do_anim = DoAnimation; break; case ACTION_KILL: if (win_launched && win_exists(win_launched, mb_tray_app_xrootwin(app))) { kill_launched_win(win_launched); win_launched = None; } else { fork_exec(cmd_str); win_launched = get_launch_window(); } break; case ACTION_TOGGLE_WIN_STATE: if (win_launched && win_exists(win_launched, mb_tray_app_xrootwin(app))) { XWindowAttributes win_attrib; XGetWindowAttributes(dpy, win_launched, &win_attrib); if (win_attrib.map_state == IsUnmapped || get_win_state(win_launched) != NormalState) XMapRaised(dpy, win_launched); else XIconifyWindow(dpy, win_launched, screen); } else { fork_exec(cmd_str); win_launched = get_launch_window(); } break; case ACTION_MESSAGE_DOCK: send_panel_message(cmd_str); break; #ifdef USE_LIBSN case ACTION_SN: do_anim = DoAnimation; sn_activate(win_panel_title, cmd_str); break; case ACTION_SI: do_anim = DoAnimation; si_activate(win_panel_title, cmd_str); break; #endif } if (do_anim) { mb_tray_app_get_absolute_coords (app, &abs_x, &abs_y); mb_util_animate_startup(mb_tray_app_xdisplay (app), abs_x, abs_y, mb_tray_app_width (app), mb_tray_app_height (app)); } } else mb_tray_app_repaint (app); }
static void handle_iptable_rule_to_NA(ip_address_t *ipaddress, int cmd, char *ifname, bool force) { char *argv[14]; unsigned int i = 0; int if_specifier = -1; int type_specifier ; char *addr_str; if (global_data->vrrp_iptables_inchain[0] == '\0') return; addr_str = ipaddresstos(NULL, ipaddress); argv[i++] = "ip6tables"; argv[i++] = cmd ? "-A" : "-D"; argv[i++] = global_data->vrrp_iptables_inchain; argv[i++] = "-d"; argv[i++] = addr_str; if (IN6_IS_ADDR_LINKLOCAL(&ipaddress->u.sin6_addr)) { if_specifier = i; argv[i++] = "-i"; argv[i++] = ifname; } argv[i++] = "-p"; argv[i++] = "icmpv6"; argv[i++] = "--icmpv6-type"; type_specifier = i; argv[i++] = "136"; argv[i++] = "-j"; argv[i++] = "ACCEPT"; argv[i] = NULL; if (fork_exec(argv) < 0 && !force) log_message(LOG_ERR, "Failed to %s ip6table rule to accept NAs sent" " to vip %s", (cmd) ? "set" : "remove", addr_str); argv[type_specifier] = "135"; if (fork_exec(argv) < 0 && !force) log_message(LOG_ERR, "Failed to %s ip6table rule to accept NSs sent" " to vip %s", (cmd) ? "set" : "remove", addr_str); if (global_data->vrrp_iptables_outchain[0] == '\0') return; argv[2] = global_data->vrrp_iptables_outchain; argv[3] = "-s"; if (if_specifier >= 0) argv[if_specifier] = "-o"; /* Allow NSs to be sent - this should only happen if the underlying interface doesn't have an IPv6 address */ if (fork_exec(argv) < 0 && !force) log_message(LOG_ERR, "Failed to %s ip6table rule to allow NSs to be" " sent from vip %s", (cmd) ? "set" : "remove", addr_str); argv[type_specifier] = "136"; /* Allow NAs to be sent in reply to an NS */ if (fork_exec(argv) < 0 && !force) log_message(LOG_ERR, "Failed to %s ip6table rule to allow NAs to be" " sent from vip %s", (cmd) ? "set" : "remove", addr_str); }
int suspend_test(void) { char wakelock_dmask[16] = ""; char earlysuspend_dmask[16] = ""; time_t now; time_t expiration; int success_count = 0; int rv; int i = 0; int k; int num_success = 0; int ret; unsigned int core1_status; unsigned int core2_status; unsigned int core3_status; unsigned int dual_core = 0; signed long usb_active; int num_cores = 0; char *ss_pid; fprintf(stdout, "Determine if wakelock node is there \n"); g_wakelock_exists = file_exists(WAKELOCK_NODE); if (g_wakelock_exists) { fprintf(stdout, "reset the sensors data setting \n"); rv = write_string_to_file(NULL, SENSOR_SETTINGS, "0\n"); if (rv < 0) { fprintf(stdout, "unable to set sensor settings: %s\n", strerror(-rv)); goto suspend_test_early_bailout; } fprintf(stdout, "sleep for sensor daemon to pick up the setting \n"); sleep(2); fprintf(stdout, "Save current wakelock debug mask\n"); rv = read_from_file( NULL, WAKELOCK_DEBUG_MASK_NODE, wakelock_dmask, sizeof(wakelock_dmask) - 1); if (rv < 0) { fprintf(stdout, "cannot read %s: %s\n", WAKELOCK_DEBUG_MASK_NODE, strerror(-rv)); goto suspend_test_bailout; } wakelock_dmask[rv] = '\0'; fprintf(stdout, "Turn on additional wakelock debug info\n"); rv = write_string_to_file( NULL, WAKELOCK_DEBUG_MASK_NODE, "22\n"); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", WAKELOCK_DEBUG_MASK_NODE, strerror(-rv)); goto suspend_test_bailout; } fprintf(stdout, "Add wakelock to hold off suspend till we suspend ourselves\n"); rv = write_string_to_file( NULL, WAKELOCK_LOCK_NODE, SUSPENDPC_WAKELOCK); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", WAKELOCK_LOCK_NODE, strerror(-rv)); goto suspend_test_bailout; } } fprintf(stdout, "Save current earlysuspend debug mask\n"); rv = read_from_file( NULL, EARLYSUSPEND_DEBUG_MASK_NODE, earlysuspend_dmask, sizeof(earlysuspend_dmask) - 1); if (rv < 0) { fprintf(stdout, "cannot read %s: %s\n", EARLYSUSPEND_DEBUG_MASK_NODE, strerror(-rv)); goto suspend_test_bailout; } earlysuspend_dmask[rv] = '\0'; fprintf(stdout, "turn on early suspend logs\n"); rv = write_string_to_file( NULL, EARLYSUSPEND_DEBUG_MASK_NODE, "5\n"); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", EARLYSUSPEND_DEBUG_MASK_NODE, strerror(-rv)); goto suspend_test_bailout; } fprintf(stdout, "Check whether power management is up\n"); if (!file_exists(PM_STATS_NODE)) { fprintf(stdout, "power management is not available\n"); goto suspend_test_bailout; } fprintf(stdout, "Determine the power management module\n"); if (directory_exists(SYS_PM_8x60)) { g_sys_pm = SYS_PM_8x60; if (file_exists_with_prefix(SYS_PM_8x60, SLEEP_MODE_NODE_CORE_3)) num_cores = 4; else if (file_exists_with_prefix(SYS_PM_8x60, SLEEP_MODE_NODE_CORE_1)) num_cores = 2; else num_cores = 1; } else { fprintf(stdout, "power management is not available\n"); goto suspend_test_bailout; } fprintf(stdout, "Delay tests for some time for usb cable to be plugged out\n"); if (g_delay_test_sec) { unsigned int seconds = g_delay_test_sec; while (seconds) seconds = sleep(seconds); } /* * check if the usb wakelock has been released before * proceeding with the test */ if (g_wakelock_exists) { /* * capture the usb wakelock stats */ rv = read_from_file(NULL, WAKELOCK_NODE, g_wakelock_stats, sizeof(g_wakelock_stats) - 1); usb_active = parse_wakelock_stats_for_active_wl( g_wakelock_stats, "\"msm_otg\""); if (usb_active != 0) { fprintf(stdout, " the usb wakelock is still held by the system\n"); goto suspend_test_bailout; } } /* * determine resume command */ do { rv = write_string_to_file(NULL, POWER_NODE, POWER_STANDBY); if (rv > 0) { g_resume_command = POWER_STANDBY; break; } rv = write_string_to_file( NULL, POWER_NODE, POWER_ON); if (rv > 0) { g_resume_command = POWER_ON; break; } fprintf(stdout, "cannot write to %s: %s\n", POWER_NODE, strerror(-rv)); goto suspend_test_bailout; } while (0); fprintf(stdout, "Set suspend configuration\n"); if (num_cores == 4) { write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_0, 1); write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_1, 1); write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_2, 1); write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_3, 1); } else if (num_cores == 2) { write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_0, 1); write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_1, 1); } else if (num_cores == 1) { write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_0, 1); } fprintf(stdout, "Turn off idle power collapse and mp-decision\n"); if ((num_cores == 2) || (num_cores == 4)) { if (num_cores == 4) { write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_2, 0); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_3, 0); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_2, 0); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_3, 0); } write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_0, 0); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_1, 0); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_0, 0); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_1, 0); fprintf(stdout, "Turn off mp-decision before testing suspend\n"); rv = fork_exec("stop", "mpdecision", NULL, NULL, 0); if (rv < 0) { fprintf(stdout, "cannot turn off mp-decision: %s\n", strerror(-rv)); goto suspend_test_bailout; } fprintf(stdout, "Now explicitly turn ON core 1 if not ON already\n"); core1_status = read_unsigned_int_from_file(NULL, HOTPLUG_NODE_CORE_1); fprintf(stdout, "core1_status = %d\n", core1_status); if (!core1_status) { fprintf(stdout, "turning on core 1\n"); rv = write_int_to_file(NULL, HOTPLUG_NODE_CORE_1, 1); } if (num_cores == 4) { fprintf(stdout, "Now explicitly turn ON core 2 if not ON already\n"); core2_status = read_unsigned_int_from_file(NULL, HOTPLUG_NODE_CORE_2); fprintf(stdout, "core2_status = %d\n", core2_status); if (!core2_status) { fprintf(stdout, "turning on core 2\n"); rv = write_int_to_file(NULL, HOTPLUG_NODE_CORE_2, 1); } fprintf(stdout, "Now explicitly turn ON core 3 if not ON already\n"); core3_status = read_unsigned_int_from_file(NULL, HOTPLUG_NODE_CORE_3); fprintf(stdout, "core3_status = %d\n", core3_status); if (!core3_status) { fprintf(stdout, "turning on core 3\n"); rv = write_int_to_file(NULL, HOTPLUG_NODE_CORE_3, 1); } } } else if (num_cores == 1) { write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_0, 0); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_0, 0); } fprintf(stdout, "Clear kernel log\n"); rv = fork_exec("dmesg", "-c", NULL, NULL, 1); if (rv < 0) { fprintf(stdout, "dmesg -c failed: %s\n", strerror(-rv)); goto suspend_test_bailout; } fprintf(stdout, "Clear power management stats\n"); rv = write_string_to_file(NULL, PM_STATS_NODE, "reset\n"); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", PM_STATS_NODE, strerror(-rv)); goto suspend_test_bailout; } fprintf(stdout, "Set wakeup time\n"); rv = write_int_to_file( g_sys_pm, SLEEP_TIME_OVERRIDE_NODE, g_wakeup_sec); if (rv < 0) { fprintf(stdout, "cannot write to %s%s: %s\n", g_sys_pm, SLEEP_TIME_OVERRIDE_NODE, strerror(-rv)); goto suspend_test_bailout; } if (g_wakelock_exists) { fprintf(stdout, "Remove the suspend wakelock before issuing the suspend command\n"); rv = write_string_to_file( NULL, WAKELOCK_UNLOCK_NODE, SUSPENDPC_WAKELOCK); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", WAKELOCK_UNLOCK_NODE, strerror(-rv)); goto suspend_test_bailout; } } for (i = 0; i < g_num_iter; i++) { msg("beginning iteration %d for suspend\n", i); fprintf(stdout, "Determine expiration time\n"); now = time(NULL); if (now == (time_t)-1) { fprintf(stdout, "time() failed: %s\n", strerror(errno)); continue; } expiration = now + g_timeout_sec; fprintf(stdout, "Issue suspend command\n"); rv = write_string_to_file(NULL, POWER_NODE, "mem\n"); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", POWER_NODE, strerror(-rv)); i++; goto suspend_test_late_bailout; } k = 0; do { usleep(300 * 1000); if (k % 10 == 0) { fprintf(stdout, "load power management stats\n"); } rv = read_from_file(NULL, PM_STATS_NODE, g_pm_stats, sizeof(g_pm_stats) - 1); if (rv < 0) { fprintf(stdout, "cannot read %s: %s\n", PM_STATS_NODE, strerror(-rv)); goto suspend_test_bailout_cur_iter; } if (rv == sizeof(g_pm_stats) - 1) { fprintf(stdout, "buffer too small for %s\n", PM_STATS_NODE); i++; goto suspend_test_late_bailout; } g_pm_stats[rv] = '\0'; if (k % 10 == 0) { fprintf(stdout, "Look for suspend event\n"); } success_count = parse_pm_stats_count(g_pm_stats, "\n[cpu 0] suspend:\n count: "); if (success_count < 0 ) { fprintf(stdout, "bad count(s) from " "power management stats\n"); i++; goto suspend_test_late_bailout; } if (success_count > num_success) break; if (k % 10 == 0) { fprintf(stdout, "Check timeout\n"); } now = time(NULL); if (now == (time_t)-1) { fprintf(stdout, "time() failed: %s\n", strerror(errno)); goto suspend_test_bailout_cur_iter; } k++; } while (now < expiration); suspend_test_bailout_cur_iter: if (g_resume_command != NULL) { fprintf(stdout, "Issue resume command\n"); rv = write_string_to_file( NULL, POWER_NODE, g_resume_command); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", POWER_NODE, strerror(-rv)); i++; goto suspend_test_late_bailout; } } if (success_count > num_success) { fprintf(stdout, "Suspend/resume succeeded on iteration %d\n", i + 1); msg("Suspend/resume succeeded on iteration %d\n", i + 1); num_success++; } if (now >= expiration) { fprintf(stdout, "Suspend/resume timed out on iteration %d\n", i + 1); msg("Suspend/resume timed out on iteration %\n", i + 1); i++; break; } } fprintf(stdout, "====BEGIN power management stats====\n"); fflush(stdout); rv = write_to_fd(STDOUT_FILENO, g_pm_stats, strlen(g_pm_stats)); if (rv < 0) fprintf(stdout, "cannot write out power management stats\n"); fprintf(stdout, "====END power management stats====\n"); if (g_wakelock_exists) { fprintf(stdout, "====BEGIN wakelock stats====\n"); fflush(stdout); rv = fork_exec("cat", WAKELOCK_NODE, NULL, NULL, 0); if (rv < 0) fprintf(stdout, "cannot dump %s\n", WAKELOCK_NODE); fprintf(stdout, "====END wakelock stats====\n"); } suspend_test_late_bailout: if (g_resume_command != NULL) { fprintf(stdout, "Issue resume command\n"); rv = write_string_to_file( NULL, POWER_NODE, g_resume_command); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", POWER_NODE, strerror(-rv)); goto suspend_test_bailout; } } suspend_test_bailout: fprintf(stdout, "Unset wakeup time\n"); rv = write_string_to_file( g_sys_pm, SLEEP_TIME_OVERRIDE_NODE, "0\n"); if ((num_cores == 2) || (num_cores == 4)) { /* restore idle power collapse */ if (num_cores == 4) { write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_2, 1); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_3, 1); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_2, 1); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_3, 1); } write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_0, 1); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_1, 1); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_0, 1); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_1, 1); fprintf(stdout, "Turn mp-decision back on\n"); rv = fork_exec("start", "mpdecision", NULL, NULL, 0); } else if (num_cores == 1) { write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_0, 1); write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_0, 1); } fprintf(stdout, "Release suspend wakelock\n"); rv = write_string_to_file( NULL, WAKELOCK_UNLOCK_NODE, SUSPENDPC_WAKELOCK); fprintf(stdout, "Restore wakelock debug mask\n"); if (g_wakelock_exists) { rv = write_string_to_file(NULL, WAKELOCK_DEBUG_MASK_NODE, wakelock_dmask); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", WAKELOCK_DEBUG_MASK_NODE, strerror(-rv)); } } fprintf(stdout, "Restore earlysuspend debug mask\n"); rv = write_string_to_file(NULL, EARLYSUSPEND_DEBUG_MASK_NODE, earlysuspend_dmask); if (rv < 0) { fprintf(stdout, "cannot write to %s: %s\n", EARLYSUSPEND_DEBUG_MASK_NODE, strerror(-rv)); } fprintf(stdout, "Restore the sensor settings\n"); fprintf(stdout, "set the sensors data setting\n"); rv = write_string_to_file(NULL, SENSOR_SETTINGS, "1\n"); fprintf(stdout, "sleep for sometime for the sensors daemon to pick up the setting\n"); sleep(2); suspend_test_early_bailout: fprintf(stdout, "====BEGIN kernel log====\n"); fflush(stdout); rv = fork_exec("dmesg", NULL, NULL, NULL, 0); if (rv < 0) fprintf(stdout, "cannot dump kernel log\n"); fprintf(stdout, "====END kernel log====\n"); fprintf(stdout, "====BEGIN userspace log====\n"); fflush(stdout); rv = fork_exec("logcat", "-d", "-v", "time", 0); if (rv < 0) fprintf(stdout, "cannot dump userspace log\n"); fprintf(stdout, "====END userspace log====\n"); fprintf(stdout, "\n Suspend/resume test succeeded %d out of %d times\n", num_success, i); if (num_success == g_num_iter) return EXIT_SUCCESS; else return EXIT_FAILURE; }
int main(int argc, char **argv) { int status; pid_t waited; char *device, *real_device, *physicalDevice = NULL; char *boot = NULL; shvarFile *ifcfg; sigset_t blockedsigs, unblockedsigs; int pppdPid = 0; int timeout = 30; char *temp; gboolean dying = FALSE; int sendsig; gboolean connectedOnce = FALSE; int maxfail = 0; // MAXFAIL Patch <*****@*****.**> if (argc < 2) { fprintf (stderr, "usage: ppp-watch <interface-name> [boot]\n"); exit(30); } if (strncmp(argv[1], "ifcfg-", 6) == 0) { device = argv[1] + 6; } else { device = argv[1]; } detach(device); /* Prepare a child process to monitor pppd. When we return, we'll be in the child. */ if ((argc > 2) && (strcmp("boot", argv[2]) == 0)) { boot = argv[2]; } ifcfg = shvarfilesGet(device); if (ifcfg == NULL) failureExit(28); real_device = svGetValue(ifcfg, "DEVICE"); if (real_device == NULL) real_device = device; doPidFile(real_device); /* We'll want to know which signal interrupted our sleep below, so * attach a signal handler to these. */ set_signal(SIGTERM, signal_tracker); set_signal(SIGINT, signal_tracker); set_signal(SIGHUP, signal_tracker); set_signal(SIGIO, signal_tracker); set_signal(SIGCHLD, signal_tracker); /* We time out only if we're being run at boot-time. */ if (boot) { temp = svGetValue(ifcfg, "BOOTTIMEOUT"); if (temp) { timeout = atoi(temp); if (timeout < 1) timeout = 1; free(temp); } else { timeout = 30; } set_signal(SIGALRM, signal_tracker); alarm(timeout); } /* Register us to get a signal when something changes. Yes, that's vague. */ fork_exec(TRUE, "/sbin/netreport", NULL, NULL, NULL); /* Reset theSigchld, which should have been triggered by netreport. */ theSigchld = 0; /* We don't set up the procmask until after we have received the netreport * signal. Do so now. */ sigemptyset(&blockedsigs); sigaddset(&blockedsigs, SIGTERM); sigaddset(&blockedsigs, SIGINT); sigaddset(&blockedsigs, SIGHUP); sigaddset(&blockedsigs, SIGIO); sigaddset(&blockedsigs, SIGCHLD); if (boot) { sigaddset(&blockedsigs, SIGALRM); } sigprocmask(SIG_BLOCK, &blockedsigs, NULL); sigfillset(&unblockedsigs); sigdelset(&unblockedsigs, SIGTERM); sigdelset(&unblockedsigs, SIGINT); sigdelset(&unblockedsigs, SIGHUP); sigdelset(&unblockedsigs, SIGIO); sigdelset(&unblockedsigs, SIGCHLD); if (boot) { sigdelset(&unblockedsigs, SIGALRM); } sigprocmask(SIG_UNBLOCK, &unblockedsigs, NULL); /* Initialize the retry timeout using the RETRYTIMEOUT setting. */ temp = svGetValue(ifcfg, "RETRYTIMEOUT"); if (temp) { timeout = atoi(temp); free(temp); } else { timeout = 30; } /* Start trying to bring the interface up. */ fork_exec(FALSE, IFUP_PPP, "daemon", device, boot); while (TRUE) { /* Wait for a signal. */ if (!theSigterm && !theSigint && !theSighup && !theSigio && !theSigchld && !theSigalrm) { sigsuspend(&unblockedsigs); } /* If we got SIGTERM or SIGINT, give up and hang up. */ if (theSigterm || theSigint) { theSigterm = theSigint = 0; /* If we've already tried to exit this way, use SIGKILL instead * of SIGTERM, because pppd's just being stubborn. */ if (dying) { sendsig = SIGKILL; } else { sendsig = SIGTERM; } dying = TRUE; /* Get the pid of our child pppd. */ pppLogicalToPhysical(&pppdPid, device, NULL); /* We don't know what our child pid is. This is very confusing. */ if (!pppdPid) { failureExit(35); } /* Die, pppd, die. */ kill(pppdPid, sendsig); if (sendsig == SIGKILL) { kill(-pppdPid, SIGTERM); /* Give it a chance to die nicely, then kill its whole process group. */ usleep(2500000); kill(-pppdPid, sendsig); hangup(ifcfg); failureExit(32); } } /* If we got SIGHUP, reload and redial. */ if (theSighup) { theSighup = 0; /* Free and reload the configuration structure. */ if (ifcfg->parent) svCloseFile(ifcfg->parent); svCloseFile(ifcfg); ifcfg = shvarfilesGet(device); /* Get the PID of our child pppd. */ pppLogicalToPhysical(&pppdPid, device, NULL); kill(pppdPid, SIGTERM); /* We'll redial when the SIGCHLD arrives, even if PERSIST is * not set (the latter handled by clearing the "we've connected * at least once" flag). */ connectedOnce = FALSE; /* We don't want to delay before redialing, either, so cut * the retry timeout to zero. */ timeout = 0; } /* If we got a SIGIO (from netreport, presumably), check if the * interface is up and return zero (via our parent) if it is. */ if (theSigio) { theSigio = 0; pppLogicalToPhysical(NULL, device, &physicalDevice); if (physicalDevice) { if (interfaceIsUp(physicalDevice)) { /* The interface is up, so report a success to a parent if * we have one. Any errors after this we just swallow. */ relay_exitcode(0); connectedOnce = TRUE; alarm(0); } free(physicalDevice); } } /* If we got a SIGCHLD, then pppd died (possibly because we killed it), * and we need to restart it after timeout seconds. */ if (theSigchld) { theSigchld = 0; /* Find its pid, which is also its process group ID. */ waited = waitpid(-1, &status, 0); if (waited == -1) { continue; } /* Now, we need to kill any children of pppd still in pppd's * process group, in case they are hanging around. * pppd is dead (we just waited for it) but there is no * guarantee that its children are dead, and they will * hold the modem if we do not get rid of them. * We have kept the old pid/pgrp around in pppdPid. */ if (pppdPid) { kill(-pppdPid, SIGTERM); /* give it a chance to die nicely */ usleep(2500000); kill(-pppdPid, SIGKILL); hangup(ifcfg); } pppdPid = 0; /* Bail if the child exitted abnormally or we were already * signalled to kill it. */ if (!WIFEXITED(status)) { failureExit(29); } if (dying) { failureExit(WEXITSTATUS(status)); } /* Error conditions from which we do not expect to recover * without user intervention -- do not fill up the logs. */ switch (WEXITSTATUS(status)) { case 1: case 2: case 3: case 4: case 6: case 7: case 9: case 14: case 17: failureExit(WEXITSTATUS(status)); break; default: break; } /* PGB 08/20/02: We no longer retry connecting MAXFAIL times on a failed connect script unless RETRYCONNECT is true. */ if ((WEXITSTATUS(status) == 8) && !svTrueValue(ifcfg, "RETRYCONNECT", FALSE)) { failureExit(WEXITSTATUS(status)); } /* If we've never connected, or PERSIST is set, dial again, up * to MAXFAIL times. */ if ((WEXITSTATUS(status) == 8) || !connectedOnce || svTrueValue(ifcfg, "PERSIST", FALSE)) { /* If we've been connected (i.e., if we didn't force a redial, * but the connection went down) wait for DISCONNECTTIMEOUT * seconds before redialing. */ if (connectedOnce) { connectedOnce = FALSE; temp = svGetValue(ifcfg, "DISCONNECTTIMEOUT"); if (temp) { timeout = atoi(temp); free(temp); } else { timeout = 2; } } sigprocmask(SIG_UNBLOCK, &blockedsigs, NULL); sleep(timeout); sigprocmask(SIG_BLOCK, &blockedsigs, NULL); if (!theSigterm && !theSigint && !theSighup && !theSigio && !theSigchld && !theSigalrm) { fork_exec(FALSE, IFUP_PPP, "daemon", device, boot); } /* Reinitialize the retry timeout. */ temp = svGetValue(ifcfg, "RETRYTIMEOUT"); if (temp) { timeout = atoi(temp); free(temp); } else { timeout = 30; } // Scott Sharkey <*****@*****.**> // MAXFAIL Patch... temp = svGetValue(ifcfg, "MAXFAIL"); if (temp) { maxfail = atoi(temp); free(temp); } else { maxfail = 0; } if ( maxfail != 0 ) { dialCount++; if ( dialCount >= maxfail ) failureExit(WEXITSTATUS(status)); } } else { failureExit(WEXITSTATUS(status)); } } /* We timed out, and we're running at boot-time. */ if (theSigalrm) { failureExit(34); } } }
int mmc_umount_all(const char *mmc_device) { FILE *fp = fopen("/proc/mounts", "r"); if (!fp) fwup_err(EXIT_FAILURE, "/proc/mounts"); char *todo[64] = {0}; int todo_ix = 0; int ultimate_rc = 0; char line[FWUP_BLOCK_SIZE] = {0}; while (!feof(fp) && fgets(line, sizeof(line), fp)) { char devname[64]; char mountpoint[256]; if (sscanf(line, "%63s %255s", devname, mountpoint) != 2) continue; if (strstr(devname, mmc_device) == devname) { // mmc_device is a prefix of this device, i.e. mmc_device is /dev/sdc // and /dev/sdc1 is mounted. if (todo_ix == NUM_ELEMENTS(todo)) fwup_errx(EXIT_FAILURE, "Device mounted too many times"); // strings from /proc/mounts are escaped, so unescape them todo[todo_ix++] = unescape_string(mountpoint); } } fclose(fp); int mtab_exists = (access("/etc/mtab", F_OK) != -1); for (int i = 0; i < todo_ix; i++) { if (mtab_exists) { // If /etc/mtab, then call umount(8) so that // gets updated correctly. int rc = fork_exec("/bin/umount", todo[i]); if (rc != 0) { fwup_warnx("Error calling umount on '%s'", todo[i]); ultimate_rc = -1; } } else { // No /etc/mtab, so call the kernel directly. #if HAS_UMOUNT if (umount(todo[i]) < 0) { fwup_warnx("umount %s", todo[i]); ultimate_rc = -1; } #else // If no umount on this platform, warn, but don't // return failure. fwup_warnx("umount %s: not supported", todo[i]); #endif } } for (int i = 0; i < todo_ix; i++) free(todo[i]); return ultimate_rc; }
int main(int argc, char *argv[], char *envp[]) { char line_buffer[MAX_BUFFER]; // 사용자로부터 입력을 받음 char **command; // parsing된 line에 대한 포인터 int flag_fa; // file append에 대한 플래그 int flag_bg; // background excution에 대한 플래그 FILE *fp = stdout; // redirection file pointer for internal command // ls -al을 저장할 공간과 // less /<fullpath>/readme를 저장할 공간이 필요해 char *alias[] = { "ls", "-al", "less" }; char path_readme[MAX_BUFFER]; // fullpath를 저장할 공간 readme 파일을 위한 것임 // 쉘을 실행하는 방법은 3가지 // 1. myshell이 있는 디렉토리에서 path없이 실행 // ex) ./myshell // 2. 외부 디렉토리에서 myshell을 경로로 실행 // ex) /home/test/myshell // 3. myshell이 있는 디렉토리가 path가 있어서 실행 // ex) myshell // 이런 경우에는 executable한 path를 어떻게 알아내냐? // 아무래도 생각하기에는 // 1번일 가능성이 높은 것으로 사료됨 // 아래의 코드는 1번을 고려해서 작성 strncpy(line_buffer, getcwd(NULL, 0), MAX_BUFFER); // SHELL strncpy(path_readme, line_buffer, MAX_BUFFER); // readme strncat(line_buffer, "/myshell", MAX_BUFFER); // SHELL strncat(path_readme, "/readme", MAX_BUFFER); // readme setenv("SHELL", line_buffer, 1); // 1. ix. if(argv[1]) // for batchfile if(!freopen(argv[1], "r", stdin)) exit(STDIN_FAIL); while(!feof(stdin)) { if(argc < 2) // batchfile에서는 프롬프트 안나오게 하기 위해서 printf("%s>", getcwd(NULL, 0)); if(fgets(line_buffer, MAX_BUFFER, stdin)) { flag_fa = OFF; flag_bg = OFF; if(fp != stdout) fclose(fp); command = line_parser(line_buffer, &flag_fa, &flag_bg); // 이쪽 아래로는 line_buffer를 // strcpy나 strcat 용도로 사용해도 괜찮음 if(command[CMD_RUN]) { // internal command alias // 왜 내부 커맨드 + .. 하면 디렉토리가 변경되는거지? // 파싱을 잘못해섴 // NULL을 마지막에 넣어주지 않았기 때문임 // 내부 커맨드의 리다이렉션을 위한 파일 오픈 if(NULL == (fp = fopen(command[CMD_STDOUT], flag_fa ? "a" : "w"))) fp = stdout; //pstatus(command, fp, flag_fa, flag_bg); switch(internal_cmd(command[CMD_RUN])) { case i_cd: // OLDPWD도 갱신해야하나? 우선은 갱신해놓기로 함 { // 물론 아래의 선언은 필요하지 않다 // 그렇지만 일관성 측면에서는 더 좋은거 같기도 하다 char *target_dir = command[CMD_RUN + 1]; if(target_dir) if(chdir(target_dir)) printf("%s : No such directory\n", target_dir); else { setenv("OLDPWD", getenv("PWD"), 1); setenv("PWD", getcwd(NULL, 0), 1); } else printf("%s\n", getcwd(NULL, 0)); } continue; case i_dir: // internal command and alias이기 때문에 // ls -al로 실행하면 될꺼 같다 // 문제는 뭐냐면 ls a b c 이런것도 가능하다는거다... // arg는 최대 64개를 넘지 않는다고 가정한다 { int arg_counter = CMD_RUN; while(command[arg_counter++]) ; while(arg_counter-- > CMD_RUN + 2) command[arg_counter] = command[arg_counter - 1]; command[CMD_RUN] = alias[0]; // ls command[CMD_RUN + 1] = alias[1]; // -al //pstatus(command, fp, flag_fa, flag_bg); } break; case i_environ: { char **env = envp; while(*env) fprintf(fp, "%s\n", *env++); fprintf(fp, "\n"); } continue; case i_clr: { fprintf(stdout, "[H[2J"); fflush(stdout); } continue; case i_echo: { char **comment = command + CMD_RUN; while(*++comment) fprintf(fp, "%s ", *comment); fprintf(fp, "\n"); } continue; case i_help: { // index 접근법을 좀 바꿀까? command[CMD_RUN] = alias[2]; // less command[CMD_RUN + 1] = path_readme; command[CMD_RUN + 2] = NULL; } break; case i_pause: { pdebug("pause"); struct termios term; // echo off tcgetattr(STDIN_FILENO, &term); term.c_lflag ^= ECHO; tcsetattr(STDIN_FILENO, TCSANOW, &term); printf("Press Enter to continue...\n"); fgets(line_buffer, MAX_BUFFER, stdin); // echo on tcgetattr(STDIN_FILENO, &term); // 이건 없어도 작동할듯? term.c_lflag ^= ECHO; tcsetattr(STDIN_FILENO, TCSANOW, &term); } continue; case i_myshell: // for batchfile { command[CMD_RUN] = getenv("SHELL"); } break; case i_quit: exit(0); } fork_exec(command, flag_fa, flag_bg); } } } exit(0); // return 0도 물론 가능하지만 // forking과 exec를 하므로 // 좀더 안전하지 않을까? }
/* create or wait for an NFS-safe lockfile and fetch url with curl or wget */ int fetch(char *url, const char *destdir) { int lockfd, status=0; char outfile[PATH_MAX], partfile[PATH_MAX]; char *name, *p; struct flock fl = { .l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = 1, .l_len = 0, }; struct cmdarray curlcmd = { .argc = 5, .argv = { "curl", "-L", "-f", "-o", partfile, NULL } }; struct cmdarray wgetcmd = { .argc = 3, .argv = { "wget", "-O", partfile, NULL } }; name = strrchr(url, '/'); if (name == NULL) errx(1, "%s: no '/' in url", url); p = strstr(url, "::"); if (p != NULL) { name = url; *p = '\0'; url = p + 2; } else { name++; } snprintf(outfile, sizeof(outfile), "%s/%s", destdir, name); snprintf(lockfile, sizeof(lockfile), "%s.lock", outfile); snprintf(partfile, sizeof(partfile), "%s.part", outfile); lockfd = open(lockfile, O_WRONLY|O_CREAT, 0660); if (lockfd < 0) err(1, "%s", lockfile); if (fcntl(lockfd, F_SETLK, &fl) < 0) { int i; printf("Waiting for %s ...\n", lockfile); for (i=0; i<10; i++) { int r = fcntl(lockfd, F_SETLKW, &fl); if (r == 0) break; if (r == -1 && errno != ESTALE) err(1, "fcntl(F_SETLKW)"); sleep(1); } } if (access(outfile, F_OK) == 0) goto fetch_done; if (access(partfile, F_OK) == 0) { printf("Partial download found. Trying to resume.\n"); add_opt(&curlcmd, "-C"); add_opt(&curlcmd, "-"); add_opt(&wgetcmd, "-c"); } add_opt(&curlcmd, url); add_opt(&wgetcmd, url); status = fork_exec(curlcmd.argv, 0); /* CURLE_RANGE_ERROR (33) The server does not support or accept range requests. */ if (status == 33) unlink(partfile); /* is we failed execute curl, then fallback to wget */ if (status == 201) status = fork_exec(wgetcmd.argv, 1); /* only rename completed downloads */ if (status == 0) rename(partfile, outfile); fetch_done: unlink(lockfile); close(lockfd); lockfile[0] = '\0'; return status; } void sighandler(int sig) { switch(sig) { case SIGABRT: case SIGINT: case SIGQUIT: case SIGTERM: unlink(lockfile); exit(0); break; default: break; } } /* exit codes get passed through from curl/wget (so we can check in abuild whether the server does not support resuming). Additional exit codes: 200: fork failed 201: curl/wget could not be started 202: curl/wget did not terminate normally 203: usage displayed */ int main(int argc, char *argv[]) { int opt; char *destdir = "/var/cache/distfiles"; program = argv[0]; while ((opt = getopt(argc, argv, "hd:")) != -1) { switch (opt) { case 'h': return usage(0); break; case 'd': destdir = optarg; break; default: printf("Unknown option '%c'\n", opt); return usage(1); break; } } argv += optind; argc -= optind; if (argc != 1) return usage(203); signal(SIGABRT, sighandler); signal(SIGINT, sighandler); signal(SIGQUIT, sighandler); signal(SIGTERM, sighandler); return fetch(argv[0], destdir); }