~martin-decky/helenos/rcu

« back to all changes in this revision

Viewing changes to uspace/app/bdsh/cmds/builtins/cd/cd.c

  • Committer: Vojtech Horky
  • Date: 2012-05-23 12:03:26 UTC
  • mfrom: (1443.1.19 misc)
  • mto: This revision was merged to the branch mainline in revision 1479.
  • Revision ID: vojtechhorky@users.sourceforge.net-20120523120326-jv50stjymxmh598s
Merge GSOC-originated patches 

Merge from lp:~vojtech-horky/helenos/misc.

The merge includes:
 * Switching to previous directory with `cd -' in Bdsh
 * Interactive mode for cp module in Bdsh
 * Implementation of sleep command
 * printf and echo for Bdsh
 * Rewrite of the mkdir module
 * Ctrl-arrow jumps over words in the editor
 * The scripts work with Python 3

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
 
41
41
static const char *cmdname = "cd";
42
42
 
 
43
/* Previous directory variables.
 
44
 *
 
45
 * Declaring them static to avoid many "== NULL" checks.
 
46
 * PATH_MAX is not that big to cause any problems with memory overhead.
 
47
 */
 
48
static char previous_directory[PATH_MAX] = "";
 
49
static char previous_directory_tmp[PATH_MAX];
 
50
static bool previous_directory_valid = true;
 
51
static bool previous_directory_set = false;
 
52
 
 
53
static int chdir_and_remember(const char *new_dir) {
 
54
 
 
55
        char *ok = getcwd(previous_directory_tmp, PATH_MAX);
 
56
        previous_directory_valid = ok != NULL;
 
57
        previous_directory_set = true;
 
58
 
 
59
        int rc = chdir(new_dir);
 
60
        if (rc != EOK) {
 
61
                return rc;
 
62
        }
 
63
 
 
64
        str_cpy(previous_directory, PATH_MAX, previous_directory_tmp);
 
65
        return EOK;
 
66
}
 
67
 
43
68
void help_cmd_cd(unsigned int level)
44
69
{
45
70
        if (level == HELP_SHORT) {
54
79
        return;
55
80
}
56
81
 
 
82
 
57
83
/* This is a very rudamentary 'cd' command. It is not 'link smart' (yet) */
58
84
 
59
85
int cmd_cd(char **argv, cliuser_t *usr)
62
88
 
63
89
        argc = cli_count_args(argv);
64
90
 
 
91
        /* Handle cd -- -. Override to switch to a directory named '-' */
 
92
        bool hyphen_override = false;
 
93
        char *target_directory = argv[1];
 
94
        if (argc == 3) {
 
95
                if (!str_cmp(argv[1], "--")) {
 
96
                        hyphen_override = true;
 
97
                        argc--;
 
98
                        target_directory = argv[2];
 
99
                }
 
100
        }
 
101
 
65
102
        /* We don't yet play nice with whitespace, a getopt implementation should
66
103
         * protect "quoted\ destination" as a single argument. Its not our job to
67
104
         * look for && || or redirection as the tokenizer should have done that
78
115
                return CMD_FAILURE;
79
116
        }
80
117
 
81
 
        /* We have the correct # of arguments
82
 
     * TODO: handle tidle (~) expansion? */
 
118
        /* We have the correct # of arguments */
 
119
        // TODO: handle tidle (~) expansion? */
83
120
 
84
 
        rc = chdir(argv[1]);
 
121
        /* Handle 'cd -' first. */
 
122
        if (!str_cmp(target_directory, "-") && !hyphen_override) {
 
123
                if (!previous_directory_valid) {
 
124
                        cli_error(CL_EFAIL, "Cannot switch to previous directory");
 
125
                        return CMD_FAILURE;
 
126
                }
 
127
                if (!previous_directory_set) {
 
128
                        cli_error(CL_EFAIL, "No previous directory to switch to");
 
129
                        return CMD_FAILURE;
 
130
                }
 
131
                char *prev_dup = str_dup(previous_directory);
 
132
                if (prev_dup == NULL) {
 
133
                        cli_error(CL_ENOMEM, "Cannot switch to previous directory");
 
134
                        return CMD_FAILURE;
 
135
                }
 
136
                rc = chdir_and_remember(prev_dup);
 
137
                free(prev_dup);
 
138
        } else {
 
139
                rc = chdir_and_remember(target_directory);
 
140
        }
85
141
 
86
142
        if (rc == 0) {
87
143
                cli_set_prompt(usr);
92
148
                        cli_error(CL_EFAIL, "Destination path too long");
93
149
                        break;
94
150
                case ENOENT:
95
 
                        cli_error(CL_ENOENT, "Invalid directory `%s'", argv[1]);
 
151
                        cli_error(CL_ENOENT, "Invalid directory `%s'", target_directory);
96
152
                        break;
97
153
                default:
98
 
                        cli_error(CL_EFAIL, "Unable to change to `%s'", argv[1]);
 
154
                        cli_error(CL_EFAIL, "Unable to change to `%s'", target_directory);
99
155
                        break;
100
156
                }
101
157
        }