summaryrefslogtreecommitdiff
path: root/src/lib9
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib9')
-rw-r--r--src/lib9/goos.c6
-rw-r--r--src/lib9/run_plan9.c38
-rw-r--r--src/lib9/run_unix.c43
-rw-r--r--src/lib9/run_windows.c83
-rw-r--r--src/lib9/tempdir_plan9.c54
-rw-r--r--src/lib9/tempdir_unix.c52
-rw-r--r--src/lib9/tempdir_windows.c110
-rw-r--r--src/lib9/utf/utf.h2
-rw-r--r--src/lib9/win.h8
9 files changed, 394 insertions, 2 deletions
diff --git a/src/lib9/goos.c b/src/lib9/goos.c
index 3b0027111..2d4a800dd 100644
--- a/src/lib9/goos.c
+++ b/src/lib9/goos.c
@@ -51,3 +51,9 @@ getgo386(void)
{
return defgetenv("GO386", GO386);
}
+
+char *
+getgoextlinkenabled(void)
+{
+ return GO_EXTLINK_ENABLED;
+}
diff --git a/src/lib9/run_plan9.c b/src/lib9/run_plan9.c
new file mode 100644
index 000000000..cd85652f7
--- /dev/null
+++ b/src/lib9/run_plan9.c
@@ -0,0 +1,38 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <u.h>
+#include <libc.h>
+
+int
+runcmd(char **argv)
+{
+ int pid;
+ Waitmsg *w;
+
+ switch(pid = fork()) {
+ case -1:
+ return -1;
+ case 0:
+ exec(argv[0], argv);
+ fprint(2, "exec %s: %r\n", argv[0]);
+ exits("exec");
+ }
+
+ w = wait();
+ if(w == nil)
+ return -1;
+ if(w->pid != pid) {
+ werrstr("unexpected pid in wait");
+ free(w);
+ return -1;
+ }
+ if(w->msg[0]) {
+ werrstr("unsuccessful exit status: %s", w->msg);
+ free(w);
+ return -1;
+ }
+ free(w);
+ return 0;
+}
diff --git a/src/lib9/run_unix.c b/src/lib9/run_unix.c
new file mode 100644
index 000000000..c26cf0afb
--- /dev/null
+++ b/src/lib9/run_unix.c
@@ -0,0 +1,43 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin freebsd linux netbsd openbsd
+
+#include <u.h>
+#include <errno.h>
+#include <sys/wait.h>
+#define NOPLAN9DEFINES
+#include <libc.h>
+
+int
+runcmd(char **argv)
+{
+ int pid, pid1, status;
+
+ switch(pid = fork()) {
+ case -1:
+ return -1;
+ case 0:
+ execvp(argv[0], argv);
+ fprint(2, "exec %s: %r\n", argv[0]);
+ _exit(1);
+ }
+
+ while((pid1 = wait(&status)) < 0) {
+ if(errno != EINTR) {
+ werrstr("waitpid: %r");
+ return -1;
+ }
+ }
+ if(pid1 != pid) {
+ werrstr("unexpected pid in wait");
+ return -1;
+ }
+ if(!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ werrstr("unsuccessful exit status %#x", status);
+ return -1;
+ }
+ return 0;
+}
+
diff --git a/src/lib9/run_windows.c b/src/lib9/run_windows.c
new file mode 100644
index 000000000..87875b42d
--- /dev/null
+++ b/src/lib9/run_windows.c
@@ -0,0 +1,83 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <u.h>
+#include <windows.h>
+#define NOPLAN9DEFINES
+#include <libc.h>
+#include "win.h"
+
+int
+runcmd(char **argv)
+{
+ // Mostly copied from ../cmd/dist/windows.c.
+ // If there's a bug here, fix the logic there too.
+ int i, j, nslash;
+ Fmt fmt;
+ char *q;
+ WinRune *r;
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+ DWORD code;
+
+ fmtstrinit(&fmt);
+ for(i=0; argv[i]; i++) {
+ if(i > 0)
+ fmtprint(&fmt, " ");
+ q = argv[i];
+ if(strstr(q, " ") || strstr(q, "\t") || strstr(q, "\"") || strstr(q, "\\\\") || (strlen(q) > 0 && q[strlen(q)-1] == '\\')) {
+ fmtprint(&fmt, "\"");
+ nslash = 0;
+ for(; *q; q++) {
+ if(*q == '\\') {
+ nslash++;
+ continue;
+ }
+ if(*q == '"') {
+ for(j=0; j<2*nslash+1; j++)
+ fmtprint(&fmt, "\\");
+ nslash = 0;
+ }
+ for(j=0; j<nslash; j++)
+ fmtprint(&fmt, "\\");
+ nslash = 0;
+ fmtprint(&fmt, "\"");
+ }
+ for(j=0; j<2*nslash; j++)
+ fmtprint(&fmt, "\\");
+ fmtprint(&fmt, "\"");
+ } else {
+ fmtprint(&fmt, "%s", q);
+ }
+ }
+
+ q = fmtstrflush(&fmt);
+ r = torune(q);
+ free(q);
+
+ memset(&si, 0, sizeof si);
+ si.cb = sizeof si;
+ si.dwFlags = STARTF_USESTDHANDLES;
+ si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+
+ if(!CreateProcessW(nil, r, nil, nil, TRUE, 0, nil, nil, &si, &pi)) {
+ free(r);
+ return -1;
+ }
+
+ free(r);
+ if(WaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE) != 0)
+ return -1;
+ i = GetExitCodeProcess(pi.hProcess, &code);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ if(!i)
+ return -1;
+ if(code != 0) {
+ werrstr("unsuccessful exit status: %d", (int)code);
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/lib9/tempdir_plan9.c b/src/lib9/tempdir_plan9.c
new file mode 100644
index 000000000..092d00d16
--- /dev/null
+++ b/src/lib9/tempdir_plan9.c
@@ -0,0 +1,54 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <u.h>
+#include <libc.h>
+
+char*
+mktempdir(void)
+{
+ char *p;
+ int fd, i;
+
+ p = smprint("/tmp/go-link-XXXXXX");
+ for(i=0; i<1000; i++) {
+ sprint(p, "/tmp/go-link-%06x", nrand((1<<24)-1));
+ fd = create(p, OREAD|OEXCL, 0700|DMDIR);
+ if(fd >= 0) {
+ close(fd);
+ return p;
+ }
+ }
+ free(p);
+ return nil;
+}
+
+void
+removeall(char *p)
+{
+ int fd, n, i;
+ Dir *d;
+ char *q;
+
+ if(remove(p) >= 0)
+ return;
+ if((d = dirstat(p)) == nil)
+ return;
+ if(!(d->mode & DMDIR)) {
+ free(d);
+ return;
+ }
+ free(d);
+
+ if((fd = open(p, OREAD)) < 0)
+ return;
+ n = dirreadall(fd, &d);
+ close(fd);
+ for(i=0; i<n; i++) {
+ q = smprint("%s/%s", p, d[i].name);
+ removeall(q);
+ free(q);
+ }
+ free(d);
+}
diff --git a/src/lib9/tempdir_unix.c b/src/lib9/tempdir_unix.c
new file mode 100644
index 000000000..99a7092b6
--- /dev/null
+++ b/src/lib9/tempdir_unix.c
@@ -0,0 +1,52 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin freebsd linux netbsd openbsd
+
+#include <u.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#define NOPLAN9DEFINES
+#include <libc.h>
+
+char*
+mktempdir(void)
+{
+ char *tmp, *p;
+
+ tmp = getenv("TMPDIR");
+ if(tmp == nil || strlen(tmp) == 0)
+ tmp = "/var/tmp";
+ p = smprint("%s/go-link-XXXXXX", tmp);
+ if(mkdtemp(p) == nil)
+ return nil;
+ return p;
+}
+
+void
+removeall(char *p)
+{
+ DIR *d;
+ struct dirent *dp;
+ char *q;
+ struct stat st;
+
+ if(stat(p, &st) < 0)
+ return;
+ if(!S_ISDIR(st.st_mode)) {
+ unlink(p);
+ return;
+ }
+
+ d = opendir(p);
+ while((dp = readdir(d)) != nil) {
+ if(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
+ continue;
+ q = smprint("%s/%s", p, dp->d_name);
+ removeall(q);
+ free(q);
+ }
+ closedir(d);
+ rmdir(p);
+}
diff --git a/src/lib9/tempdir_windows.c b/src/lib9/tempdir_windows.c
new file mode 100644
index 000000000..1a530059a
--- /dev/null
+++ b/src/lib9/tempdir_windows.c
@@ -0,0 +1,110 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <u.h>
+#include <windows.h>
+#include <libc.h>
+#include "win.h"
+
+char*
+toutf(WinRune *r)
+{
+ Rune *r1;
+ int i, n;
+ char *p;
+
+ n = 0;
+ while(r[n] != '\0')
+ n++;
+ n++;
+ r1 = malloc(n*sizeof r1[0]);
+ for(i=0; i<n; i++)
+ r1[i] = r[i];
+ p = smprint("%S", r1);
+ free(r1);
+ return p;
+}
+
+WinRune*
+torune(char *p)
+{
+ int i, n;
+ Rune rr;
+ WinRune *r;
+
+ n = utflen(p);
+ r = malloc((n+1)*sizeof r[0]);
+ for(i=0; i<n; i++) {
+ p += chartorune(&rr, p);
+ r[i] = rr;
+ }
+ r[n] = '\0';
+ return r;
+}
+
+char*
+mktempdir(void)
+{
+ WinRune buf[1024];
+ WinRune tmp[MAX_PATH];
+ WinRune golink[] = {'g', 'o', 'l', 'i', 'n', 'k', '\0'};
+ int n;
+
+ n = GetTempPathW(nelem(buf), buf);
+ if(n <= 0)
+ return nil;
+ buf[n] = '\0';
+
+ if(GetTempFileNameW(buf, golink, 0, tmp) == 0)
+ return nil;
+ DeleteFileW(tmp);
+ if(!CreateDirectoryW(tmp, nil))
+ return nil;
+
+ return toutf(tmp);
+}
+
+void
+removeall(char *p)
+{
+ WinRune *r, *r1;
+ DWORD attr;
+ char *q, *elem;
+ HANDLE h;
+ WIN32_FIND_DATAW data;
+
+ r = torune(p);
+ attr = GetFileAttributesW(r);
+ if(attr == INVALID_FILE_ATTRIBUTES || !(attr & FILE_ATTRIBUTE_DIRECTORY)) {
+ DeleteFileW(r);
+ free(r);
+ return;
+ }
+
+ q = smprint("%s\\*", p);
+ r1 = torune(q);
+ free(q);
+ h = FindFirstFileW(r1, &data);
+ if(h == INVALID_HANDLE_VALUE)
+ goto done;
+ do{
+ q = toutf(data.cFileName);
+ elem = strrchr(q, '\\');
+ if(elem != nil) {
+ elem++;
+ if(strcmp(elem, ".") == 0 || strcmp(elem, "..") == 0) {
+ free(q);
+ continue;
+ }
+ }
+ removeall(q);
+ free(q);
+ }while(FindNextFileW(h, &data));
+ FindClose(h);
+
+done:
+ free(r1);
+ RemoveDirectoryW(r);
+ free(r);
+}
diff --git a/src/lib9/utf/utf.h b/src/lib9/utf/utf.h
index 8a79828bc..72d01ed63 100644
--- a/src/lib9/utf/utf.h
+++ b/src/lib9/utf/utf.h
@@ -16,8 +16,6 @@
#ifndef _UTFH_
#define _UTFH_ 1
-#include <stdint.h>
-
typedef unsigned int Rune; /* Code-point values in Unicode 4.0 are 21 bits wide.*/
enum
diff --git a/src/lib9/win.h b/src/lib9/win.h
new file mode 100644
index 000000000..d9df319af
--- /dev/null
+++ b/src/lib9/win.h
@@ -0,0 +1,8 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+typedef unsigned short WinRune;
+
+WinRune* torune(char*);
+char *toutf(WinRune*);