- Implemented execp*.
[planlOS.git] / programs / libc / unistd.c
blob978b7522c00a6dd83152a8e9f3aabea34f40c84a
1 /*
2 Copyright (C) 2008 Mathias Gottschlag
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in the
6 Software without restriction, including without limitation the rights to use,
7 copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8 Software, and to permit persons to whom the Software is furnished to do so,
9 subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <planlos/syscalls.h>
25 #include <string.h>
26 #include <stdlib.h>
28 char **environ = 0;
30 pid_t fork(void)
32 int status = -1;
33 asm volatile("int $0x80" : "=b"(status): "a"(SYS_FORK));
34 return status;
37 static char *exec_get_path(const char *file, const char *paths)
39 while (strlen(paths) > 0)
41 const char *nextpath = strchr(paths, ':');
42 if (!nextpath) nextpath = paths + strlen(paths);
43 if (nextpath && (nextpath != paths))
45 char *path = malloc(strlen(file) + 1 + ((uintptr_t)nextpath - (uintptr_t)paths));
46 memset(path, 0, strlen(file) + 1 + ((uintptr_t)nextpath - (uintptr_t)paths));
47 strncpy(path, paths, ((uintptr_t)nextpath - (uintptr_t)paths));
48 strcat(path, "/");
49 strcat(path, file);
50 // Test path
51 int fd = open(path, O_RDONLY);
52 if (fd != -1)
54 close(fd);
55 return path;
58 free(path);
60 if (strchr(paths, ':'))
61 paths = nextpath + 1;
62 else
63 break;
65 return 0;
68 int execl(const char *path, const char *arg0, ...)
70 char **args = (char**)&arg0;
71 return execv(path, args);
73 int execle(const char *path, const char *arg0, ...)
75 char **args = (char**)&arg0;
76 char **env = args;
77 while (*env) env++;
78 env++;
79 return execve(path, args, env);
81 int execlp(const char *file, const char *arg0, ...)
83 char **args = (char**)&arg0;
84 return execvp(file, args);
86 int execv(const char *path, char *const argv[])
88 int argcount;
89 for (argcount = 0; argv[argcount] != 0; argcount++);
90 char **env = environ;
91 int envcount = 0;
92 if (env)
93 while (*env) envcount++;
94 int status = -1;
95 asm volatile("int $0x80" : "=b"(status): "a"(SYS_EXEC), "b"(path),
96 "c"(argcount), "d"(argv), "S"(envcount), "D"(environ));
97 return status;
99 int execve(const char *path, char *const argv[], char *const env[])
101 int argcount = 0;
102 if (argv)
103 for (; argv[argcount] != 0; argcount++);
104 int envcount = 0;
105 if (env)
106 for (; env[envcount] != 0; envcount++);
107 int status = -1;
108 asm volatile("int $0x80" : "=b"(status): "a"(SYS_EXEC), "b"(path),
109 "c"(argcount), "d"(argv), "S"(envcount), "D"(env));
110 return status;
112 int execvp(const char *file, char *const argv[])
114 char *path = 0;
115 if (!strchr(file, '/'))
117 char *pathvar = getenv("PATH");
118 if (pathvar)
119 path = exec_get_path(file, pathvar);
120 if (!path)
121 path = exec_get_path(file, "/bin:/usr/bin");
122 if (!path) return -1;
124 if (!path)
125 return execve(file, argv, 0);
126 else
128 int result = execve(path, argv, 0);
129 free(path);
130 return result;
134 char *getcwd(char *buf, size_t size)
136 int status = -1;
137 asm volatile("int $0x80" : "=b"(status): "a"(SYS_GETWD), "b"(buf), "c"(size));
138 if (status == -1) return 0;
139 return buf;
141 int chdir(const char *path)
143 int status = -1;
144 asm volatile("int $0x80" : "=b"(status): "a"(SYS_CHDIR), "b"(path));
145 return status;
147 int dup(int fd)
149 return fcntl(fd, F_DUPFD, 0);
151 int dup2(int fd, int fd2)
153 return fcntl(fd, F_DUPFD, fd2);
156 pid_t getpid(void)
158 int pid;
159 asm volatile("int $0x80" : "=b"(pid): "a"(SYS_GETPID));
160 return pid;
164 int isatty(int fildes)
166 return 1;
169 int access(const char *path, int amode)
171 return R_OK;
174 char *setlocale(int category, const char *locale)
176 return 0;
179 pid_t tcgetpgrp(int fd)
181 return -1;
183 pid_t getpgrp(void)
185 return 0;
188 char *getenv(const char *name)
190 if (!environ) return 0;
191 char **env = environ;
192 while (*env)
194 if (!strncmp(name, *env, (uintptr_t)strchr(*env, '=') - (uintptr_t)*env))
196 return strchr(*env, '=') + 1;
199 return 0;
202 int putenv(char *string)
204 char *value = strchr(string, '=');
205 if (!value)
207 // Remove from environment
208 int found = -1;
209 int i = 0;
210 char **env = environ;
211 while (*env)
213 int namelength = (uintptr_t)strchr(*env, '=') - (uintptr_t)*env;
214 if (namelength < (int)strlen(string)) continue;
215 if (!strncmp(string, *env, (uintptr_t)strchr(*env, '=') - (uintptr_t)*env))
217 found = i;
219 i++;
222 if (found == -1) return -1;
224 char **newenv = malloc(sizeof(char*) * i);
225 memcpy(newenv, environ, found * sizeof(char*));
226 memcpy(newenv + found, environ + found + 1, (i + 1 - found) * sizeof(char*));
227 free(environ);
228 environ = newenv;
229 return 0;
231 // Set to new value
232 char *name = strdup(string);
233 *strchr(name, '=') = 0;
234 int found = -1;
235 int i = 0;
236 char **env = environ;
237 while (*env)
239 if (!strncmp(name, *env, (uintptr_t)strchr(*env, '=') - (uintptr_t)*env))
241 found = i;
243 i++;
245 int size = i;
246 if (found == -1)
248 char **newenv = malloc(sizeof(char*) * (size + 2));
249 memcpy(newenv, environ, sizeof(char*) * size);
250 newenv[size] = string;
251 newenv[size + 1] = 0;
252 free(environ);
253 environ = newenv;
255 else
257 environ[found] = string;
259 free(name);
260 return 0;
263 int setenv(const char *name, const char *value, int overwrite)
265 // Set to new value
266 int found = -1;
267 int i = 0;
268 char **env = environ;
269 while (*env)
271 if (!strncmp(name, *env, (uintptr_t)strchr(*env, '=') - (uintptr_t)*env))
273 found = i;
275 i++;
277 int size = i;
278 if (found == -1)
280 char **newenv = malloc(sizeof(char*) * (size + 2));
281 memcpy(newenv, environ, sizeof(char*) * size);
282 newenv[size] = malloc(strlen(name) + strlen(value) + 2);
283 strcpy(newenv[size], name);
284 strcat(newenv[size], "=");
285 strcat(newenv[size], value);
286 newenv[size + 1] = 0;
287 free(environ);
288 environ = newenv;
290 else
292 environ[found] = malloc(strlen(name) + strlen(value) + 2);
293 strcpy(environ[found], name);
294 strcat(environ[found], "=");
295 strcat(environ[found], value);
297 return 0;
300 int unsetenv(const char *name)
302 // Remove from environment
303 int found = -1;
304 int i = 0;
305 char **env = environ;
306 if (!environ) return 0;
307 while (*env)
309 if (!strncmp(name, *env, (uintptr_t)strchr(*env, '=') - (uintptr_t)*env))
311 found = i;
313 i++;
315 if (found == -1) return 0;
317 char **newenv = malloc(sizeof(char*) * i);
318 memcpy(newenv, environ, found * sizeof(char*));
319 memcpy(newenv + found, environ + found + 1, (i + 1 - found) * sizeof(char*));
320 free(environ);
321 environ = newenv;
322 return 0;
325 int clearenv(void)
327 // TODO
328 environ = NULL;
329 return 0;