Пример #1
0
/* Report an error to the user and return EXECUTION_FAILURE. */
int
mpibash_report_mpi_error (int mpierr)
{
  char errstr[MPI_MAX_ERROR_STRING];
  int errstrlen;

  MPI_Error_string(mpierr, errstr, &errstrlen);
  builtin_error("%s", errstr);
  return EXECUTION_FAILURE;
}
Пример #2
0
int					b_history(t_context *context, t_list *args)
{
	size_t			arg_count;

	arg_count = ft_lstsize(args);
	if (arg_count > 3)
		return (builtin_error(HISTORY_BUILTIN, ERR_TOO_MANY_ARGS, 0));
	if (arg_count == 1)
		return (history_display(context, 0, 0));
	return (BUILTIN_SUCCESS);
}
Пример #3
0
int			b_pid(t_context *context, t_list *args)
{
	size_t	arg_count;

	UNUSED(context);
	arg_count = ft_lstsize(args);
	if (arg_count > 1)
		return (builtin_error(PID_BUILTIN, ERR_TOO_MANY_ARGS, 0));
	ft_putnbr(getpid());
	ft_putchar('\n');
	return (BUILTIN_SUCCESS);
}
Пример #4
0
int			b_exit(t_context *context, t_list *args)
{
	size_t	arg_count;
	int		exit_code;

	arg_count = ft_lstsize(args);
	if (arg_count > 2)
		return (builtin_error(EXIT_BUILTIN, ERR_TOO_MANY_ARGS, 0));
	exit_code = EXIT_SUCCESS;
	if (arg_count == 2)
		exit_code = ft_atoi(token_value(args, 2));
	shell_exit(context, exit_code);
	return (BUILTIN_SUCCESS);
}
Пример #5
0
int			b_unsetenv(t_context *context, t_list *args)
{
	size_t	arg_count;
	size_t	i;

	arg_count = ft_lstsize(args);
	if (arg_count == 1)
		return (builtin_error(UNSETENV_BUILTIN, ERR_TOO_FEW_ARGS, 0));
	i = 1;
	while (i < arg_count)
	{
		environ_remove(context, token_value(args, i + 1));
		++i;
	}
	return (BUILTIN_SUCCESS);
}
Пример #6
0
// Given an appropriate format and an ffi_type, create a prefixed type from
// value and store in *result, which should be freed by the caller.
char * encode_primitive_type(const char *format, ffi_type *type, void *value)
{
    char *result;

    switch (type->size) {
        case  1: asprintf(&result, format, *(uint8_t  *) value); break;
        case  2: asprintf(&result, format, *(uint16_t *) value); break;
        case  4: asprintf(&result, format, *(uint32_t *) value,  *(float *) value); break;
        case  8: asprintf(&result, format, *(uint64_t *) value, *(double *) value); break;
        case 16: asprintf(&result, format, *(long double *) value); break;
        default:
            builtin_error("cannot handle size %lu", type->size);
            return NULL;
    }

    return result;
}
Пример #7
0
/* Look up a user-provided callback function. */
int
mpibash_find_callback_function (WORD_LIST *list, SHELL_VAR **user_func)
{
  char *funcname;     /* Name of the user-defined function. */

  /* If no argument was provided, nullify the callback function. */
  if (list == NULL) {
    *user_func = NULL;
    return EXECUTION_SUCCESS;
  }

  /* Get the callback function. */
  funcname = list->word->word;
  list = list->next;
  no_args(list);
  *user_func = find_function(funcname);
  if (*user_func == NULL) {
    builtin_error(_("function %s not found"), funcname);
    return EXECUTION_FAILURE;
  }
  return EXECUTION_SUCCESS;
}
Пример #8
0
// Usage:
//
//  dlopen [-N] [-t] [-d] [-g] [-n] [library] [RTLD_NODELETE|RTLD_GLOBAL|...] [...]
//
static int open_dynamic_library(WORD_LIST *list)
{
    char varname[1024];
    char value[1024];
    uint32_t flags;
    void *handle;
    int opt;

    reset_internal_getopt();

    flags   = RTLD_LAZY;
    handle  = NULL;

    // Options can either be specified as bash-like flags, or as a list. The
    // bash-like flags look like this:
    //
    // $ dlopen -tg libc.so
    //
    while ((opt = internal_getopt(list, "lNtdgn")) != -1) {
        switch (opt) {
                // RTLD_LAZY and RTLD_NOW are mutually exclusive.
            case 'l':
                flags = (flags & ~RTLD_NOW) | RTLD_LAZY;
                break;
            case 'N':
                flags = (flags & ~RTLD_LAZY) | RTLD_NOW;
                break;
            case 't':
                flags |= RTLD_NOLOAD;
                break;
            case 'd':
                flags |= RTLD_DEEPBIND;
                break;
            case 'g':
                flags |= RTLD_GLOBAL;
                break;
            case 'n':
                flags |= RTLD_NODELETE;
                break;
            default:
                builtin_usage();
                return EX_USAGE;
        }
    }

    // Skip past any options.
    if ((list = loptend) == NULL) {
        builtin_usage();
        return 1;
    }

    // Check and decode parameters, which can be specified as strings.
    //
    // $ dlopen libc.so RTLD_LAZY RTLD_NODELETE
    //
    // or, as an integer
    //
    // $ dlopen libc.so 0x10101
    //
    if (list->next) {
        WORD_LIST *flaglist = list->next;

        // Caller wants more control over flags, so reset and decode the flags
        // specified.
        for (flags = 0; flaglist; flaglist = flaglist->next) {
            flags |= rtld_flags_decode(flaglist->word->word);
        }
    }

    // Now list->word is the library name.
    if (!(handle = dlopen(list->word->word, flags))) {
        builtin_error("dlopen(\"%s\", %#x) failed, %s", list->word->word, flags, dlerror());
        return 1;
    }

    // Print the handle, although this is not usable unless being used interactively.
    printf("%p\n", handle);

    snprintf(varname, sizeof varname, "DLHANDLES[\"%s\"]", basename(list->word->word));
    snprintf(value, sizeof value, "%p", handle);

    // Make the handle available programmatically.
    if (assign_array_element(varname, value, 4) == NULL) {
        builtin_error("failed to append element to $DLHANDLES array");
        return 1;
    }

    return 0;
}
Пример #9
0
// Usage:
//
// dlcall $RTLD_DEFAULT "printf" "hello %s %u %c" $USER 123 int:10
//
static int call_foreign_function(WORD_LIST *list)
{
    unsigned nargs;
    int opt;
    ffi_cif cif;
    ffi_type **argtypes;
    ffi_type *rettype;
    void **values;
    void *handle;
    void *func;
    char *prefix;
    char *format;
    char *resultname;

    nargs       = 0;
    argtypes    = NULL;
    values      = NULL;
    format      = NULL;
    prefix      = NULL;
    rettype     = &ffi_type_void;
    resultname  = "DLRETVAL";

    reset_internal_getopt();

    // $ dlcall [-a abi] [-r type] [-n name]
    while ((opt = internal_getopt(list, "a:r:n:")) != -1) {
        switch (opt) {
            case 'a':
                builtin_warning("FIXME: only abi %u is currently supported", FFI_DEFAULT_ABI);
                return 1;
                break;
            case 'r':
                if (decode_type_prefix(prefix = list_optarg, NULL, &rettype, NULL, &format) != true) {
                    builtin_warning("failed to parse return type");
                    return 1;
                }
                break;
            case 'n':
                resultname = list_optarg;
                break;
            default:
                builtin_usage();
                return 1;
        }
    }

    // Skip past any options.
    if ((list = loptend) == NULL || list->next == NULL) {
        builtin_usage();
        return 1;
    }

    if (check_parse_ulong(list->word->word, (void *) &handle) == 0) {
        builtin_warning("handle %s %p is not well-formed", list->word->word, handle);
        return 1;
    }

    if (!(func = dlsym(handle, list->next->word->word))) {
        builtin_warning("failed to resolve symbol %s, %s", list->next->word->word, dlerror());
        return 1;
    }

    // Skip to optional parameters
    list = list->next->next;

    while (list) {
        argtypes = realloc(argtypes, (nargs + 1) * sizeof(ffi_type *));
        values   = realloc(values, (nargs + 1) * sizeof(void *));

        if (decode_primitive_type(list->word->word, &values[nargs], &argtypes[nargs]) != true) {
            builtin_error("failed to decode type from parameter %s", list->word->word);
            goto error;
        }

        nargs++;
        list = list->next;
    }

    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, nargs, rettype, argtypes) == FFI_OK) {
        char *retval;
        void *rc = alloca(rettype->size);

        // Do the call.
        ffi_call(&cif, func, rc, values);

        // Print the result.
        if (format) {
            switch (rettype->size) {
                case  1: asprintf(&retval, format, *(uint8_t  *) rc); break;
                case  2: asprintf(&retval, format, *(uint16_t *) rc); break;
                case  4: asprintf(&retval, format, *(uint32_t *) rc, *(float *) rc); break;
                case  8: asprintf(&retval, format, *(uint64_t *) rc, *(double *) rc); break;
                case 16: asprintf(&retval, format, *(long double *) rc); break;
                default:
                    builtin_error("cannot handle size %lu", rettype->size);
                    abort();
            }

            fprintf(stderr, "%s\n", retval);
            bind_variable(resultname, retval, 0);
            free(retval);
        }
    }

    for (unsigned i = 0; i < nargs; i++)
        free(values[i]);
    free(values);
    free(argtypes);
    return 0;

  error:
    for (unsigned i = 0; i < nargs; i++)
        free(values[i]);
    free(values);
    free(argtypes);
    return 1;
}
Пример #10
0
/**************************
*** CLIENT LISTENING THREAD
**************************/
void* client_thread(void *socket)
{
    // Get the socket
    int socket_fd = *((int*)socket);

    // Redirect SIGUSR signal
    sigset_t mask;
    sigset_t fdmask;

    // Handle SIGUSR1
    sigemptyset(&fdmask);
    sigaddset(&fdmask, SIGUSR1);

    // We need to block SIGUSR2 and SIGINT to they are handled by main thread
    sigemptyset(&mask);
    sigaddset(&mask, SIGUSR2);
    sigaddset(&mask, SIGINT);

    // Block SIGUSR1/2 SIGINT
    if(pthread_sigmask(SIG_BLOCK, &mask, NULL) < 0)
    {
        if(close(socket_fd) < 0)
        {
            ERROR("Can't close client socket", strerror(errno));
        }
        ERROR("Can't block signal in client thread", strerror(errno));
        pthread_mutex_lock(&client_count_mutex);
        --client_count;
        pthread_mutex_unlock(&client_count_mutex);
        return NULL;
    }

    // Block SIGUSR1
    if(pthread_sigmask(SIG_BLOCK, &fdmask, NULL) < 0)
    {
        if(close(socket_fd) < 0)
        {
            ERROR("Can't close client socket", strerror(errno));
        }
        ERROR("Can't block signal in client thread", strerror(errno));
        pthread_mutex_lock(&client_count_mutex);
        --client_count;
        pthread_mutex_unlock(&client_count_mutex);
        return NULL;
    }

    // Redirect SIGUSR1 to fd
    int sigusr_fd = signalfd(-1, &fdmask, 0);
    if(sigusr_fd < 0)
    {
        if(close(socket_fd) < 0)
        {
            ERROR("Can't close client socket", strerror(errno));
        }
        ERROR("Can't redirect signal in client thread", strerror(errno));
        pthread_mutex_lock(&client_count_mutex);
        --client_count;
        pthread_mutex_unlock(&client_count_mutex);
        return NULL;
    }

    // Message management
    char message[MAX_BUF];
    char *saved_decomp;

    // Buffering management
    int buffering = FALSE;
    char message_buffer[MAX_BUF];

    // Sockets set
    fd_set in_desc;

    // Timeout setting
    struct timeval timeout_set;
    timeout_set.tv_sec = TIMEOUT_V;
    timeout_set.tv_usec = 1000 * TIMEOUT_V;

    int listening = TRUE;
    int usrquit = FALSE;

    while(listening)
    {
        // Setting the file desciptors set
        FD_ZERO(&in_desc);
        FD_SET(sigusr_fd, &in_desc);
        FD_SET(socket_fd, &in_desc);

        int max = sigusr_fd;
        if(sigusr_fd < socket_fd)
            max = socket_fd;

        // Select the socket to watch
        if(select(max + 1, &in_desc , NULL , NULL , &timeout_set) < 0 && (errno != EINTR))
        {
            ERROR("Error while selecting client sockets", strerror(errno));
            if(close(socket_fd) < 0)
            {
                ERROR("Can't close client socket", strerror(errno));
            }
            pthread_mutex_lock(&client_count_mutex);
            --client_count;
            pthread_mutex_unlock(&client_count_mutex);
            return NULL;
        }

        // If received SIGUSR1
        if(FD_ISSET(sigusr_fd, &in_desc))
        {
            struct signalfd_siginfo si;
            ssize_t length;

            // Read signal
            if((length = read(sigusr_fd, &si, sizeof(si))) < 0)
            {
                ERROR("Error while reading sigusr1 file descriptor", strerror(errno));
            }
            if (length != sizeof(si))
            {
                ERROR("Error while reading sigusr1 file descriptor", strerror(errno));
            }

            // Handle signal
            if (si.ssi_signo == SIGUSR1)
            {
                // Stop listening and get out of loop
                char message[17] = "Server shutdown\n\0";
                send_to(socket_fd, message);
                listening = FALSE;
                usrquit = TRUE;
                break;
            }
            else
            {
                ERROR("Error, received an unhandled signal", "UNKNOWN SIGNAL");
            }
        }

        // If client socket changed state
        if(FD_ISSET(socket_fd, &in_desc))
        {
            size_t length;
            memset(message, 0, sizeof(message));
            if((length = read(socket_fd, &message, MAX_BUF)) > 0)
            {
                // Manage command buffering
                if(message[length - 1] != '\n')
                {
                    if(!buffering)
                        message_buffer[0] = '\0';

                    // Fill buffer
                    buffering = TRUE;
                    strncat(message_buffer, message, length);
                    continue;
                }
                else if(buffering)
                {
                    // Get all buffer value
                    buffering = FALSE;
                    strncat(message_buffer, message, length);
                    strncpy(message, message_buffer, strlen(message_buffer));
                }

                // Manage multiple command per line
                char *saved_decomp;
                char *decomp_command = strtok_r(message, "\n", &saved_decomp);
                while(decomp_command)
                {
                    // Get command
                    char *saved_ptr;
                    char *command = strtok_r(decomp_command, " ", &saved_ptr);

                    // Get function
                    int (*function) (void*, void*) = NULL;

                    {
                        int i;
                        for(i = 0; bltins[i].cmd; ++i)
                        {
                            if(strcmp(bltins[i].cmd, command) == 0)
                            {
                                function = bltins[i].function;
                                break;
                            }
                        }
                    }

                    if(function != NULL)
                    {
                        void *state = NULL;
                        size_t arguments_count = 1;
                        size_t arguments_remai = 1;
                        size_t argc = 0;

                        // Init arguments structure
                        struct args_s *arguments_s = malloc(sizeof(struct args_s));
                        arguments_s->socket = socket_fd;
                        arguments_s->args = malloc(sizeof(char*) * arguments_count);

                        // Get arguments
                        char *parameters = strtok_r(NULL, "", &saved_ptr);
                        while(parameters)
                        {
                            char *argument = strtok_r(parameters, " ", &saved_ptr);

                            // Dynamic allocation
                            if(arguments_remai-- == 0)
                            {
                                arguments_remai = arguments_count;
                                arguments_count *= 2;
                                arguments_s->args = realloc(arguments_s->args, sizeof(char*) * arguments_count);
                            }
                            // Add argument
                            arguments_s->args[argc] = malloc(sizeof(char) * strlen(argument) + 1);
                            arguments_s->args[argc][0] = '\0';
                            strncpy(arguments_s->args[argc], argument, strlen(argument));
                            arguments_s->args[argc][strlen(argument)] = '\0';

                            ++argc;
                            parameters = strtok_r(NULL, "", &saved_ptr);
                        }

                        // End the args array with NULL
                        if(arguments_remai)
                        {
                            arguments_s->args[argc] = NULL;
                        }
                        else
                        {
                            arguments_s->args = realloc(arguments_s->args, sizeof(char*) * argc + 1);
                            arguments_s->args[argc] = NULL;
                        }

                        // Call function
                        INFO("Client command:");
                        INFO(command);
                        listening = function(arguments_s, state);

                        // Free memory
                        {
                            int i;
                            for(i = 0; arguments_s->args[i]; ++i)
                            {
                                free(arguments_s->args[i]);
                            }
                            free(arguments_s->args);
                            free(arguments_s);
                        }
                    }
                    else
                    {
                        // Wrong command, log server and avert client
                        WARNING("Client asked for an unknown command", command);

                        struct args_s *arguments_s = malloc(sizeof(struct args_s));
                        arguments_s->socket = socket_fd;
                        builtin_error(arguments_s , NULL);
                        free(arguments_s);
                    }
                    char *get_back_command = strtok_r(NULL, "", &saved_decomp);
                    decomp_command = strtok_r(get_back_command, "\n", &saved_decomp);
                }
            }
            else if(length == 0)
            {
                // Client disconnected
                listening = FALSE;
            }
            else
            {
                // Error while reading
                ERROR("Error while reading socket", strerror(errno));
            }

        }
    }
    // Close connection socket
    if(close(socket_fd) < 0)
    {
        ERROR("Can't close client socket", strerror(errno));
    }

    // Close binded signale file descriptor
    if(close(sigusr_fd) < 0)
    {
        ERROR("Can't close client sigusr file descriptor", strerror(errno));
    }
    INFO("Client thread disconnected");
    pthread_mutex_lock(&client_count_mutex);
    --client_count;
    pthread_mutex_unlock(&client_count_mutex);

    if(!usrquit)
    {
        union sigval sv;
        sv.sival_int = socket_fd;

        if(sigqueue(getpid(), SIGUSR2, sv) < 0)
        {
            ERROR("Can't send signal to main thread", strerror(errno));
        }
    }

    return NULL;
} // void* client_thread(void*)
Пример #11
0
/* change working directory
 * ----------------------------------------------------------------------- */
int builtin_cd(int argc, char **argv) {
  int c;
  int ok = 0;
  int symbolic = 1;
  const char *arg;
  unsigned long len;
  unsigned long n;
  stralloc newcwd;
  
  /* check options, -L for symlink, -P for physical path */
  while((c = shell_getopt(argc, argv, "LP")) > 0) {
    switch(c) {
      case 'L': symbolic = 1; break;
      case 'P': symbolic = 0; break;
      default: builtin_invopt(argv); return 1;
    }
  }
  
  arg = argv[shell_optind];
  stralloc_init(&newcwd);

  /* empty argument means chdir(HOME) */
  if(arg == NULL) {
    arg = var_value("HOME", &len);

    if(arg[0] == '\0') {
      sh_msg("HOME variable not set!");
      return 1;
    }
  }

  len = str_len(arg);
  
  /* when it isn't an absolute path we have to check CDPATH */
  if(arg[0] != '/') {
    char path[PATH_MAX + 1];
    const char *cdpath;

    /* loop through colon-separated CDPATH variable */
    cdpath = var_value("CDPATH", NULL);

    do {
      /* too much, too much :) */
      if((n = str_chr(cdpath, ':')) + len + 1 > PATH_MAX) {
        /* set error code and print the longer string in the error msg */
        errno = ENAMETOOLONG;
        return builtin_errmsgn(argv, (n > len ? cdpath : arg),
                               (n > len ? n : len), strerror(errno));
      }
      
      /* copy path prefix from cdpath if present */
      if(n) {
        byte_copy(path, n, cdpath);
        cdpath += n;
        path[n++] = '/';
      }
      
      /* copy the argument and canonicalize */
      str_copy(&path[n], arg);

      ok = shell_realpath(path, &newcwd, symbolic, &sh->cwd);

      /* skip the colon */
      if(*cdpath == ':')
        cdpath++;
    } while(*cdpath && !ok);

  }
  /* absolute path */
  else {
    /* last cdpath length set to 0, because we're not using cdpath here */
    n = 0;
    ok = shell_canonicalize(arg, &newcwd, symbolic);
  }
  
  stralloc_nul(&newcwd);

  /* try to chdir() if everything's ok */
  if(ok && chdir(newcwd.s) == 0) {
    /* print path if prefix was taken from cdpath */
    if(n) {
      buffer_putsa(fd_out->w, &newcwd);
      buffer_putnlflush(fd_out->w);
    }
    
    /* set the path */
    stralloc_move(&sh->cwd, &newcwd);

    /* if the path has symlinks then set sh->cwdsym */
    sh->cwdsym = (ok > 1);

    return 0;
  }
  
  /* we failed */
  builtin_error(argv, newcwd.s);
  stralloc_free(&newcwd);
  return 1;
}
Пример #12
0
// Usage:
//
// dlcall "printf" "hello %s %u %c" $USER 123 int:10
//
static int call_foreign_function(WORD_LIST *list)
{
    unsigned nargs;
    unsigned i;
    int opt;
    ffi_cif cif;
    ffi_type **argtypes;
    ffi_type *rettype;
    void **values;
    void *handle;
    void *func;
    char *prefix;
    char *format;
    char *resultname;

    nargs       = 0;
    argtypes    = NULL;
    values      = NULL;
    format      = NULL;
    prefix      = NULL;
    rettype     = &ffi_type_void;
    resultname  = "DLRETVAL";
    handle      = RTLD_DEFAULT;

    reset_internal_getopt();

    // $ dlcall [-a abi] [-r type] [-n name] [-h handle] symbol args...
    while ((opt = internal_getopt(list, "h:a:r:n:")) != -1) {
        switch (opt) {
            case 'a':
                builtin_warning("FIXME: only abi %u is currently supported", FFI_DEFAULT_ABI);
                return 1;
                break;
            case 'r':
                if (decode_type_prefix(prefix = list_optarg, NULL, &rettype, NULL, &format) != true) {
                    builtin_warning("failed to parse return type");
                    return 1;
                }
                break;
            case 'n':
                resultname = list_optarg;
                break;
            case 'h':
                if (check_parse_ulong(list_optarg, (void *) &handle) == 0) {
                    builtin_warning("handle %s %p is not well-formed", list_optarg, handle);
                    return EXECUTION_FAILURE;
                }
                break;
            default:
                builtin_usage();
                return EX_USAGE;
        }
    }

    // Skip past any options.
    if ((list = loptend) == NULL) {
        builtin_usage();
        return EX_USAGE;
    }

    if (!(func = dlsym(handle, list->word->word))) {
        builtin_warning("failed to resolve symbol %s, %s", list->word->word, dlerror());
        return 1;
    }

    // Skip to optional parameters
    list = list->next;

    while (list) {
        argtypes = realloc(argtypes, (nargs + 1) * sizeof(ffi_type *));
        values   = realloc(values, (nargs + 1) * sizeof(void *));

        if (decode_primitive_type(list->word->word, &values[nargs], &argtypes[nargs]) != true) {
            builtin_error("failed to decode type from parameter %s", list->word->word);
            goto error;
        }

        nargs++;
        list = list->next;
    }

    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, nargs, rettype, argtypes) == FFI_OK) {
        char *retval;
        void *rc = alloca(rettype->size);

        // Do the call.
        ffi_call(&cif, func, rc, values);

        // Decode the result.
        if (format) {
            retval = encode_primitive_type(format, rettype, rc);

            // If this is an interactive shell, print the output.
            if (interactive_shell) {
                fprintf(stderr, "%s\n", retval);
            }

            // Save the result to the requested location.
            bind_variable(resultname, retval, 0);

            // Bash maintains it's own copy of this string, so we can throw it away.
            free(retval);
        }
    }

    for (i = 0; i < nargs; i++)
        free(values[i]);
    free(values);
    free(argtypes);
    return 0;

  error:
    for (i = 0; i < nargs; i++)
        free(values[i]);
    free(values);
    free(argtypes);
    return 1;
}
Пример #13
0
/* sets or displays current hostname
 * ----------------------------------------------------------------------- */
int builtin_hostname(int argc, char **argv) {
  int c;
  int force = 0;
  
  /* check options */
  while((c = shell_getopt(argc, argv, "f")) > 0) {
    switch(c) {
      case 'f': force = 1; break;
      default: builtin_invopt(argv); return 1;
    }
  }
  
  /* if there is an argument we set it as new hostname */
  if(argv[shell_optind]) {
    unsigned long n;
    
    n = str_len(argv[shell_optind]);
    
    /* unless force is set and if the new hostname is 
       the same as the current then do not update it */
    if(!force && n == sh_hostname.len && 
       !byte_diff(sh_hostname.s, n, argv[shell_optind]))
      return 0;
      
#ifdef HAVE_SETHOSTNAME    
    /* set the supplied hostname */
#if !defined(__CYGWIN__) && !defined(__MINGW32__)
    if(sethostname(argv[shell_optind], n))
#else
    errno = ENOSYS;
#endif
    {
      /* report any error */
      builtin_error(argv, "sethostname");
      return 1;
    }
#endif
    
    /* on success update internal hostname */
    stralloc_copyb(&sh_hostname, argv[shell_optind], n);
  }
  /* if there is no argument we display the current hostname */
  else {
    /* force re-get of hostname by clearing it now */
    if(force)
      stralloc_zero(&sh_hostname);
    
    /* get hostname if it isn't there */
    if(sh_hostname.len == 0)
      shell_gethostname(&sh_hostname);
    
    /* report errors */
    if(sh_hostname.len == 0) {
      builtin_error(argv, "gethostname");
      return 1;
    }
    
    /* finally output the hostname */
    buffer_putsa(fd_out->w, &sh_hostname);
    buffer_putnlflush(fd_out->w);
  }
  
  return 0;
}
Пример #14
0
static int generate_native_callback(WORD_LIST *list)
{
    int nargs;
    void *callback;
    ffi_cif *cif;
    ffi_closure *closure;
    ffi_type **argtypes;
    ffi_type *rettype;
    char **proto;
    char *resultname = "DLRETVAL";
    char opt;
    reset_internal_getopt();

    // $ dlcall [-a abi] [-r type] [-n name]
    while ((opt = internal_getopt(list, "a:r:n:")) != -1) {
        switch (opt) {
            case 'n':
                resultname = list_optarg;
                break;
            default:
                builtin_usage();
                return EX_USAGE;
        }
    }

    // Skip past any options.
    if ((list = loptend) == NULL || !list->next) {
        builtin_usage();
        return EX_USAGE;
    }

    closure     = ffi_closure_alloc(sizeof(ffi_closure), &callback);
    cif         = malloc(sizeof(ffi_cif));
    argtypes    = NULL;
    proto       = malloc(sizeof(char *));
    proto[0]    = strdup(list->word->word);
    nargs       = 0;
    list        = list->next;

    // Second parameter must be the return type
    if (decode_type_prefix(list->word->word,
                           NULL,
                           &rettype,
                           NULL,
                           NULL) != true) {
        builtin_warning("couldnt parse the return type %s", list->word->word);
        return EXECUTION_FAILURE;
    }

    // Skip past return type
    list = list->next;

    while (list) {
        argtypes        = realloc(argtypes, (nargs + 1) * sizeof(ffi_type *));
        proto           = realloc(proto, (nargs + 1 + 1) * sizeof(char *));

        if (decode_type_prefix(list->word->word, NULL, &argtypes[nargs], NULL, &proto[nargs+1]) != true) {
            builtin_error("failed to decode type from parameter %s", list->word->word);
            goto error;
        }

        list = list->next;
        nargs++;
    }

    if (ffi_prep_cif(cif, FFI_DEFAULT_ABI, nargs, rettype, argtypes) == FFI_OK) {
        // Initialize the closure.
        if (ffi_prep_closure_loc(closure, cif, execute_bash_trampoline, proto, callback) == FFI_OK) {
            char retval[1024];
            snprintf(retval, sizeof retval, "pointer:%p", callback);
            fprintf(stderr, "%s\n", retval);
            bind_variable(resultname, retval, 0);
        }
    }

    //free(argtypes);
    return 0;

  error:
    //free(argtypes);
    return 1;
}